Skip to content

feat: add source field to session_start telemetry#968

Merged
anandgupta42 merged 6 commits into
mainfrom
feat/telemetry-source-field
Jul 7, 2026
Merged

feat: add source field to session_start telemetry#968
anandgupta42 merged 6 commits into
mainfrom
feat/telemetry-source-field

Conversation

@altimate-harness-bot

@altimate-harness-bot altimate-harness-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds source to every telemetry event by injecting it globally in toAppInsightsEnvelopes(), matching the existing cli_version injection pattern
  • Stores source as a module-level variable (clientSource); callers set it once at startup via Telemetry.setSource()
  • In session/prompt.ts, calls Telemetry.setSource(Flag.ALTIMATE_CLI_CLIENT) at init — defaults to "cli" for terminal invocations

Source values

Value When
"cli" Default — user runs altimate in terminal
"vscode" VS Code extension spawns the server (set via ALTIMATE_CLI_CLIENT=vscode env var, injected in companion PR AltimateAI/vscode-altimate-mcp-server#386)

Why global injection (not per-event type)

cli_version is already injected globally into every App Insights event envelope. source follows the same pattern — zero per-event-type changes needed, and all 30+ event types get the field automatically.

Requested by @saravmajestic via harness

@github-actions

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@saravmajestic saravmajestic marked this pull request as ready for review June 26, 2026 03:14

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@dev-punia-altimate dev-punia-altimate left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Code Review — OpenCodeReview (Gemini) — 1 finding(s)

  • 1 anchored to a line (posted inline when the comment stream is on)
  • 0 without a line anchor
All findings (full text)

1. packages/opencode/src/session/index.ts (L227-L229)

[🔵 LOW] Here you can use Info.shape.metadata to reuse the type definition and maintain consistency with how permission is defined, avoiding duplicate Zod schema declarations.

Suggested change:

        permission: Info.shape.permission,
        workspaceID: WorkspaceID.zod.optional(),
        metadata: Info.shape.metadata,

Comment thread packages/opencode/src/session/index.ts Outdated
Comment on lines +227 to +229
permission: Info.shape.permission,
workspaceID: WorkspaceID.zod.optional(),
metadata: z.record(z.string(), z.unknown()).optional(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] Here you can use Info.shape.metadata to reuse the type definition and maintain consistency with how permission is defined, avoiding duplicate Zod schema declarations.

Suggested change:

Suggested change
permission: Info.shape.permission,
workspaceID: WorkspaceID.zod.optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
permission: Info.shape.permission,
workspaceID: WorkspaceID.zod.optional(),
metadata: Info.shape.metadata,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 6c60c31 — the create schema now uses Info.shape.metadata, matching the permission: Info.shape.permission pattern.

@dev-punia-altimate

Copy link
Copy Markdown
Contributor

🤖 Code Review — OpenCodeReview (Gemini) — No Issues Found

No supported files changed.

@ralphstodomingo

Copy link
Copy Markdown
Contributor

Aligning the platform-team telemetry work on this source field — it's the same mechanism as our parallel launch_surface PRs (env var in _spawnServer → global stamp in toAppInsightsEnvelopes) but finer-grained (cli / datamates / poweruser), so source supersedes launch_surface. Closing our #970 in favor of this.

One thing our #970 added after AI review that's worth carrying over — normalize + allowlist the value so a stray env/flag can't inflate the dimension's cardinality:

const KNOWN_SOURCES = new Set(["cli", "datamates", "poweruser", "vscode"])
export function setSource(s: string): void {
  const normalized = (s ?? "").trim().toLowerCase()
  clientSource = KNOWN_SOURCES.has(normalized) ? normalized : "cli"
}

(The per-session read at source: session.metadata?.source ?? Flag.ALTIMATE_CLI_CLIENT could apply the same normalization.)

@anandgupta42

Copy link
Copy Markdown
Contributor

Deep review — telemetry source field

Traced the full path end-to-end (POST /sessionSession.create/createNexttoRow/fromRowsession_start emit → toAppInsightsEnvelopes) plus the migration wiring. The approach is sound and the migration is correct. A few things worth addressing before merge.

What's solid

  • Global injection mirrors cli_version — minimal, and all 30+ event types get source for free. Good call over per-event-type edits.
  • Migration is correct & backward-compatible: nullable text column, snapshot chain intact (prevIds = prior snapshot id f13dfa58…), auto-discovered by both the dev folder-reader (storage/db.ts::migrations()) and the build-time bundler (script/build.ts globs the folder), so it ships in the compiled binary; drizzle-kit check will pass since schema + snapshot are in sync.
  • Round-trip verified: metadata is plumbed through create schema, createNext, toRow, fromRow, and read back at the session_start emit. Session.create.schema.optional() on the route accepts it.
  • Marker Guard passes (only prompt.ts is in the upstream-shared set and it's properly marked).

Should address

1. Default source is "cli" and is only ever set inside the prompt flow. clientSource starts as "cli" and is overridden only by setSource(Flag.ALTIMATE_CLI_CLIENT) in session/prompt.ts. Any event emitted by a code path that doesn't run SessionPrompt.chat() — standalone CLI subcommands (cli/cmd/skill.ts, cli/cmd/debug/snapshot.ts both Telemetry.track directly), and anything emitted in a serve process before the first prompt (connection registration, project-scan, warehouse-add during the extension's setup UI) — reports source:"cli" even when the process was launched with ALTIMATE_CLI_CLIENT=vscode. That defeats the stated goal for a meaningful class of events.

Fix is trivial and strictly more correct: seed the default from the flag instead of a literal —

let clientSource = Flag.ALTIMATE_CLI_CLIENT   // instead of "cli"

(or set it once in doInit()). setSource() then becomes an optional dynamic override, and the explicit setSource(Flag.ALTIMATE_CLI_CLIENT) call in prompt.ts becomes redundant.

2. Only session_start carries the per-session (metadata) source; every other event uses the process-global. This is by design, but it means in the shared-serve-process model (datamates + poweruser on one altimate serve) all non-session_start events collapse to the single process-level ALTIMATE_CLI_CLIENT. Attributing any other event type to a specific extension requires joining session_id back to that session's session_start.source. That's a real, non-obvious constraint for whoever builds the dashboards — worth confirming it's acceptable and documenting it. If per-event attribution is ever needed, source has to be threaded per-event (like session_id is in fields), not via the global.

3. No tests. For a new persisted column + migration + telemetry field, add: (a) round-trip — Session.create({ metadata: { source: "datamates" } })Session.get → assert metadata persisted; (b) envelope — source present on a generic event (= clientSource) and overridden to the metadata value on session_start. (b) also locks in the merge-order behavior that finding #4 depends on.

Minor / nits

4. session.metadata?.source as string is an unchecked cast. metadata is Record<string, unknown> accepted verbatim from the API. If a client sends metadata:{ source: 42 }, the value is a number — in toAppInsightsEnvelopes the field-loop routes numbers to measurements, so source silently drops out of properties (stays at the global) and a bogus source measurement appears; an object gets JSON.stringify'd. A typeof … === "string" guard makes malformed input fall back cleanly to the flag.

5. metadata is an unbounded z.record(z.string(), z.unknown()) persisted wholesale, but only source is consumed. Consider narrowing to z.object({ source: z.string().optional() }).passthrough() to document intent and bound what gets stored, or note explicitly that it's an intentional open extension point.

6. The session_start override is correct-by-coincidence. It works because the field-loop overwrites properties.source after the global injection and source isn't in the loop's skip-list. A one-line comment at the injection site ("per-event source, e.g. session_start, intentionally overrides this") would keep a future refactor from silently breaking it.

7. Consistency (optional): the metadata additions in session/index.ts and session.sql.ts are unmarked while other changes in session/index.ts use altimate_change markers. Guard passes (these aren't in the upstream-shared set), so not a blocker — but wrapping them would match the file's own convention.

Net: #1 (seed default from flag) and #3 (tests) are the two I'd want before merge; #2 is a "confirm the analytics model is understood" rather than a code change.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@anandgupta42

Copy link
Copy Markdown
Contributor

Pushed fixes for the review findings (531d617)

Addressed the items from the review above:

One design consideration for you (surfaced by a second-pass review)

The globally-injected source collides with pre-existing per-event source fields that mean something unrelated: skill_created / skill_installed / skill_removed carry source: "cli" | "tui" (command surface), and the connection events carry a connection-origin source. For those event types the field-loop overwrites the injected client value, so their source will not be the client identifier — a query on source across event types returns the client for most events but cli/tui or connection-origin for those.

Not something I changed (it's your schema call and touches the companion extension's expectations), but worth deciding: renaming the injected dimension to client / client_source would give a clean client axis across all events without colliding. Flagging so it's a conscious choice rather than a silent overlap.

@kilo-code-bot

kilo-code-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (10 files)
  • packages/opencode/migration/20260626041744_elite_malcolm_colcord/migration.sql
  • packages/opencode/migration/20260626041744_elite_malcolm_colcord/snapshot.json
  • packages/opencode/src/altimate/telemetry/index.ts
  • packages/opencode/src/session/index.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/session/session.sql.ts
  • packages/opencode/test/session/session.test.ts
  • packages/opencode/test/telemetry/telemetry.test.ts
  • packages/sdk/js/src/v2/gen/types.gen.ts
  • packages/sdk/openapi.json

Notes:

  • Incremental re-review at 6c60c31 (prev: 1c1c1007). The incremental diff touches 4 files: session/index.ts (reuse Info.shape.metadata + fork inherits metadata), session.test.ts (fork-inherits-metadata test), and the auto-generated types.gen.ts / openapi.json.
  • Resolved: the prior LOW finding on session/index.ts (duplicate z.record(...) schema) is now fixed — the create route schema reuses Info.shape.metadata, matching the Info.shape.permission pattern.
  • fork now passes metadata: original.metadata to createNext. original comes from fromRow (DB-deserialized), and each session is serialized to its own DB row, so the shared in-memory reference cannot cause cross-session mutation; metadata is treated as write-once per-session config. Behavior is covered by the new fork inherits metadata (source) test.
  • The generated types.gen.ts/openapi.json add metadata consistently to Session, GlobalSession, and SessionCreateData — matches the Record<string, unknown> shape.
  • No new inline comments; no findings to address.
Previous Review Summaries (2 snapshots, latest commit 1c1c100)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 1c1c100)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (8 files)
  • packages/opencode/migration/20260626041744_elite_malcolm_colcord/migration.sql
  • packages/opencode/migration/20260626041744_elite_malcolm_colcord/snapshot.json
  • packages/opencode/src/altimate/telemetry/index.ts
  • packages/opencode/src/session/index.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/session/session.sql.ts
  • packages/opencode/test/session/session.test.ts
  • packages/opencode/test/telemetry/telemetry.test.ts

Notes:

  • Incremental re-review (previous review SHA unreachable, fell back to full diff verification at 1c1c1007). HEAD unchanged since last review; re-verified all changed code, no new findings.
  • clientSource is read live from Flag.ALTIMATE_CLI_CLIENT (a dynamic env getter with OPENCODE_CLIENT/"cli" fallback) inside toAppInsightsEnvelopes(), correctly labelling pre-prompt/startup events. setSource()/clientSource module var are fully removed (no dangling references — confirmed via grep).
  • session.metadata round-trips cleanly: Info schema (line 157) → create route schema → createNexttoRow → DB → fromRowget. Existing partial .update() calls don't clobber it.
  • The session_start per-session source is type-guarded (typeof ... === "string") against non-string metadata.source, falling back to the flag — verified by a dedicated telemetry test.
  • The global source dimension overlaps pre-existing skill_*/connections per-event source fields (cli/tui, connection origin); documented in-code and acknowledged on the PR, so not flagged here.
  • The duplicate z.record(z.string(), z.unknown()).optional() schema at session/index.ts:232 is already covered by an existing inline comment (suggesting reuse of Info.shape.metadata), so no duplicate is posted.

Migration is backward-compatible (nullable text, snapshot prevIds chain intact) and tests cover env-flag default, "cli" fallback, per-event override, non-string routing, and metadata round-trip (present + undefined).

Previous review (commit 531d617)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (8 files)
  • packages/opencode/migration/20260626041744_elite_malcolm_colcord/migration.sql
  • packages/opencode/migration/20260626041744_elite_malcolm_colcord/snapshot.json
  • packages/opencode/src/altimate/telemetry/index.ts
  • packages/opencode/src/session/index.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/session/session.sql.ts
  • packages/opencode/test/session/session.test.ts
  • packages/opencode/test/telemetry/telemetry.test.ts

Notes:

  • clientSource is now read live from Flag.ALTIMATE_CLI_CLIENT (a dynamic env getter), correctly labelling pre-prompt/startup events. setSource() is fully removed (no dangling references).
  • session.metadata round-trips cleanly through createtoRow → DB → fromRowget; existing partial .update() calls don't clobber it.
  • The session_start per-session source is type-guarded against non-string metadata.source.
  • The global source dimension overlaps pre-existing skill_*/connections per-event source fields (cli/tui, connection origin), but this is documented in-code and already discussed/acknowledged on the PR — not flagged here.
  • The duplicate z.record(z.string(), z.unknown()).optional() schema at session/index.ts:232 is already covered by an existing inline comment, so no duplicate is posted.

Migration is backward-compatible (nullable text, snapshot chain intact) and tests cover env-flag default, "cli" fallback, per-event override, non-string routing, and metadata round-trip.


Reviewed by glm-5.2 · Input: 31K · Output: 4.6K · Cached: 251.7K

Review guidance: REVIEW.md from base branch main

saravmajestic and others added 5 commits July 6, 2026 21:59
Adds source: string to the session_start event type definition and
populates it with Flag.ALTIMATE_CLI_CLIENT at the call site. Defaults
to "cli" for terminal invocations; overridden to "vscode" when the
VS Code extension spawns the server via ALTIMATE_CLI_CLIENT env var.
…sion metadata)

