Skip to content

docs(captions): add Arabic/RTL caption guidance - #1

Closed
AmroAlemam wants to merge 1246 commits into
mainfrom
docs/arabic-rtl-captions
Closed

AmroAlemam wants to merge 1246 commits into
mainfrom
docs/arabic-rtl-captions

Conversation

@AmroAlemam

Copy link
Copy Markdown
Owner

What

A short Arabic/RTL section in skills/hyperframes/references/captions.md, plus the regenerated hyperframes hash in skills-manifest.json.

Why

heygen-com#5887 had this guidance and was closed because the references restructure removed the files it edited. The same notes belong as one short section under skills/hyperframes/references/.

Related work

Replaces heygen-com#5887 (closed after the references restructure). Refs heygen-com#5885. The lint warnings proposed on that issue are not part of this change.

How

The section is "Arabic and right-to-left text", after "Fit and place" and before "Text behind the speaker".

It covers:

  • dir="rtl" and lang on the element that holds the word spans, never on <html>
  • picking direction by counting RTL words, so a Latin name at the start does not flip an Arabic line
  • animating Arabic by word; a per-character split shapes each letter alone
  • when letters must move, splitting into units the browser can still join (vowel marks, lam-alef, الله, a run of digits or Latin, ZWJ padding, spans built with textContent)
  • a split line coming out a few pixels wider than the unsplit text
  • no letter-spacing or text-transform on Arabic
  • embedding an Arabic face, since none of the bundled families covers Arabic script; Hebrew is covered by bundled Open Sans
  • Safari falling back inside a ZWJ-padded word when the font has no U+200D glyph; MP4 renders are fine

Test plan

  • oxfmt@0.41.0 --check on the changed files
  • scripts/lint-skills.ts (markdown cross-references)
  • gen-skills-manifest.ts --check after the hash refresh
  • Unit tests added/updated (docs only)
  • Manual testing performed
  • Documentation updated
  • Comments follow CONTRIBUTING.md "Comments" (no new code comments)
Open in Web Open in Cursor 

WaterrrForever and others added 30 commits November 3, 2026 11:07
* fix(cli,skills): say a step's credits are its total, and keep cost out of retries

An out-of-credits refusal named what the step needs, and an agent read
that as the shortfall. It now says the number is the step's total.

After its last try, an agent told the person what was spent and what
another try would cost. The HeyGen reference now says not to.

* fix(cli): plan avatar credits from the HyperFrames price rows

An avatar's credits came from its old API price, about five times what
the plan charges, so --max-credits refused calls that fit and a top-up
asked for too much. They now use the Avatar IV photo row plus the
general avatar video row, 950 credits a minute.

* fix(cli): pin the avatar price test and keep pricing under the comment share

* fix(cli): plan avatar seconds on the Avatar IV row alone

The general avatar row is only checked at admission and billed on
seconds left after Avatar IV, so adding it to every second made a 15 s
script plan at 238 instead of 200 and a 220 limit refuse a call that fits.

* feat(skills): creator templates on the HyperFrames plan

A Pro account asks for a video in a creator's format and the agent pulls that
template on demand. The packs sit in the private bucket behind the plan-gated
bundle route, so a Free account gets a 402 and the upgrade step. A pull costs
no credits; making the film spends them as Reverse does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): make creator-remix the one template skill

SKILL.md holds the catalog, the Pro openings, the pull and the credit
rules. references/remix.md is how to make the episode, from Desktop's
creator-remix with only what the app alone has swapped for the CLI.
The packs now hold only the template, so their hashes change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): the creator-remix skill and its packs

SKILL.md holds the catalog, the Pro openings, the pull and the credit
rules. references/remix.md is how to make the episode, from Desktop's
creator-remix with only what the app alone has swapped for the CLI.
The packs now hold only the template, so their hashes change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(skills): word creator-remix's sign-in steps the way media-use does

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): a creator-remix presenter runs on the plan by default

The person's own HeyGen avatar is recommended, not required: without
one, 小Lin's presenter is made with HeyGen Video 1 from their photo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(cli): pin template packs whose voice bills the plan first

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): offload media named inside template tags

