Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d8525e8
feat(session-context)!: detect the AI editor and select it with --editor
rhuanbarreto Aug 7, 2026
3308f0d
docs(governance): record how harness detection differs from install d…
rhuanbarreto Aug 7, 2026
94d1d47
fix(session-context): match Cursor's own slugify for dot-segment paths
rhuanbarreto Aug 7, 2026
084ef4c
docs: regenerate llms-full.txt
rhuanbarreto Aug 7, 2026
b384cbe
fix(session-context): read --root through the parent-option merge
rhuanbarreto Aug 7, 2026
153659e
refactor(session-context): derive --editor choices from the detection…
rhuanbarreto Aug 7, 2026
70c3b04
docs: regenerate llms-full.txt
rhuanbarreto Aug 7, 2026
61757ce
feat(session-context): read Codex and Pi sessions
rhuanbarreto Aug 8, 2026
d91bc87
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
38c49d5
perf(session-context): bound rollout discovery and read only session …
rhuanbarreto Aug 8, 2026
fed8934
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
07cd4c6
test(session-context): cover the new readers' untested paths
rhuanbarreto Aug 8, 2026
47636a8
feat(session-context): read Antigravity CLI conversations
rhuanbarreto Aug 8, 2026
d538884
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
cd2ebe8
fix(session-context): read Antigravity desktop app conversations too
rhuanbarreto Aug 8, 2026
664e748
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
6266d98
test(session-context): clear every harness marker in the auto suite
rhuanbarreto Aug 8, 2026
96dce7f
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
c53a7ec
fix(session-context): read Codex CLI turns, which use a different eve…
rhuanbarreto Aug 8, 2026
e0c69b2
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
5faaaab
fix(session-context): read Pi's active branch and drop prose-less turns
rhuanbarreto Aug 8, 2026
cd5d448
docs: regenerate llms-full.txt
rhuanbarreto Aug 8, 2026
6e86874
fix(session-context): read a nested session id without a flat variable
rhuanbarreto Aug 8, 2026
56ac249
fix(session-context): skip Copilot turns that carry only tool calls
rhuanbarreto Aug 8, 2026
8154018
docs(claude): require live-session verification for session readers
rhuanbarreto Aug 8, 2026
bb911bd
Merge branch 'main' into claude/session-context-editor-detection-ae9bf4
rhuanbarreto Aug 8, 2026
56a5431
refactor(session-context): address review and widen error-path coverage
rhuanbarreto Aug 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .archgate/adrs/ARCH-004-no-barrel-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ A **re-export** is any `export { X } from "./other-module"` or `export type { X
Files named `index.ts` that contain actual logic are **not** barrel files and are permitted. Examples of permitted `index.ts` files:

- `src/commands/adr/index.ts` — defines `registerAdrCommand()` with command group composition logic
- `src/commands/session-context/index.ts` — defines `registerSessionContextCommand()` with subcommand composition logic
- `src/commands/plugin/index.ts` — defines `registerPluginCommand()` with subcommand composition logic

## Do's and Don'ts

Expand Down
4 changes: 3 additions & 1 deletion .archgate/adrs/ARCH-014-prefer-bun-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ All environment variable access in `src/` MUST use `Bun.env` instead of `process
- **DO** use nullish coalescing for defaults: `Bun.env.NODE_ENV ?? "production"`
- **DO** use `Boolean(Bun.env.CI)` for truthy checks on environment flags — but only inline, as one operand of a larger `&&`/`||` expression, or assigned to a `const` first. `Boolean(x)` used as the _sole, direct_ condition of `if (...)`/`cond ? a : b`/`!x` trips `eslint(no-extra-boolean-cast)` ("redundant Boolean call"), since that position is already boolean-coerced — assign to a `const` first (see Implementation Pattern) or use an explicit `!== undefined && !== ""` comparison instead
- **DO** keep `process.env` in test files (`tests/`) where test harness compatibility is needed
- **DO** normalize a value through `usableEnv()` (`src/helpers/paths.ts`) before using it as a lookup key, path segment, or identifier — it maps both `""` and the literal string `"undefined"`, which shells and tooling surface for an unset variable, to `null`

### Don't

- **DON'T** use `process.env` in any file under `src/` — use `Bun.env` instead
- **DON'T** create wrapper functions around `Bun.env` — access it directly
- **DON'T** create wrapper functions around `Bun.env` — access it directly. `usableEnv()` is not such a wrapper: it validates a value already read from `Bun.env`, and performs no lookup of its own
- **DON'T** default an env value to an empty string (`Bun.env.FOO ?? ""`) when the consumer distinguishes "absent" from "supplied" — `""` reads as absent at the far end, so a rejected value becomes indistinguishable from an unset one and the failure surfaces as silently wrong behavior rather than an error
- **DON'T** destructure `Bun.env` (e.g., `const { HOME } = Bun.env`) — the proxy-based implementation may not support it reliably across versions; access properties individually