- Add optional metadata column to SessionTable (JSON blob, backward-compatible)
- Add metadata field to Session.Info schema, fromRow, toRow, create, and createNext
- Add source?: string to session_start event type in telemetry/index.ts
- In prompt.ts session_start emit, override source with session.metadata?.source
  when present, falling back to Flag.ALTIMATE_CLI_CLIENT for sessions without it

VS Code extensions (datamates, poweruser) can now pass { metadata: { source: "datamates" } }
in POST /session to produce distinguishable session_start telemetry even though both
extensions share the same altimate serve process. The global source injection in
toAppInsightsEnvelopes() (clientSource) is unchanged and still covers all other events.
Resolves review findings on the telemetry `source` field:

- Read `Flag.ALTIMATE_CLI_CLIENT` live at envelope-build time instead of a
  hardcoded `clientSource = "cli"` set only inside the prompt flow. Events
  emitted before the first prompt (startup, connection setup, standalone CLI
  subcommands) are now labelled with the real client instead of defaulting to
  `"cli"`. Removes the now-redundant `clientSource` variable, `setSource()`,
  and its call in `session/prompt.ts`.
- Type-guard `session.metadata?.source` in the `session_start` emit (was an
  unchecked `as string`) so malformed client JSON falls back to the flag
  instead of being routed to `measurements` downstream.