References in a composition's <template> were never rewritten, because the DOM
query stops at the tag and template.content does not serialize, so the file stayed
in the zip. A stem matched as a plain word and a same-named file elsewhere counted
as a mention too. A 5-minute presented film went from 196 MB to 71 MB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(cli): lipsync, and avatars that speak a finished voice

Video 1 takes audio as a reference and re-paces it, so a shot's lips follow its
own track and drift up to a second from the voice. generate --type lipsync redoes
the mouth to the exact voice. generate --type avatar takes --audio, and --avatar
for the person's own look, so the lips land on the voice from one job.

Also moves the plan rows to the 2026-10-30 price book, estimates a voice's credits
so --max-credits can hold it, logs jobs from a folder with no project, and describes
the resolve flags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): presenters go avatar first, and a voice can be stock

The person's own avatar, then Avatar IV from their photo, then Video 1 with
lipsync. With no clone or recording, a stock voice named in the credits. Pins the
five rebuilt packs. The archive test keeps its ../ under GNU tar with -P.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cli): fix avatar price and sfx provider tests, trim comments

A wav gives the avatar price test an exact length on every platform. The
sfx tests now expect HeyGen first. Comment share is back under the base.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(core): read a font shorthand whose size nests parentheses

`font: calc(var(--size) * 1px)/1 "X"` cut at the first closing parenthesis, so a
bad family name failed the render.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): one ledger row per job, and search skips a template's own pictures

A job done at once logs one row, transcribe logs to the project, and resolve no
longer offers a component's file for a search. --reuse and --provider get help text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): pin the tested template packs, and a board needs no voice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cli): read the transcribe ledger row as JSON, for Windows paths

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): pin the Big Questions pack without the film length check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(skills): call them style templates, and the docs example pulls a real slug

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): pin the cleaned template packs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(skills): drop the stock-presenter ban and the no-spend-before-storyboard rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): pin the Paper Trail and Long Story Short packs without the stock-presenter ban

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): rename creator-remix to style-remix, and the five templates to names that say the look

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): style-remix lists the five templates when none is named

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): pin the Finance Explainer pack that varies its motion graphics

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(cli): media-use generate --type cutout takes a shot out of its background on the plan

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): pin the Finance Explainer pack without the provisional variety rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): pin the five style packs with variety rules measured on real films

Animated Science gets a worlds-and-boards budget, 3D True Crime a main board and a
brief corner note, 3D Brand caps by measured rate, Finance and Collage set pieces and
more than one look.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(skills): media-use names the on-plan cutout and lipsync commands, not the heygen CLI ones

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): cutout retries dedupe on request_id, uploads carry their real type; style-remix is public

The background-removal route dedupes on the body's request_id and ignores the Idempotency-Key
header, so a retry after a lost answer started a second job: runJob now also sends the key in the
body for such a route. Uploads typed every non-MP4 file as audio, so WebM and MOV inputs were
refused: they now take their type from the extension. Fails without the fix: the new cutout test
in generate.test.ts sees audio/mpeg for WebM and MOV.

style-remix drops metadata.internal and is listed with the other published skills.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(cli): keep the comment share of the touched files at main's

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: count style-remix in the README and CLAUDE.md skill lists

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(skills): rename style-remix to style-sampling

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ead at 0.5 s behind, not 1 s (heygen-com#7082)

* fix(core): Safari audio that sits frozen after its cut is pulled onto the playhead in 0.4 s, not 1 s

* fix(core): shorten the frozen-audio comment

* fix(core): leave a WebKit audio element that is still filling data out of the frozen rule
… has its id (heygen-com#7069)

* test(parsers): a stamped document needs no parse to keep its ids

* perf(parsers): ensureHfIds skips the parse when every element already has its id

* fix(parsers): a fragment checks every tag, a stray body tag included

* fix(parsers): keep the parse for a page not opening head then body

* refactor(parsers): split the head check out of the page shape check

* fix(parsers): find the head end tag without stripping comments
…'s release tag (heygen-com#7013)

* fix(cli): no auto-update across 0.x minors; install skills at the CLI's release tag

- autoUpdate: before 1.0 a minor bump counts as a major one, so 0.8.x -> 0.9.x
  is a notice, not a silent background install. From 1.0 on, the major alone.
- skills: `skills update` / bare `skills` / `init` install from
  heygen-com/hyperframes#v<VERSION>, and `skills check` plus the background
  freshness nudge read the manifest at the same tag. A build the repo has no
  tag for (dev build) falls back to main, as before.
- skills: run the upstream installer as `npx skills@1.7.4` instead of an
  unpinned `npx skills`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): keep the comment share of the touched files from rising

Comment ratchet: trim the comments added in the previous commit. No code change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): pass the CLI version into the skills check instead of importing it