## Implementation Pattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Conversely, every heading whose command path's parent chain consists of command-
**Scope:**

- **Module-backed subcommands, at every depth.** A group is any directory with an `index.ts`; its subcommands are sibling `<sub>.ts` modules and child groups. `src/commands/adr/domain/add.ts` is the command `adr domain add` and needs that heading in `adr.mdx`.
- **In-module subcommands are manual territory.** Subcommands registered inside a single module (e.g. `session-context/claude-code.ts` registering `list`/`show`) are invisible to file-layout discovery: their headings are permitted, not orphan-flagged, and their coverage rests on code review.
- **In-module subcommands are manual territory.** Subcommands registered inside a single module (e.g. `session-context.ts` registering `list`/`show`) are invisible to file-layout discovery: their headings are permitted, not orphan-flagged, and their coverage rests on code review. A heading is orphan-checked only when every ancestor in its command path is a group directory, so a command whose parent is a plain module — or a top-level command with no directory at all — is exempt.
- **EN docs only.** The pt-br mirror is enforced by GEN-002.
- **Website docs only.** The skill reference (`commands.md` in plugin directories) is in a separate repository and cannot be checked from this project. Its sync is a manual responsibility documented in the Do's section below.

Expand Down Expand Up @@ -75,7 +75,7 @@ Conversely, every heading whose command path's parent chain consists of command-
### Risks

- **Non-standard heading format bypasses the rule.** A heading like `## Import ADRs` instead of `## archgate adr import` goes undetected. **Mitigation:** The Do's section specifies the required format, and the rule's fix suggestion includes the expected heading text.
- **Orphan detection is depth-limited by design.** A heading whose parent chain ends in a leaf module (e.g. `#### archgate session-context claude-code list`) cannot be verified against the file layout and is never orphan-flagged, so a stale in-module subcommand heading survives the rule. **Mitigation:** reviewers check in-module subcommand docs when the registering module changes.
- **Orphan detection is depth-limited by design.** A heading is orphan-flagged only when every ancestor in its command path is a group directory. A heading under a leaf module, or under a top-level command with no directory (e.g. `### archgate session-context list`), cannot be verified against the file layout, so a stale in-module subcommand heading survives the rule. **Mitigation:** reviewers check in-module subcommand docs when the registering module changes.

## Compliance and Enforcement

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ export default {

// Docs -> subcommand: a heading is an orphan only when its parent
// chain consists of group directories — a heading under a leaf
// module (e.g. "session-context claude-code list") documents an
// in-module subcommand the file layout cannot verify.
// module (e.g. "session-context list") documents an in-module
// subcommand the file layout cannot verify.
const lowerPaths = new Set([...cmdPaths].map((p) => p.toLowerCase()));
for (const docPath of [...documented].sort()) {
if (lowerPaths.has(docPath)) continue;
Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ Editor integrations share the `EditorTarget` union. Adding a new editor requires
5. `src/commands/plugin/install.ts` — extend `.choices([...] as const)` and add a case to `installForEditor` + the manual-instructions `catch`
6. `src/commands/plugin/url.ts` — extend `.choices([...] as const)` and branch before the URL ternary
7. Tests that assert the exact choice list: `tests/commands/plugin/install.test.ts`, `tests/commands/plugin/url.test.ts`, and `tests/helpers/editor-detect.test.ts` (length + id order)
8. To make the editor's transcripts readable, also extend `src/helpers/harness-detect.ts` (`DetectedHarness` union and the `SIGNALS` table), the `listFor`/`readFor` switches in `src/helpers/session-context-auto.ts`, and the `EDITORS` choice list in `src/commands/session-context.ts`

**A session reader must be verified against a live session of the editor, not against fixtures.** Every harness records a turn where the agent only issued tool calls as a message whose prose content is empty; a reader that maps events to transcript entries without checking emits it as a blank entry. Skip a turn whose content preview is empty after trimming. The same class of gap hides in event shapes: one editor's CLI and desktop distribution can write the same conversation in different shapes, and a reader taught only one of them returns zero turns for the other. Fixtures agree with whatever the reader already assumes, so neither is visible until a real transcript is read.

**Two detections answer different questions — keep them apart.** `editor-detect.ts` asks whether an editor is _installed_, so a config directory or a binary on PATH is proof. `harness-detect.ts` asks which editor is _running this process_, where only a variable the editor injects into its subprocesses counts; an installed-but-idle editor must never register there. Reaching for `copilotConfigDir()` or a PATH probe in the runtime path would make every user of that editor look like they are inside it.

User-scope editors (e.g., opencode) write to a path resolved in `paths.ts` rather than the project tree — `configureEditorSettings` returns that path for the init summary and the real work happens in `tryInstallPlugin`.

Expand Down
Loading
Loading