- Document `Session.Info.metadata` as an intentional open extension point.
- Add tests: telemetry envelope `source` behaviour (env-flag default, `"cli"`
  fallback, per-event override, non-string routing contract) and session
  `metadata` round-trip through `create` -> `get`.

Comments clarified per Codex review: events that carry their own `source`
field (session_start, and pre-existing `skill_*`/connections events) override
the injected process-level value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@anandgupta42 anandgupta42 force-pushed the feat/telemetry-source-field branch from 531d617 to 1c1c100 Compare July 7, 2026 04:59
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@sahrizvi sahrizvi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1. Session.fork doesn't carry the new source label.
This PR threads metadata through Session.createcreateNext, but Session.fork (packages/opencode/src/session/index.ts, ~L256) still calls createNext({ directory, workspaceID, title }) without it. Normal sessions now carry their source (datamates / poweruser), but forked sessions get metadata: undefined and their session_start falls back to the process-level Flag.ALTIMATE_CLI_CLIENT ("cli"). createNext already accepts metadata, so the fix is a one-line pass-through — either inherit original.metadata or accept an optional metadata on the fork request. Worth a test pinning whichever behavior is intended.

2. The generated SDK / OpenAPI artifacts weren't regenerated.
The PR adds metadata to the Session.create request schema (which POST /session validates against), but the committed client is now out of sync:

  • packages/sdk/js/src/v2/gen/types.gen.tsSession has no metadata, and SessionCreateData.body still allows only parentID / title / permission / workspaceID.
  • packages/sdk/openapi.json — the /session POST body wasn't updated.