scripts/clawhub-unlist-retired.mjs loads skillsManifest.ts from source under
plain node, which cannot resolve a relative `../version.js` import. Callers now
pass `cliVersion` (and skillsSourceRef takes it as an argument), so the module
keeps importing only node builtins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): read skills at the CLI's tag without a probe; pin skills@1.5.13

- A release build reads the manifest at its own tag directly (publish pushes
  the tag before npm publish). Only a 404 for that manifest falls back to main;
  a timeout, missing git or proxy error now surfaces instead of quietly
  comparing against main, so the background nudge can't cache a false
  "outdated" count.
- checkSkills returns the ref it read, and skills update installs from that
  same ref, so check and install can't disagree within one run.
- Pin skills@1.5.13 (it parses `#<ref>` too) so the pin matches the version
  agentDirs.generated.ts and the lock-path notes were checked against.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(cli): split the tag and main manifest fetches

Fallow flagged fetchRemoteManifest's CRAP score (31.6 > 30). The tag fetch
(404 is the only fallback to main) and the SHA-pinned main fetch are now their
own functions. No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): never auto-upgrade a Homebrew install

`brew upgrade hyperframes` installs whatever formula the tap holds, so a
background run scheduled for an allowed patch could still cross a 0.x minor.
Homebrew installs now only get the update notice naming `brew upgrade`.
A new test drives the scheduler through the real installer detection and
installer script: no spawn on Homebrew, a versioned npm install for a patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…and why it failed (heygen-com#7088)

* feat(engine): a script-load failure names where the script came from and why it failed

* fix(engine): keep the script-load cause helpers private and within the engine size budget
…n answers (heygen-com#7092)

* test(studio-server): a stamped preview build parses its page once

* perf(studio-server): preview steps skip the page parse when a tag scan answers
…d after it finishes (heygen-com#7087)

* fix(studio-server): a render that ran over 5 minutes can still be read after it finishes

* fix(studio-server): keep the finished-jobs helper's reasoning in its names
…eygen-com#7084)

The pack was written to a temporary file before tar read it. tar now
reads the checked bytes on stdin, so nothing downloaded is written to
disk before it is unpacked.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ade_url (heygen-com#7031)

reverse/start answers upgrade_url: null when no plan can be bought right
now. The CLI treated that like a missing field and built its own plans
link, so a Free account under gate "block" was sent to a page where it
can't buy. Now null means no link anywhere: the JSON prints
upgrade_url: null and subscribe_command: null (billing subscribe would
open that same plans page), the refusal says a plan can't be purchased
right now instead of naming the subscribe command, and the skill runs
nothing and passes on no link. Only an absent field (an older server)
falls back to the plans page; a string is used as is.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…file, not once per clip (heygen-com#6745)

* fix(studio): a film that cuts one file into many clips plays smoothly while their durations load

* test(studio): the metadata test counts one store write per file
…makes (heygen-com#6919)

* fix(check): the analysis restarts the idle window with every call it makes

* test(check): runAuditGrid's analysis must use the progress-reporting driver
…pens the result (heygen-com#7101)

* docs(skills): reverse-any-video runs sign-in and payment itself and opens the result

From Wenbo's end-to-end reverse test (F1, F2, F8, F9, F12, F13):
- the person types nothing: the agent runs auth login, billing subscribe and
  billing top-up itself and gives each page as a clickable link
- never sign in with an API key to get past Pro
- reverse start's plan is final; auth status is read only for a null plan,
  and its hyperframes field, never user.subscription
- an old CLI without reverse start: run this run as npx -y hyperframes@latest
- hand over: side by side from diff --sbs, Studio preview, Framey line
- animated shots: cut the guide inside a dissolve, retime each generated shot

* docs(skills): reverse sign-in names --device, reads auth status --json, trims dissolve frames

Rames's three wording notes on heygen-com#7101, and the old-CLI subscribe line now
applies only to a plugin's pinned CLI, beside main's null upgrade_url rule.

* docs(skills): a plugin whose CLI can't reverse stops before payment

Jerrai on heygen-com#7101: the plugin fallback sent the person to subscribe when the
pinned CLI has no reverse start, so the run could not go on after paying.
It now stops and says the plugin needs updating.
…, not frame 0 (heygen-com#7104)

* fix(producer): a stalled capture resumes at the first unwritten frame instead of frame 0

* fix(producer): a page that keeps stalling falls back after three resumes instead of resuming forever
…leep as a capture stall (heygen-com#7096)

* fix(producer): a laptop that sleeps mid-render no longer counts the sleep as a capture stall

* style(producer): format the stall watchdog timers
…th in the way (heygen-com#7116)

* fix(cli): templates pull reuses only a template it pulled, not any path in the way

* fix(cli): templates pull names an older pull, with the reasons in names, not comments
heygen-com#7068)

* feat(cli): billing top-up becomes add-credits, top-up stays as an alias

* fix(cli): keep the skills manifest and core-skills test in step with add-credits

* revert: leave the core-skills test to its own PR

* feat(cli): billing shows the price and pays from the terminal on Enter

* fix(cli): the top-up page opens at the credit packs

* test(cli): billing tests cover the checkout offer with no terminal

* fix(cli): the purchase wait runs while Press Enter is open
…gnal (heygen-com#7115)

* fix(cli): the FFmpeg cannot-start error names the OS error code or signal

* fix(cli): drop a comment the check counts

* test(cli): a timed-out FFmpeg reads as the timeout, not its kill signal
…en-com#7112)

* fix(cli): media-use sends a picture on a machine with no ffmpeg

* fix(cli): pictures fall back to ffmpeg when sharp cannot load

* fix(cli): drop two comments the names already carry
…der do (heygen-com#6947)

* test(cli): check waits as long as snapshot for the composition by default

* fix(cli): check waits for the composition as long as snapshot and render do

* docs(cli): check's --timeout default matches snapshot and render

* fix(cli): check's render-ready warning advises a --timeout above the new default

* fix(cli): drop the doc comment on the render-ready warning suffix

* style(cli): format checkBrowser.ts
…file, not a broken image (heygen-com#6928)

* fix(cli): check ignores the cancelled fetch of a proxy-swapped video in any container

* fix(cli): check ignores the cancelled fetch of a proxy-swapped media file, not a broken image
…m#7120)

* fix(cli): check skill freshness at the install destination

* fix(cli): report foreign skill requests while offline
…t, never the heygen sign-in (heygen-com#7144)

* fix(cli): the voice a film uses is listed from the HyperFrames account, never the heygen sign-in

* fix(cli): drop a comment line and an unenforced range from the voices command
… shares a composition id (heygen-com#7143)

* test(core): two hosts in a scene whose files share an id get their own timelines

* fix(core): a host inside a scene keeps its own timeline when its file shares a composition id

* fix(core): the nested-host fallback is told by its docstring alone

* fix(core): the identity map's docstring keeps its length
miguel-heygen and others added 29 commits November 7, 2026 22:54
…en-com#7378)

* fix(core): retain complete preview pictures during native seeks

* fix: settle failed seeks and preserve coherent progress
…eygen-com#7379)

* feat(studio): scrub full-quality video with decoded preview frames

* fix(studio): release scrub decoders before native playback

* fix(studio): bound paused fallback and tolerate decoder load failure

* fix(studio): recover stalled native preview handoffs

* fix(runtime): recognize cross-realm preview video elements

* fix(studio): bound Play handoffs and drain transparent preview samples

* fix(preview): recover retained video without chasing playback clock

* fix(studio): drain finite alpha queries before disposing readers
…com#7393)

* fix(studio): bound recovery and verify full-quality playback

* fix(studio): compare preview pixels with captured HTML clock
…s end (heygen-com#7397)

* fix(core): a set written before its tween no longer erases the tween's end

* fix(core): shorten two comment lines to the limit

* fix(core): the stamp takes any GSAP the runtime types, so the runtime typecheck passes
…eygen-com#7401)

* ci: install ffmpeg through the GitHub API asset route with a cache

* ci: the three jobs without a prepared ffmpeg stop downloading ffmpeg-static from releases

* ci: the ffmpeg install failure message counts its three downloads
* fix(core): capture pages load only the clips on screen

* fix(core): name the capture page media rule instead of commenting it
…-no-craft (heygen-com#7398)

* feat(cli): check returns an unchanged project's last pass in about a second

* fix(cli): the check cache hashes files without a stat race and its tests run before the signal test

* test(cli): the warm check test compares two real runs, not a run and its cached pass

* feat(cli): check --no-craft skips the craft pass for a render preflight

* fix(cli): the check cache keys on timeout, env and large files and never replays a moved tree

* style(cli): format the check cache

* fix(cli): the large-file cache test waits for the clock tick it depends on

* fix(cli): the check cache keys on the browser and on scripts under .hyperframes

* fix(cli): the check cache ignores the video copies the check itself touches
…the same film (heygen-com#7410)

* fix(producer): every render draws the same random values, at any worker count

* fix(producer): run the random-stagger fixture in CI and say what seeding covers
…rack at a cut (heygen-com#7412)

* fix(core): a muted video's picture no longer waits on its own audio track at a cut

A muted video takes its clock from its audio track in Safari; a late start of that track stalls the picture after the cut. The runtime now switches the track off.

* test(core): a video muted by script and unmuted later keeps its audio track

* fix(core): type the audio track loop so it passes the strict index check
…ygen-com#6150)

The declaration rule validates data-composition-variables on every
declaring element since 571c99c (heygen-com#4454), but the template-fragment
reproduction case from heygen-com#4383 had no regression coverage. Add it.

Refs heygen-com#4383

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…ction of the time (heygen-com#7415)

* perf(studio-server): a large project's first history copy takes a fraction of the time

* perf(studio-server): read a small file through one handle, with fewer comments

* fix(studio-server): small files keep their exact permissions in history under a strict umask
…er Unicode form than the page's (heygen-com#7419)

* fix(cli): cloud render finds media whose file name is stored in another Unicode form than the page's

* fix(cli): keep the archive-key change from raising publishProject's comment share

* fix(cli): a page that names a decomposed file as the disk lists it still matches its archive entry
)

* feat(cli): add 1440p resolution presets to --resolution

Adds landscape-1440p (2560x1440), portrait-1440p (1440x2560) and
square-1440p (1440x1440) next to the existing 4K, 720p and 480p tiers,
with the aliases 1440p, 2k and qhd plus 1440p-portrait and 1440p-square.
1440p joins the aspect-agnostic aliases, like 720p and 480p.

Every validator derives from CANVAS_DIMENSIONS, so no logic changes: a 4K
composition renders down to 1440p through the existing smaller-preset
path, and a 1280x720 composition supersamples to 1440p at an exact 2x.
A 1920x1080 composition is still refused by the non-integer-scale check
(4/3); fractional scale factors are not part of this change.

Refs heygen-com#6309

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(cli): clarify 1440p aliases and repair skill validation

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: James <james.russo@heygen.com>
* feat(cli): detect more agent runtimes in telemetry

Agent runtime rules:
- copilot_agent: key on COPILOT_AGENT=1 or AI_AGENT=github_copilot_*
  (VS Code agent terminals) instead of the unverified Actions markers.
- copilot_cli: COPILOT_CLI=1 or COPILOT_AGENT_SESSION_ID, ahead of
  copilot_agent.
- kilo (KILO=1, KILOCODE_VERSION), ahead of opencode.
- opencode (OPENCODE=1, OPENCODE_SESSION_ID).
- qwen_code (QWEN_CODE=1), junie (JUNIE_SHIM_PATH),
  antigravity (ANTIGRAVITY_AGENT), qoder (QODER_AGENT),
  kiro (AGENT_DISPLAY_OUT, AGENT_CONTEXT_OUT), openhands (AI_AGENT=openhands).
- AI_AGENT fallback after every vendor rule: known names map to their
  runtime, any other slug-safe name becomes other_ai_agent. Bare AGENT
  is not used.

Discovery hints: other_ai_agent keeps its hints, agent_hint prefers
AI_AGENT over AGENT, and AGENT_TOOLSDIRECTORY,
GSM_SKIP_SSH_AGENT_WORKAROUND and EDGE_METRICS_SESSION_ID are no
longer hint keys.

CI: name AWS CodeBuild (CODEBUILD_BUILD_ID) as codebuild.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* feat(cli): detect agents seen in discovery hints

Add rules for closed-source agents whose markers show up in the CLI's
own agent_env_hints on non-interactive runs: WorkBuddy, CodeBuddy, Trae,
Pippit, Doubao, Aily, Grok, Kimi, ZCode, SWE-agent and apps built on the
Claude Agent SDK. Qoder also matches its CLI and agent SDK keys.

The AI_AGENT name map now covers the names agents report (Devin, Amp,
v0, Rovo Dev, Base44, Trae, Antigravity, OpenHands, Copilot, and
hermes-agent), and a known name in the bare AGENT variable counts too.
Unknown AGENT values such as AGENT=1 still do not.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* feat(cli): detect the DeepSeek harness

Every dsh model shell call runs with DSH_SHELL=1 and the agent's
DSH_SESSION_ID. HyperFrames Desktop also runs dsh; its runs carry
HYPERFRAMES_CLIENT, so the client field separates the two.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(cli): cite the Agent SDK source for claude_agent_sdk

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(cli): let the closest agent win over inherited markers

Copilot's COPILOT_AGENT / AI_AGENT and COPILOT_CLI pass down to the
agents it starts, and TERM_PROGRAM / REPL_ID only say where a shell runs.
Those rules now come after every other agent rule, so opencode or Qwen
started by Copilot, or Kilo in a Cursor terminal, report as themselves.

dsh keys on DSH_SHELL=1 only: it sets DSH_SESSION_ID on the terminal a
person types into too. Qoder drops its app-wide SDK and setting keys,
CodeBuddy drops CODEBUDDY_AGENT_RUNTIME (a setting it reads), and Kiro's
markers must be non-empty.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n-com#7424)

TERM_PROGRAM=cursor|windsurf and Replit's REPL_ID only say where a shell
runs. They now sit in their own list, checked after the AI_AGENT / AGENT
name check, so Amp in a Cursor terminal or Devin in Replit report as
themselves, and an unknown AI_AGENT there keeps its discovery hints.
agentOnly had no users left, so it is gone.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…eygen-com#7425)

* feat(cli): add agent markers other detectors use, verified upstream

Compared std-env, @vercel/detect-agent, am-i-vibing and agent-cli-detector
against our rules and kept only markers the agent itself sets on the
shells it spawns: Auggie AUGMENT_AGENT, Amp AMP_CURRENT_THREAD_ID, Cursor
CURSOR_CONVERSATION_ID and CURSOR_SANDBOX, Cline CLI CLINE_WRAPPER_PATH,
Muse MUSE_RELEASE_INFO, and Warp Oz OZ_RUN_ID (after the harnesses it
wraps).

Claude Code now keys on CLAUDE_CODE_CHILD_SESSION or
CLAUDE_CODE_ENTRYPOINT. Its IDE extensions also set CLAUDECODE in the
integrated terminal a person types into, so CLAUDECODE alone counted that
person as an agent: no prompts, agent-mode login.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(cli): trim comments and fix citations the comment gates flag

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: raise the cli packed size budget to its measured size

main already sat at the edge of the 1% tolerance; the new agent rules
put the packed CLI 842 bytes past it (8062664 vs 7982002 + 1%).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ygen-com#7426)

CLAUDE_CODE_ENTRYPOINT is set by current Claude Code versions too, and it
is the only Claude marker MCP servers inherit, so it is not an
"older versions" fallback. The Agent SDK comment still said Claude Code's
shell tool sets CLAUDECODE; the rule keys on CLAUDE_CODE_CHILD_SESSION.

Follow-up to review nits on heygen-com#7425. Comments only.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The references restructure removed the files heygen-com#5887 edited. Put that
guidance back as one section in captions.md and refresh the
hyperframes skill hash.

Co-authored-by: AmroA <AmroAlemam@users.noreply.github.com>
@AmroAlemam AmroAlemam closed this Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.