Skip to content

feat(agents): identify Gram's Claude processes as the gram entrypoint - #91

Merged
ANT1OFF merged 1 commit into
mainfrom
feat/claude-entrypoint-gram
Nov 2, 2026
Merged

ANT1OFF merged 1 commit into
mainfrom
feat/claude-entrypoint-gram

Conversation

@ANT1OFF

@ANT1OFF ANT1OFF commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Claude processes that Gram starts now identify themselves as CLAUDE_CODE_ENTRYPOINT=gram. Before this change they fell back to the Agent SDK default, sdk-ts. This follows pingdotgg/t3code#28410, but the code is Gram's own.

Change

  • buildChildEnv (packages/agents/src/claude/env.ts) still strips an inherited CLAUDE_CODE_ENTRYPOINT in any spelling, so a parent's value such as claude-desktop can't leak into Gram's children. It then sets GRAM_ENTRYPOINT (gram). No auth stripping changed.
  • No override. Gram has no per-instance or per-profile env setting: gateway profiles hold only a URL, a key and models. So, unlike T3 Code, nothing overrides gram, and I didn't add a settings surface for it. Claude Code 2.1.316 also ignores the entrypoint in settings.json env (see below), so I added no settings reader.
  • Terminals don't change. terminalEnv builds the terminal's env from process.env and never calls buildChildEnv, so a claude the user runs in Gram's terminal keeps its own entrypoint.

Spawn paths

These Claude spawn paths go through buildChildEnv (via ClaudeEnvironment.prepare) and now send gram:

  • thread and worker turns, including gateway-profile threads (gatewayChildEnv builds on prepared.env)
  • helpers (thread naming, Dreams and other helper jobs via helperClaudeOptions)
  • the model listing
  • the subscription-limits read
  • the claude --version probe and claude auth status in prepare and checkAuth

One path doesn't use the builder: launch checks (packages/server/src/launch-checks/handler.ts). They run claude --version and claude auth status --json with Gram's own process env through Proc. They make no model requests, and I left them unchanged.

Verification

  • vitest run packages/agents: 860 passed, 21 skipped.
  • vitest run packages/server/src/terminal/pure.test.ts: 13 passed.
  • bun run typecheck, bun run check:scaffold and bun run fmt:check pass.
  • New tests check that an inherited value (claude-desktop, or Claude_Code_Entrypoint on Windows) becomes gram, that gateway threads keep gram, and that terminalEnv passes the entrypoint through untouched.
  • Live header capture with claude --version → 2.1.316 (Claude Code). The child env came from buildChildEnv with a synthetic parent env (PATH, a temporary HOME and CLAUDE_CODE_ENTRYPOINT=claude-desktop). I added a temporary CLAUDE_CONFIG_DIR, a fake API key and a loopback ANTHROPIC_BASE_URL pointing at a local fake API. No real login was used: every request carried the fake key and no Authorization header.
    • /v1/messages got User-Agent: claude-cli/2.1.316 (external, gram), and the body carried cc_entrypoint=gram.
    • With {"env":{"CLAUDE_CODE_ENTRYPOINT":"custom"}} in that config dir's settings.json, the request still carried gram. Claude Code reads the entrypoint only from the process env.

Known limits

  • Launch checks don't send gram (see above).
  • I tested the header with an API key against the fake API, not with a subscription login against Anthropic.

@ANT1OFF

ANT1OFF commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

Merging with e2e 8/8 red. The one failure is unrelated to this diff: apps/web/e2e/dictation.spec.ts:219 ("a tap of Right ⌥, or ⌥ with another key, throws dictation away without a sound"). At line 237 it expected the composer to read Draft and got Draft Refactor the model store so it: the mock dictation text landed before the tap discarded it. The other 83 tests in that shard passed. This PR changes only the Claude child env builder in packages/agents, and the web e2e suite runs against the browser mock, so it never reaches that code. The same test passed on main at the base commit (8bdce01), and Gram's local check passed on this head. The job couldn't be re-run while the run was still in progress.

@ANT1OFF
ANT1OFF merged commit f7dd703 into main Nov 2, 2026
18 of 22 checks passed
@ANT1OFF
ANT1OFF deleted the feat/claude-entrypoint-gram branch November 2, 2026 14:32
ANT1OFF added a commit that referenced this pull request Nov 2, 2026
Desktop release metadata proposal only. Merging this PR does not publish
or tag Gram; follow docs/RELEASING.md to release.
---


## [1.4.0](v1.3.1...v1.4.0)
(2026-11-02)


### Features

* **agents:** identify Gram's Claude processes as the gram entrypoint
([#91](#91))
([f7dd703](f7dd703))
* **desktop:** run on Linux
([#82](#82))
([1d37deb](1d37deb))
* **desktop:** turn voice input off on Linux with one check
([#79](#79))
([470ff8b](470ff8b))
* **orchestration:** a person's PR comment wakes the worker that owns it
([#86](#86))
([19bdc1c](19bdc1c))
* **orchestration:** a wrap-up turn when a worker stops without
reporting ([#88](#88))
([36a07fb](36a07fb))
* **orchestration:** workers say what they ruled out and check before
repeating ([#90](#90))
([8bdce01](8bdce01))
* **release:** publish and update Linux AppImage and .deb
([#95](#95))
([c33c464](c33c464))
* **voice:** an accurate mode with a Parakeet pass on each pause
([#83](#83))
([2b04a52](2b04a52))
* **voice:** hold one key to talk, with a tone at each end
([#87](#87))
([1a9b3ef](1a9b3ef))
* **voice:** start capture at the press, and an opt-in ready microphone
([#81](#81))
([505d240](505d240))
* **web:** a Done section that keeps the last 7 days
([#65](#65))
([8c7bd49](8c7bd49))
* **web:** Done lists every finished chat
([#67](#67))
([c91d9ac](c91d9ac))
* **web:** one attention count, quieter rows, a sidebar and board that
agree ([#92](#92))
([f193da4](f193da4))
* **web:** orchestrator → workers in the sidebar, a board that matches
([#80](#80))
([686e737](686e737))


### Bug Fixes

* **desktop:** harden the Linux key vault and autostart entry
([#85](#85))
([4b35eac](4b35eac))
* **e2e:** hold the t-flaky turn while the smoke test reads its opening
line ([#93](#93))
([2edc4ac](2edc4ac))
* **e2e:** release the dictation tap as soon as a word is heard
([#94](#94))
([7781194](7781194))
* prepare only approved local-check sources
([#32](#32))
([af3fab7](af3fab7))
* repair main after [#32](#32)
([#68](#68))
([ce352e6](ce352e6))
* **voice:** keep the last word after release
([#78](#78))
([cc40a47](cc40a47))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: gram-release-please[bot] <351321620+gram-release-please[bot]@users.noreply.github.com>
Co-authored-by: Johan <32440065+ANT1OFF@users.noreply.github.com>
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.

1 participant