This self-corrects on the next SDK rebuild (packages/sdk/js/script/build.ts runs bun dev generate), but as committed, consumers of the generated types can't send metadata. Regenerate + commit the artifacts; optionally add a CI check that fails on schema/client drift.

…ema reuse

- `Session.fork` now inherits `original.metadata`, so forked sessions keep
  the origin (`source`) of the session they were forked from instead of
  falling back to the process-level `Flag.ALTIMATE_CLI_CLIENT` in their
  `session_start` telemetry. Adds a fork-inherits-metadata test.
- Regenerate the committed SDK/OpenAPI artifacts for the new `metadata` field:
  `packages/sdk/openapi.json` (`Session`, `GlobalSession`, and the `/session`
  POST body) and `packages/sdk/js/src/v2/gen/types.gen.ts` (`Session`,
  `GlobalSession`, `SessionCreateData.body`). Applied only the `metadata`
  delta — verified byte-for-byte against the real `@hey-api/openapi-ts`
  output — to avoid importing unrelated pre-existing spec drift.
- Reuse `Info.shape.metadata` in the `Session.create` request schema instead
  of re-declaring the Zod record, matching the `permission` pattern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@anandgupta42

Copy link
Copy Markdown
Contributor

Addressed all review comments (6c60c31)

@sahrizvi #1Session.fork didn't carry the source label. Fixed. fork now inherits original.metadata in its createNext call, so a forked session keeps the origin of the session it was forked from instead of falling back to the process-level flag. Chose inherit (over accepting a new metadata on the fork request) since a fork is a continuation of an existing session — same rationale as it already copying title/workspaceID. Added a test pinning it: fork inherits metadata (source) from the original session.

