65 Commits
Author SHA1 Message Date
AkitaOnRails e2d7d17d90 fix(run): allow same-owner lease recovery
Refs #795
2026-10-01 16:18:44 -03:00
AkitaOnRails 15a26421a3 fix(workstream): recover stale Codex daemon runs
Fixes #987
2026-10-01 13:40:39 -03:00
AkitaOnRailsandClaude Opus 5.5 013bf691fd docs: fix audited drift in frontend-api, windows, and Codex managed runs
- frontend-api.md (#986): the list, search, and recent routes return bare
  JSON arrays, not `{ "workspaces": … }`-style wrappers (the route tests
  assert `as_array()`); a page read returns `body_markdown`, not `body`; a
  search hit carries workspace/project/kind and no `id`.
- windows.md (#758): native `ai-memory upgrade` is done (#801/#802), not
  in-progress.
- managed-workstreams.md + support matrix (#987): document the Codex shared
  daemon handing hooks a stale AI_MEMORY_RUN_ID and the `--no-daemon`
  workaround until the server-side fix lands.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 02:47:14 -03:00
AkitaOnRailsandClaude Opus 5.5 ae676d4918 fix(run): ai-jail re-exec/offer, --true-yolo semantics, and relaunch after an interrupted run
ai-jail integration (`ai-memory run --yolo`):
- The re-exec built `ai-jail <flags> <exe> run …` with no `--`. ai-jail
  rejects one of its own flags after the command and `run` shares flag names
  with it, so `run claude --yolo --env GH_TOKEN=…` aborted. The invocation now
  emits `--` before the wrapped exe (forwarding a colliding flag additionally
  needs ai-jail >= 2.4.2, whose guard honors the separator; the cross-tool
  test gates on that version).
- The offer only checked for a file named ai-jail: Windows could show it, a
  host without bwrap/sandbox-exec was offered a jail that cannot start, and a
  ~/.local/bin-only install was offered and then not found by the bare
  `Command::new("ai-jail")` re-exec after the run was already cancelled.
  usable_ai_jail(os, lookup) now returns the exact binary to exec only on
  Linux/macOS with the backend present; otherwise no question is asked.

--true-yolo:
- It now implies --yolo (warning, ai-jail offer, harness dangerous mode):
  alone it used to apply Claude's bypassPermissions with no warning. It is
  interchangeable with --yolo for non-Claude harnesses, and recognized after
  native arguments (`run claude --model opus --true-yolo`), where clap leaves
  it in the native argv and it was forwarded to Claude as an unknown option.
- The claude_true_yolo config key only upgrades an explicit yolo launch, as
  its doc comment stated, instead of bypassing permissions on every run.
- Removed what never worked: three CLAUDE_CODE_DISABLE_*RM* env vars Claude
  Code does not read (absent from the 2.1.280 binary and its env reference),
  and an empty permissions.ask array that cannot clear ask rules from other
  scopes (Claude unions them). Docs now state that Claude honors explicit ask
  rules and its command-safety checks in every permission mode.

Relaunch after an interrupted run:
- A launcher killed before releasing its lease (terminal closed, ai-jail
  torn down) left the workstream held for up to 90s and the next launch failed
  after a 5s retry. An interactive launch now parses the holder and expiry from
  the 409, waits for that lease to lapse (bounded by one lease; Ctrl-C aborts),
  then proceeds. A holder that renews meanwhile is reported as live and never
  displaced; the server's busy check stays the only arbiter (security
  inventory row 13b). Non-interactive launches keep the short window.

Tests: usable_ai_jail OS/backend/Windows/exact-path, `--` placement and the
colliding-flag regression (unit + real ai-jail --dry-run), the yolo_modes
table, --true-yolo in both argv positions via real clap parses, the reduced
true-yolo argv, and HTTP-level held-lease wait / renewed-owner / Ctrl-C cases.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 01:53:49 -03:00
John Costa 2a14b5db3f feat(run): finalize the session on exit for harnesses without a session-end hook
Command Code, Kiro CLI (v2 and v3) and Antigravity CLI have no native
session-end hook, so their sessions stayed open until a manual
`ai-memory finalize-session`. When `ai-memory run` launched one of them, it
now finalizes the run's own session after the harness exits: the one named
on the command line or chosen before the spawn, or the one its child linked
under AI_MEMORY_RUN_ID in this checkout, never a discovered one.

SessionId::from_native moves the hooks router's native-id mapping into core
so hook POSTs and the lookup share one key. finalize_session::run is split
into finalize() and report printing so the run reports on stderr. The
harness's exit code is kept; finalizing is bounded by a timeout, Ctrl-C
skips it, and a failure prints the exact finalize-session command.
The lookup matches the ended session too (as --reopen does), because these
harnesses keep capturing under the same id after a resume; a re-end with
nothing new is a no-op on the server.

Closes #941
2026-09-28 22:28:33 -07:00
Éverton Toffanetto fed7d80140 docs(omp): clarify profile selection and install paths 2026-09-27 01:16:35 -03:00
Éverton Toffanetto 86f001c6bf fix(omp): follow OMP's profile rules, PI_CONFIG_DIR and XDG session dir
A named profile (`--profile`, `OMP_PROFILE`, or the legacy `PI_PROFILE`) owns
`~/.omp/profiles/<name>/agent` and ignores `PI_CODING_AGENT_DIR`, as OMP does;
`install-hooks` wrote the extension into `PI_CODING_AGENT_DIR` instead. Profile
names are normalized and refused like OMP does, `PI_CONFIG_DIR` renames the
`~/.omp` root, and on Linux and macOS sessions move to `$XDG_DATA_HOME/omp`
when that directory exists. `install-mcp`, auto-wire, session import,
`backfill`, `doctor` and the `uninstall` sweep follow the same agent dir.

Refs #820
2026-09-27 00:24:41 -03:00
AkitaOnRailsandClaude Opus 4.8 47af33a79c Merge PR #899 into release/2.5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-25 11:32:41 -03:00
AkitaOnRailsandClaude Opus 4.8 a0836577df Merge PR #900 into release/2.5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-25 11:32:41 -03:00
Éverton Toffanetto 041899a1c0 Merge branch 'fix/autowire-run-env' into fix/crush-launch-context 2026-09-25 00:49:53 -03:00
Éverton Toffanetto dbacca6b49 Merge branch 'fix/autowire-run-env' into fix/uninstall-sentinel-sweep 2026-09-25 00:44:52 -03:00
Éverton Toffanetto 8b04b37ba5 Merge branch 'fix/autowire-run-env' into fix/kiro-v3-resume 2026-09-25 00:44:28 -03:00
Éverton Toffanetto 407d55d0f8 Merge remote-tracking branch 'upstream/release/2.5' into fix/autowire-run-env 2026-09-25 00:44:04 -03:00
AkitaOnRails 8f55486e5f Merge branch 'main' into release/2.5
Forward-merge the 2.4.x fix batch (#877,#891,#893,#888,#820,#885,#886,#884,#890,#894,#895) so main stays a subset of release/2.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm

# Conflicts:
#	CHANGELOG.md
#	crates/ai-memory-cli/src/commands/run.rs
#	crates/ai-memory-store/tests/suite/multi_session.rs
2026-09-25 00:22:09 -03:00
Éverton Toffanetto 66b7567aae fix(uninstall): clear auto-wire sentinels and keep the hook bearer for partial uninstalls
`ai-memory uninstall` left the `ai-memory run` auto-wire sentinels behind, so
the next managed launch skipped wiring and captured nothing. Removing hooks or
MCP now deletes every sentinel and lists them in the dry-run plan.
`--only mcp|instructions|skills` no longer deletes the stored hook bearer the
still-installed hooks read.

Refs #820
2026-09-25 00:06:30 -03:00
Éverton Toffanetto 6ca93eb278 fix(run): find, layer onto and attribute Crush sessions as Crush does
`ai-memory run crush`, `backfill` and `doctor` looked for sessions only in
`<cwd>/.crush/crush.db`; they now resolve the data directory as Crush's
`setDefaults` does. The managed context packet no longer drops the `CRUSH.md`
and `AGENTS.md` Crush loads by default, accepts every global `crush.json`
Crush accepts, and carries the global `crushrc` over.

Two fresh managed launches in one checkout could import each other's
transcript. A session a hook in the child linked under the run id now wins
when this checkout's store holds it, and Crush, which has no hooks, claims
only the one top-level session the run created, importing nothing with a
warning when another launch created one too.

Refs #820
2026-09-25 00:05:47 -03:00
Éverton Toffanetto 2aedb95867 fix(run): auto-wire the default Kiro home a v3 default-store resume reads
A Kiro v3 resume that falls back to the default session store drops
`KIRO_HOME` from the child, but auto-wire still installed hooks and MCP under
`KIRO_HOME`, so the resumed session ran without either. Auto-wire now wires
the default home that resume reads.

Refs #820
2026-09-25 00:05:46 -03:00
Éverton Toffanetto 84ef3a64dd chore(omp): move the OMP profile and PI_CONFIG_DIR paths to their own change 2026-09-24 23:39:37 -03:00
Éverton Toffanetto 3c2051f4ce chore(run): move the Crush launch context, data dir and session attribution to their own change 2026-09-24 23:32:18 -03:00
Éverton Toffanetto 7d81d60721 chore(uninstall): move the auto-wire sentinel sweep to its own change 2026-09-24 23:29:04 -03:00
Éverton Toffanetto a4e72075b3 chore(run): move the Kiro v3 resume auto-wire to its own change 2026-09-24 23:27:51 -03:00
Éverton Toffanetto 4dcde8ec2b Merge remote-tracking branch 'upstream/release/2.5' into fix/autowire-run-env 2026-09-24 19:03:13 -03:00
Éverton Toffanetto 6295dd814b fix(run): wire hooks and MCP where the launch environment points
`ai-memory run --env/--env-file` values reached the spawned harness and
native-session resolution but not first-launch auto-wire, so hooks and MCP
landed in the default config home, and a sentinel keyed only on agent and
version skipped a second account on the same version. Auto-wire now resolves
every install target from the launch environment, the Codex MCP entry follows
`CODEX_HOME`, and the sentinel also keys on the resolved hook and MCP paths.

Fixes found on the same paths: OMP profile and PI_CONFIG_DIR resolution,
blank relocation values, uninstall leaving sentinels behind, the Crush
context packet (default context files and the global crushrc), the Crush data
directory lookup, session discovery with concurrent launches in one checkout,
and Kiro v3 resume wiring. Spawned-server test fixtures now survive losing a
free port to another socket.

Refs #820
2026-09-24 19:03:13 -03:00
Éverton Toffanetto 762d5ae243 fix(run): import the session linked during a managed run
`managed_runs.native_session_id` starts as the workstream's current session
when a run is prepared, and a hook in the launched harness replaces it through
the link path. A link that repeated the prepared session left no trace, so
after exit `ai-memory run` fell back to the newest session in the checkout,
which a concurrent launch there may own.

Migration V67 adds `managed_runs.native_session_linked_at`, stamped by
`link_native_session` for its own run and dropped by `finish` when the session
changes. The run status reports it as `native_session_linked` (an older server
omits it and reads as false), and the launcher imports a linked session when
this checkout's store holds it, never falling back to one it set aside. A
process the child starts inherits the run id, so a session from another
checkout is refused; OpenCode is checked by the session's recorded directory.

Refs #820
2026-09-24 18:57:06 -03:00
AkitaOnRails 98d0a9e483 Merge branch 'main' into release/2.5
Forward-merge the 2.4.x fixes (#875, #824, #861, #873, #866, #871, #872) so main stays a subset of release/2.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm

# Conflicts:
#	CHANGELOG.md
#	crates/ai-memory-cli/src/commands/serve.rs
#	crates/ai-memory-mcp/src/server.rs
2026-09-24 17:06:25 -03:00
Felipe Neves RicardoandClaude Opus 5.5 068a040fb7 fix(wrapper): keep the native client and its hook bundle out of the cache
`ai-memory run` auto-wires hooks whose command is the wrapper's native
client path. Keeping that client under ~/.cache meant a cache flush broke
every hook of Claude Code, Codex, Kimi Code, Command Code, Kiro CLI v3,
Grok and Antigravity CLI. Keep it in $XDG_DATA_HOME/ai-memory instead.

The wrapper also deleted the release's hooks/ bundle after extraction,
so auto-wire failed with "could not locate hooks directory" for
script-based harnesses on a host where install-hooks never ran. Keep
the bundle beside the client, where install-hooks looks for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PoLrSBy2WePNoHhD8BJHD
2026-09-24 14:25:28 -03:00
AkitaOnRailsandClaude Opus 4.8 5bdc206543 Add --env/--env-file pass-through to ai-memory run (#820)
Users who launch harnesses via env-wrapping aliases (`env
CLAUDE_CONFIG_DIR=... claude`) had no first-class way to pass that
environment through `ai-memory run`. Add a repeatable `--env KEY=VALUE`
and an `--env-file <path>` (blank lines and `#` comments skipped),
wrapper-owned like `--yolo`/`--executable` so they must precede the
harness name. A later `--env` overrides a same-key `--env-file` entry;
values are taken literally.

The resolved environment reaches both the spawned harness `Command`
and `build_launch_plan`'s own native-session-store resolution (new
`build_launch_plan_with_env`, layered in front of the real process
environment), so a caller-scoped `CLAUDE_CONFIG_DIR` override no longer
requires exporting the variable into the invoking shell for
ai-memory's own hook/session resolution to agree with the harness.

This is the tractable first slice of #820; named launch profiles /
persisted configs remain out of scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-23 14:54:58 -03:00
AkitaOnRailsandClaude Opus 4.8 f500f5476e docs(run): export native store env (CLAUDE_CONFIG_DIR) before ai-memory run
Document that ai-memory run resolves the native session dir and installs
hooks from its own environment, so a custom CLAUDE_CONFIG_DIR set only
inside a harness wrapper causes a split-brain and "native transcript
import failed" (#820). Export per-account config dirs before invoking
ai-memory run. The launch-configuration ergonomics half of #820 remains a
separate design-first feature.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-22 17:43:42 -03:00
Éverton Toffanetto a109c0cf06 fix(run): cancel native session selection on interrupt 2026-09-20 01:33:09 -03:00
AkitaOnRailsandClaude Opus 4.8 da8d07dcc9 feat(run): auto-install a harness's hooks + MCP on first ai-memory run
Managed launch is the recommended way to start a harness, so it should be the
path that makes capture "just work" — but it didn't: `ai-memory run kimi`
captured nothing if the Kimi hooks/MCP had never been manually installed.

`ai-memory run <harness>` now auto-installs that harness's ai-memory lifecycle
hooks and MCP server the first time it launches the harness, if they are not
already wired. It runs before the child spawns (so the harness picks up the
fresh hooks), is idempotent and one-time per harness + binary version (a
per-agent sentinel under <data_dir>/autowire-state/, keyed on the version so an
upgrade re-stages the fresh bundle), and is best-effort — an install failure
warns with the manual command and the harness still launches. It reuses the
existing install-hooks / install-mcp apply paths, which preserve unrelated user
config. Harnesses with no installer support (Crush) are skipped cleanly; Pi
wires hooks but has no MCP client to write.

On by default; opt out with `ai-memory run --no-autowire` (accepted before or
after the harness, so it is never forwarded to the child), AI_MEMORY_RUN_AUTOWIRE=false,
or run_autowire = false. Manual install-hooks/install-mcp remain for harnesses
never launched through run. Documented as the preferred launch path ("if in
doubt, run with ai-memory") in the README and managed-workstreams docs.

Tests: harness->AgentChoice mapping completeness (+ Crush skip, Pi no-MCP),
sentinel keying by agent+version, a real install-through-the-installers test
asserting hooks + MCP land AND unrelated user config is preserved AND a gated
re-launch is byte-identical (paths injected so it never touches real $HOME),
unsupported-harness-writes-nothing, present-sentinel-short-circuits, and
--no-autowire parsing in both positions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-16 11:28:54 -03:00
Maiky GuanaesandClaude Sonnet 5 fd7f4f864e feat(run): accept claude*-prefixed harness names
Multi-account users (e.g. Corporate + Personal) name a PATH wrapper
script per account (claude-corp, claude-personal, ...) and select one
with --executable, since PATH resolution bypasses shell-only aliases.
Previously the harness positional only accepted the fixed claude/
claude-code names, so anything else was rejected as an unknown value
before --executable even got a chance to matter.

parse_run_harness_choice now falls back to a case-insensitive `claude`
prefix match after the normal ValueEnum lookup, so any claude*-prefixed
name (claude-corp, claude-personal, claudex, ...) resolves to
RunHarnessChoice::Claude. Every other unknown value is still rejected
with the existing "expected one of" error. One alias mechanism, not
two: no separate claude-any special case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 14:22:32 -03:00
enrell 33b5dd2c2d feat(opencode2): add first-party OpenCode 2.0 beta support
MCP (mcp.servers + oauth:false), dependency-free plugin shape
(ai-memory-opencode2.ts), managed run opencode2, v2 transcript
adapter (session_v2/session_message), acceptance case, docs,
changelog. Shares v1's config dir, session store, and agent kind;
no migration. Verified live against beta-18999.
2026-09-03 23:30:16 -03:00
AkitaOnRailsandClaude Fable 5 0b35ed873e docs: the why/when pass - adoption guidance over feature lists (item 8)
Every user-facing doc was graded on four axes (what / why / when-to /
real example, including when-NOT-to). Fixes for the highest-impact
gaps:

- managed-workstreams: 'Do you need this?' - hooks + handoffs already
  cover the quit-Claude-open-Codex case; managed runs are for native
  resume surviving a harness switch. Skip guidance included.
- auto-improvement-loop: a 60-second user-facing top for a feature that
  is on by default - what auto-approve means, the explicit
  require_approval=true recommendation for shared/team servers, cost
  shape, and what a staged proposal sidecar contains. Research prose
  retained below the fold.
- okf: opens with the user payoff (hand a bundle to someone without
  ai-memory; export-okf one-liner; what the receiving side sees)
  before the conformance design.
- temporal: when to reach for as_of (audits/post-mortems; plain
  memory_query is right 99% of the time) plus a worked
  postgres-then-migrated example with both results.
- typed-edges: the gotcha->fixes->contradicts->lint loop as a concrete
  scenario, and 'plain wikilinks remain the default' skip guidance.
- experience: a sample staged cross-session proposal.
- config template: consolidation and slots blocks say why/when, not
  just what.

Accuracy bugs found by the same sweep: auto-scope's config snippet
still called mode="single" the default (per_actor since v1.39); ZCode
was listed twice with conflicting statuses in both support matrices
(it has MCP #529 AND hooks #532 - merged to one Supported row); the
README docs index listed ROADMAP-2.0 twice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-01 20:10:53 -03:00
676e55f43b feat(cli): add interactive workstream resume picker (#534)
* feat(cli): add interactive workstream resume picker

* chore(changelog): restore the blank line before [1.36.0]

The branch dropped one blank line separating the end of [1.37.0] from the
[1.36.0] heading. Whitespace only, but it sits inside an already-released
section, so `check-changelog-frozen.sh` rejects it - correctly: the guard
cannot tell a stray edit from a rewritten entry, and should not try.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm

---------

Co-authored-by: AkitaOnRails <fabioakita@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 22:58:59 -03:00
ff4f260267 feat(cli): add ai-memory rename-workstream for checkout-local renames (#538)
Workstream names were fixed at `run --new` time and had no correction path,
so a typo outlived the work it labelled and the only escape was starting a
new workstream and abandoning the ledger attached to the old one.

The rename selects by current name or by the stable id `workstreams` prints,
resolving the same (workspace, project, repository, worktree) identity `run`
selects with. Both selectors repeat the checkout predicate: `workstreams.id`
is globally unique, so without it a caller holding an id from another
checkout could retitle a workstream their request never named. An id outside
the resolved scope reads as absent rather than renamable.

It is metadata only. `workstream_events`, `managed_runs`, and
`workstream_native_sessions` all key on `workstreams.id`, so the rename is a
single-row update with nothing to cascade, and `selected_at` and
`updated_at` are deliberately left untouched — relabelling is not activity.
Neither the discovery listing order nor the workstream a bare `ai-memory
run` resumes moves as a side effect of fixing a typo.

The destination is validated exactly like a `--new` name and refused with a
named conflict when another workstream in the same checkout already holds
it, turning the UNIQUE constraint into a typed error instead of a bare
SQLite failure. Renaming a workstream to the name it already has writes
nothing and is not an error.

The new `/workstream/rename` route requires NormalWrite rather than the
NormalRead its sibling discovery read uses, and resolves scope through
`lookup_existing_scope` so a rename never creates the workspace or project
it names. The Docker shell wrapper routes the command through its native
host client alongside `run`, `show`, `continue`, and `workstreams`, since
repository identity is a host resource the helper container cannot see.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: AkitaOnRails <fabioakita@gmail.com>
2026-08-31 22:23:50 -03:00
7e02f09f3b feat(cli): add ai-memory workstreams checkout-local discovery (#499)
List the managed workstreams that `run --workstream` can select from the
current checkout, so branching between lines of work no longer requires
remembering names or reading the database by hand.

The list resolves the same (workspace, project, repository, worktree)
identity `run` selects with, puts the current selection first, then orders
by recent activity. Rows carry the linked harnesses and the stable
workstream id that `workstream-search --workstream-id` accepts.

Discovery is a read of workstream metadata only: checkout paths, repository
and worktree fingerprints, and native session ids never travel back to the
client. The new `/workstream/recent` route requires NormalRead, resolves
scope through `lookup_existing_scope` (no-create, fails closed), and bounds
the limit server-side.

The Docker shell wrapper routes the command through its native host client
alongside `run`, `show`, and `continue`, since repository identity is a host
resource the helper container cannot see.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: AkitaOnRails <fabioakita@gmail.com>
2026-08-28 15:07:38 -03:00
AkitaOnRailsandClaude Opus 5 47f6917e2c docs(run): explain agent detection when running inside Herdr
Herdr identifies a pane's agent from the foreground process, falling back
to matching the agent's own screen output. `ai-memory run` defeats the
first half: the foreground process is the wrapper and the agent is its
child, sharing one process group whose leader is `ai-memory`. So the pane
shows no agent until the harness paints a title Herdr recognizes, which
can be well after launch and may never happen for a harness matching no
manifest.

Deliberately not fixed in code. Herdr scopes its `HERDR_AGENT` hint to the
pane's foreground process, and a process cannot amend its own environment
after exec, so the wrapper cannot describe itself from the inside. Setting
the variable on the agent it spawns would put it somewhere Herdr does not
look — code that reads like a fix while doing nothing.

Documents the two things that do work: naming the agent on the command
(`HERDR_AGENT=codex ai-memory run codex`), and installing Herdr's own agent
integration, which reports identity and lifecycle state over Herdr's socket
and is authoritative regardless of process detection. Notes that the two
hook mechanisms write to separate files and that ai-memory's installer
preserves foreign entries.

No behavior change; docs only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 23:04:03 -03:00
AkitaOnRails 813b51aed1 feat(workstream): support Command Code sessions (#373) 2026-08-07 15:29:27 -03:00
AkitaOnRails ad7243eebe fix(workstream): accept current Kimi session cwd (#382) 2026-08-07 14:51:06 -03:00
AkitaOnRails bfee1547d2 feat(workstream): support Kiro CLI v3 sessions (#356) 2026-08-07 14:32:47 -03:00
AkitaOnRails 7a6490c134 docs(command-code): narrow managed acceptance gate 2026-08-05 20:46:37 -03:00
AkitaOnRails fe2bd57d13 feat(command-code): add verified MCP and hook support 2026-08-05 17:47:03 -03:00
AkitaOnRails e75f9b8676 docs(kiro): align open-ticket blockers with current contracts 2026-08-04 16:00:10 -03:00
AkitaOnRails eb05a773c7 fix(workstream): harden explicit Kiro v2 support 2026-08-04 13:21:13 -03:00
Samir Hanna VerzaandClaude Fable 5 4429adc34c feat(workstream): add a v2-engine Kiro CLI managed-workstream adapter
Add `ai-memory run kiro` (alias `kiro-cli`) for the AWS Kiro CLI (#356),
deliberately scoped to the binary's default v2 agent engine.

Cross-engine resume is prevented by construction, not detection: Kiro v3
sessions occupy a separate id space the v2 engine cannot resume (the
resume hint printed after a v3 session silently starts a fresh v2
session unless --v3 is added), and the v3 persisted-session format is
not publicly documented — so any `--v3`, `--mode`, or non-v2
`--agent-engine` selection turns the whole invocation into an unmanaged
passthrough with argv byte-identical. Headless `--no-interactive` runs
persist to Kiro's v1 SQLite store rather than the v2 session files this
adapter reads, so they pass through too, as do the one-shot
list/delete/model flags and every root utility subcommand except `chat`
(list verified against kiro-cli 2.16.0 --help-all).

Launch planning: session ids are server-assigned, so a fresh launch
injects nothing and the session is linked by the session-start hook or
discovered post-exit; a returning session appends `--resume-id <id>`
after user arguments (accepted at the root and on `chat`, verified on
the 2.16.0 binary). Explicit `-r/--resume`, `--resume-id`,
`--resume-picker`/`--list` selections always win. Kiro's `-v` is
verbose, not version, and stays managed.

Discovery/import: the interactive store is flat —
`$KIRO_HOME/sessions/cli/<uuid>.json` metadata + `<uuid>.jsonl` event
stream — and the adapter matches checkouts on the metadata `cwd`,
requiring the metadata session_id to agree with the file stem. The
parser imports the versioned v1 envelope (Prompt / AssistantMessage
with toolUse parts / ToolResults), ignores unknown record kinds for
forward compatibility, and annotates unknown envelope versions and
non-text parts as explicit losses. The stream is not verified
append-only, so it shares Kimi's rewrite tolerance: a prefix-hash
cursor that resets and replays on in-place rewrites, with stable
line-hash record ids deduplicating server-side.

`--yolo` maps to the official v2 flag `--trust-all-tools`, treats
`-a`/`--trust-tools` as already-satisfying (an explicit narrower trust
set is never widened), and maps nothing on non-v2 engines — v3 replaced
the flag with permissions.yaml — with a stderr notice.

Kiro joins the automatic bare-`run` pool (client and server side) and
the deterministic phase of the acceptance script, including a
byte-identical `--v3` passthrough check; the real-harness phase skips
kiro with an explanation because scripted headless turns cannot write
the store the adapter reads. Session-file shapes derive from public
kiro-cli 1.29.x references and are documented as pending revalidation
on a live logged-in install; the CLI argument contract was verified
against kiro-cli 2.16.0 locally.

Closes #356.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LJvj7D7czyZzqk4pDXgLxY
2026-08-04 13:07:51 -03:00
AkitaOnRails dc2a210cf4 fix(cli): harden global managed resume 2026-08-03 10:31:52 -03:00
Vivaldo JuniorandClaude Opus 5 82882ba87d feat(cli): add ai-memory continue for global session resume
Bare `ai-memory run` already continues the current checkout, but its
workstream lookup is keyed by (workspace, project, repo fingerprint,
worktree fingerprint), so it requires a `cd` into the project first.
Nothing resolved "the checkout I last worked in" from an arbitrary
directory.

`continue` fills that gap without new server state. Every successful
managed prepare already refreshes `ProjectLink::linked_at` in the
client-local registry, so the newest link is the last checkout used.
The command orders links by that stamp, revalidates the newest one, and
then delegates to the same bare-mode launch with the resolved directory,
including automatic harness selection.

Selection is revalidated on this host before anything launches. The
recorded path must still canonicalize to itself, which rejects a checkout
that moved or was replaced by a symlink, and it must still resolve to the
same (workspace, project), which prevents attaching a session to a
directory that now belongs to a different project. A link failing either
check is reported on stderr and skipped in favor of the next-newest, and
the chosen project and path are always printed, so a resume never
silently lands somewhere else. Stored strings are stripped through the
existing terminal filter before display.

Native harness arguments and `--executable` are rejected at parse time
because bare mode does not know which harness it will pick.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 17:44:16 -03:00
AkitaOnRails b75699f2b3 fix(cli): harden project-first managed launches 2026-08-01 11:21:33 -03:00
AkitaOnRails fc0b30657a test(workstream): harden Antigravity managed support 2026-08-01 10:28:02 -03:00
Vivaldo JuniorandClaude Opus 5 30b9040b42 feat(workstream): manage Antigravity CLI as a launcher harness
`ai-memory run antigravity` (aliases `antigravity-cli`, `agy`) joins an
Antigravity session to the same workstream as the Claude Code or Codex
sessions on the same checkout.

`agy` accepts no caller-chosen id for a new conversation, so a fresh
launch injects nothing and the id is linked by the hooks or discovered
afterwards; a linked resume passes `--conversation <id>`. `--continue`
and `-c` are respected as explicit user choices and never overridden.
`--yolo` maps to `--dangerously-skip-permissions`, and the utility
subcommands pass through without a selector.

Conversation discovery reads the per-conversation SQLite databases under
`~/.gemini/antigravity-cli/conversations/`: the id is the file name, so
locating one needs no scan, and the workspace comes from two
self-describing protobuf fields in `trajectory_metadata_blob`. Only
conversations opened on the current directory are offered, and a
database whose metadata is shaped differently — an older or newer `agy`
— is skipped rather than failing the listing. The field walk is bounds
checked throughout and reads nothing else from the store.

Step payloads are undocumented, unversioned protobuf whose step-type
enum changes between releases, so conversation text is deliberately not
decoded: the visible-event ledger for this harness comes from
lifecycle-hook capture, and transcript export fails with a message
saying so. Antigravity is not part of the no-argument auto-detection
pool.

The server-side managed-run allowlist accepts the agent kind too;
without it the launch is rejected after the user has already chosen a
project and a harness.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 10:09:53 -03:00