Skip to content

feat(threads): write, fork, continue into and sync Kiro sessions - #4614

Merged
atuin-bot merged 1 commit into
mainfrom
mkt/kiro-write
Nov 4, 2026
Merged

atuin-bot merged 1 commit into
mainfrom
mkt/kiro-write

Conversation

@BinaryMuse

@BinaryMuse BinaryMuse commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

The write side for Kiro, as #4580 was for Copilot: a thread can now be restored as a Kiro session on another machine, caught up or switched when two copies diverge, forked, and continued into Kiro from another agent, and sync appends to and replaces Kiro's logs. writes_transcripts goes away again, as it did there.

The writer (kiro/rehydrate.rs) puts a session where Kiro looks for it: sessions/<hash of the directory>/sess_<id>/ with the header, the log in Kiro's row shapes (each turn framed by turn_start/turn_end, shell calls as execute_bash with Output:…Exit Code: N), and the session-index line; a fork names its original in the header (parentSessionId, forkedAtMessageId) and under _meta.kiro.atuin. What Kiro needs of a hand-written session was found by probing 2.36.0 and is in the module docs: a tool_call must carry a status or the call and its result drop out of the model's context; foreign ids, foreign tool names, failed results and a missing session_start are all fine; an agent_note reaches the model, so the continuation marker goes there. The reader now links each row to the one before it, so sync sees a Kiro session as a tree, and reads the header's parentSessionId as a fork's parent.

Liveness for an idle copy asks the process table (a kiro-cli-chat or its engine working in the session's directory), since Kiro keeps no per-session lock: a just-restored copy refused its own catch-up otherwise.

Shaken down against the real CLI: a Claude Code thread continued into Kiro resumed there quoting the marker and the carried facts; a captured Kiro session restored under a second KIRO_HOME resumed with its conversation and tool call. The end-to-end suite runs Kiro through the restore, catch-up, switch, fork and continuation cases.

A cross-harness stress test with the real agents (102 hops, 33 of them Kiro, every Kiro pair in both directions) turned up one bug, fixed here: Kiro ends each turn with a redacted reasoning row after the reply, which made every plain catch-up of a native copy look like a divergence, since the restored copy lacked that row and the classifier's fast-forward rule did not know Kiro. The writer now writes the marker back and Kiro is in the rule. The same test showed a written session opening under Kiro's Default profile whatever --agent says, so the header now names the user's chat.defaultAgent.

@BinaryMuse
BinaryMuse added this pull request to stack #4613 October 30, 2026 23:03
@BinaryMuse BinaryMuse changed the title mkt/kiro write feat(threads): write, fork, continue into and sync Kiro sessions Oct 30, 2026
@greptile-apps

greptile-apps Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; the previous branch-mixing issue is fixed.

Summary

Adds writing, restoring, catching up, switching, forking, and continuing into Kiro sessions.

  • Atuin can restore, fork, and continue threads as Kiro sessions.
  • Kiro copies can catch up or switch between conversation branches.

Reviews (6) Β· Last reviewed commit: "fix(threads): fast-forward a Kiro copy o..." Β· Reviewed by Greptile

@BinaryMuse
BinaryMuse marked this pull request as ready for review October 30, 2026 23:25
@atuin-bot

atuin-bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Landed as d784213. GitHub shows this merged once it reaches main.

The write side for Kiro, as #4580 was for Copilot: a thread can now be restored as a Kiro session on another machine, caught up or switched when two copies diverge, forked, and continued into Kiro from another agent, and sync appends to and replaces Kiro's logs. `writes_transcripts` goes away again, as it did there.

The writer (`kiro/rehydrate.rs`) puts a session where Kiro looks for it: `sessions/<hash of the directory>/sess_<id>/` with the header, the log in Kiro's row shapes (each turn framed by `turn_start`/`turn_end`, shell calls as `execute_bash` with `Output:…Exit Code: N`), and the `session-index` line; a fork names its original in the header (`parentSessionId`, `forkedAtMessageId`) and under `_meta.kiro.atuin`. What Kiro needs of a hand-written session was found by probing 2.36.0 and is in the module docs: a `tool_call` must carry a `status` or the call and its result drop out of the model's context; foreign ids, foreign tool names, failed results and a missing `session_start` are all fine; an `agent_note` reaches the model, so the continuation marker goes there. The reader now links each row to the one before it, so sync sees a Kiro session as a tree, and reads the header's `parentSessionId` as a fork's parent.

Liveness for an idle copy asks the process table (a `kiro-cli-chat` or its engine working in the session's directory), since Kiro keeps no per-session lock: a just-restored copy refused its own catch-up otherwise.

Shaken down against the real CLI: a Claude Code thread continued into Kiro resumed there quoting the marker and the carried facts; a captured Kiro session restored under a second `KIRO_HOME` resumed with its conversation and tool call. The end-to-end suite runs Kiro through the restore, catch-up, switch, fork and continuation cases.

A cross-harness stress test with the real agents (102 hops, 33 of them Kiro, every Kiro pair in both directions) turned up one bug, fixed here: Kiro ends each turn with a redacted reasoning row after the reply, which made every plain catch-up of a native copy look like a divergence, since the restored copy lacked that row and the classifier's fast-forward rule did not know Kiro. The writer now writes the marker back and Kiro is in the rule. The same test showed a written session opening under Kiro's Default profile whatever `--agent` says, so the header now names the user's `chat.defaultAgent`.
Base automatically changed from mkt/kiro-subagents to main November 4, 2026 00:58
@atuin-bot
atuin-bot merged commit d784213 into main Nov 4, 2026
4 checks passed
@atuin-bot
atuin-bot deleted the mkt/kiro-write branch November 4, 2026 00:59
atuin-bot pushed a commit that referenced this pull request Nov 4, 2026
### Bug Fixes

- *(daemon)* Include pre-session history in session-preload search ([&#35;4536](#4536))
- *(deps)* Bump pulldown-cmark to 0.13.6 for RUSTSEC-2026-0433 ([&#35;4631](#4631))
- *(mcp)* Show the input schema on bad arguments, and accept query and a string as search terms ([&#35;4640](#4640))
- *(scripts)* Run scripts with process's original umask ([&#35;4651](#4651))
- *(threads)* Open written pi and omp sessions on one root, and on a model omp can use ([&#35;4649](#4649))
- *(threads)* Key a Grok tool result by its call, not its output ([&#35;4652](#4652))


### Features

- *(ai)* Remove TERMINAL.md user context ([&#35;4646](#4646))
- *(api)* Delete a thread with its descendants, and refuse threads under a deleted one
- *(client)* Load ai-session records by id
- *(daemon)* Upload captured threads to octavo
- *(devenv)* A dev shell with CI's toolchain and a sandboxed Atuin ([&#35;4616](#4616))
- *(setup)* New onboarding that asks what to capture and how to search it ([&#35;4637](#4637))
- *(setup)* Ask what to import on a screen of its own, with checkboxes and a button to continue ([&#35;4650](#4650))
- *(threads)* Add Grok Build session capture, resume, and sync ([&#35;4583](#4583))
- *(threads)* Capture Amp threads through a generic atuin threads push, and import them ([&#35;4635](#4635))
- *(threads)* Kiro CLI harness ([&#35;4611](#4611))
- *(threads)* Capture Kiro subagents as child sessions ([&#35;4612](#4612))
- *(threads)* Write, fork, continue into and sync Kiro sessions ([&#35;4614](#4614))
- *(threads)* Carry Kiro's write, edit and search tools, and fix its read offset ([&#35;4633](#4633))
- *(web)* Derive thread state and transcripts, and fake thread rpcs


### Miscellaneous Tasks

- Remove vestigial mentions of TERMINAL.md ([&#35;4648](#4648))


### Refactor

- *(threads)* Replace manual enum dispatches with `enum_dispatch` ([&#35;4639](#4639))


### Testing

- Keep two tests from reading the real environment ([&#35;4617](#4617))
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Nov 4, 2026
…) (#2542)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/atuinsh/atuin](https://github.com/atuinsh/atuin) | patch | `18.24.4` β†’ `18.24.5` |

---

### Release Notes

<details>
<summary>atuinsh/atuin (ghcr.io/atuinsh/atuin)</summary>

### [`v18.24.5`](https://github.com/atuinsh/atuin/blob/HEAD/CHANGELOG.md#18245)

[Compare Source](atuinsh/atuin@v18.24.4...v18.24.5)

##### Bug Fixes

- *(daemon)* Include pre-session history in session-preload search ([#&#8203;4536](atuinsh/atuin#4536))
- *(deps)* Bump pulldown-cmark to 0.13.6 for RUSTSEC-2026-0433 ([#&#8203;4631](atuinsh/atuin#4631))
- *(mcp)* Show the input schema on bad arguments, and accept query and a string as search terms ([#&#8203;4640](atuinsh/atuin#4640))
- *(scripts)* Run scripts with process's original umask ([#&#8203;4651](atuinsh/atuin#4651))
- *(threads)* Open written pi and omp sessions on one root, and on a model omp can use ([#&#8203;4649](atuinsh/atuin#4649))
- *(threads)* Key a Grok tool result by its call, not its output ([#&#8203;4652](atuinsh/atuin#4652))

##### Features

- *(ai)* Remove TERMINAL.md user context ([#&#8203;4646](atuinsh/atuin#4646))
- *(api)* Delete a thread with its descendants, and refuse threads under a deleted one
- *(client)* Load ai-session records by id
- *(daemon)* Upload captured threads to octavo
- *(devenv)* A dev shell with CI's toolchain and a sandboxed Atuin ([#&#8203;4616](atuinsh/atuin#4616))
- *(setup)* New onboarding that asks what to capture and how to search it ([#&#8203;4637](atuinsh/atuin#4637))
- *(setup)* Ask what to import on a screen of its own, with checkboxes and a button to continue ([#&#8203;4650](atuinsh/atuin#4650))
- *(threads)* Add Grok Build session capture, resume, and sync ([#&#8203;4583](atuinsh/atuin#4583))
- *(threads)* Capture Amp threads through a generic atuin threads push, and import them ([#&#8203;4635](atuinsh/atuin#4635))
- *(threads)* Kiro CLI harness ([#&#8203;4611](atuinsh/atuin#4611))
- *(threads)* Capture Kiro subagents as child sessions ([#&#8203;4612](atuinsh/atuin#4612))
- *(threads)* Write, fork, continue into and sync Kiro sessions ([#&#8203;4614](atuinsh/atuin#4614))
- *(threads)* Carry Kiro's write, edit and search tools, and fix its read offset ([#&#8203;4633](atuinsh/atuin#4633))
- *(web)* Derive thread state and transcripts, and fake thread rpcs

##### Miscellaneous Tasks

- Remove vestigial mentions of TERMINAL.md ([#&#8203;4648](atuinsh/atuin#4648))

##### Refactor

- *(threads)* Replace manual enum dispatches with `enum_dispatch` ([#&#8203;4639](atuinsh/atuin#4639))

##### Testing

- Keep two tests from reading the real environment ([#&#8203;4617](atuinsh/atuin#4617))

</details>

---

### Configuration

πŸ“… **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

πŸ”• **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xOTkuMiIsInVwZGF0ZWRJblZlciI6IjQ0LjE5OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/2542
BinaryMuse added a commit that referenced this pull request Nov 9, 2026
A harness atuin reads but can't write yet says so with `writes_transcripts`, and restore, catch-up, fork and continuation into it are refused up front: the resumer offers its copy as it is, never as a continuation target, and `continue_in` returns `ContinueError::Unwritable`. Kiro needed this for its first PR and lost it once its writer landed (#4614); Hermes Agent needs it now.
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.

2 participants