@sahrizvi #2 — generated SDK/OpenAPI artifacts out of sync. Updated both:

  • packages/sdk/openapi.jsonmetadata added to the /session POST body, plus the Session and GlobalSession component schemas.
  • packages/sdk/js/src/v2/gen/types.gen.tsmetadata?: { [key: string]: unknown } on Session, GlobalSession, and SessionCreateData.body.

One deliberate call: I applied only the metadata delta rather than a full regen. The committed spec is already stale on main for unrelated reasons (it's missing the /session/{sessionID}/transcript endpoint that exists in code, and the opencodeAltimate Code branding), so a blind bun dev generate here would import ~560 lines of drift that isn't this PR's. I verified the surgical additions byte-for-byte against the real @hey-api/openapi-ts output for these three types, so they match exactly what a regen would emit — just scoped. (That pre-existing spec drift is worth a separate cleanup PR.)

@dev-punia-altimate (Gemini, LOW) — reuse Info.shape.metadata. Done — the Session.create request schema now uses Info.shape.metadata instead of re-declaring the Zod record, matching how permission is defined.

Validation: opencode + sdk/js typecheck clean (the hand-edited types.gen.ts compiles), session tests 6/6 (incl. the new fork test), telemetry tests 135/135, Marker Guard green.

@anandgupta42 anandgupta42 merged commit f376fef into main Jul 7, 2026
14 checks passed
anandgupta42 added a commit that referenced this pull request Jul 8, 2026
Merge the 5 commits on `main` since this branch was cut (bearer-auth remote
MCP #793, session_start `source` telemetry #968, aireceipts CI #992, REVIEW.md
docs #983/#984) into the upstream OpenCode v1.17.9 bridge branch.

9 conflicts resolved:

- `altimate/telemetry/index.ts` — keep upstream `InstallationVersion`; re-add
  #968's `Flag`/`source` (per-session client label).
- `session/index.ts` — keep upstream `permission` readonly cast AND #968's
  `metadata: row.metadata`. Session `metadata` already exists upstream (core
  `SessionTable`, upstream PR #23068), so #968's persistence layer is redundant.
- `session/session.sql.ts` — accept upstream deletion (persistence moved to
  `@opencode-ai/core`); dropped #968's duplicate migration
  `20260626041744_elite_malcolm_colcord` (would crash "duplicate column: metadata"
  against upstream's `20260511173437_session-metadata`).
- `test/session/session.test.ts` — keep upstream Effect harness (main's metadata
  cases were the redundant old-harness variant).
- `config/config.ts` — take upstream (schema relocated to core Effect Schema);
  re-apply #793's `headersCommand`/`oauth` normalize passthrough.
- `mcp/index.ts` — re-port #793 (bearer-auth) onto upstream's Effect-based MCP
  rewrite: `resolveHeadersCommand` (execFile, no shell), case-insensitive
  `mergeHeaders`, lenient `listTools` retry, OAuth auto-disable folded into
  upstream's `supportsOAuth`, `maskString` on failures. Adapted `Either`→`Result`
  (effect 4.0.0-beta.74).
- `core/v1/config/mcp.ts` — add `headersCommand` to the Effect Schema `Remote`
  struct as a mutable non-empty string-array record (`Schema.mutable(...).check
  (Schema.isNonEmpty())`), so `DeepMutable`-wrapped consumers type-check.
- `test/mcp/headers.test.ts`, `test/mcp/mcp-bearer-auth.test.ts` — re-expressed
  #793's schema/integration tests against the Effect Schema and `it.instance`
  harness (Zod `safeParse` → `Schema.decodeUnknownSync`).
- SDK artifacts kept at the upstream-HEAD baseline (regenerated by CI/release).

Verification: all 13 packages typecheck clean (`bun turbo typecheck`); MCP +
session + telemetry suites 194/194; bearer-auth + headers 32/32. Zero conflict
markers. Marker guard non-strict pass (CI mode for upstream-merge PRs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
anandgupta42 added a commit that referenced this pull request Jul 9, 2026
First stable 0.9.x on npm `latest` — brings the upstream OpenCode v1.4.0→v1.17.9
bridge merge, bearer-auth remote MCP (#793), session_start `source` telemetry
(#968), and the MCP permission-check security fix to stable users upgrading from
0.8.10. Adds the v0.9.1 adversarial suite (headersCommand shell-injection safety,
MCP tolerant-retry gate precision, hostile session.metadata). See CHANGELOG.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants