samagotchi 0.61.0 → 0.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +91 -1
- data/README.md +4 -1
- data/bin/chi +3 -2
- data/docs/architecture.md +3 -0
- data/docs/cli.md +26 -9
- data/docs/configuration.md +33 -20
- data/docs/context.md +21 -3
- data/docs/guardrails.md +2 -1
- data/docs/hooks.md +14 -3
- data/docs/internals/engine.md +24 -11
- data/docs/internals/prompt-caching.md +6 -1
- data/docs/memory.md +1 -1
- data/docs/plugins.md +131 -5
- data/docs/releasing.md +1 -1
- data/docs/sessions.md +4 -4
- data/docs/sub-agent.md +6 -0
- data/docs/testing.md +10 -4
- data/lib/samagotchi/answer_refs.rb +18 -26
- data/lib/samagotchi/bridge.rb +23 -1
- data/lib/samagotchi/bundles/claude-peer/manifest.yml +22 -0
- data/lib/samagotchi/bundles/claude-peer/plugin.rb +406 -0
- data/lib/samagotchi/bundles/claude-peer/scripts/chi-peer-SKILL.md +104 -0
- data/lib/samagotchi/bundles/claude-peer/scripts/pair +66 -0
- data/lib/samagotchi/bundles/claude-peer/skill_claude_peer.md +60 -0
- data/lib/samagotchi/bundles/dev/manifest.yml +2 -1
- data/lib/samagotchi/bundles/github-pr/manifest.yml +3 -3
- data/lib/samagotchi/bundles/github-pr/plugin.rb +70 -14
- data/lib/samagotchi/bundles/loop-guard/manifest.yml +2 -2
- data/lib/samagotchi/bundles/loop-guard/plugin.rb +17 -6
- data/lib/samagotchi/bundles/slow-commands/manifest.yml +2 -2
- data/lib/samagotchi/bundles/slow-commands/plugin.rb +5 -1
- data/lib/samagotchi/bundles/source-links/hooks/source_links.rb +58 -3
- data/lib/samagotchi/bundles/source-links/manifest.yml +4 -4
- data/lib/samagotchi/bundles/source-links/source_links.md +1 -1
- data/lib/samagotchi/bundles/system/manifest.yml +2 -2
- data/lib/samagotchi/bundles/system/memory_guide.md +1 -1
- data/lib/samagotchi/context_absorber.rb +25 -6
- data/lib/samagotchi/engine.rb +9 -0
- data/lib/samagotchi/engine_peers.rb +1 -0
- data/lib/samagotchi/idle_recap.rb +2 -3
- data/lib/samagotchi/image_store.rb +8 -0
- data/lib/samagotchi/kernel_loop.rb +7 -16
- data/lib/samagotchi/llm/chat_loop.rb +23 -15
- data/lib/samagotchi/plugin/api.rb +36 -18
- data/lib/samagotchi/plugin/attached_context.rb +7 -4
- data/lib/samagotchi/reasoning_history.rb +22 -4
- data/lib/samagotchi/recap_setup.rb +3 -3
- data/lib/samagotchi/row_refs.rb +125 -0
- data/lib/samagotchi/session.rb +12 -0
- data/lib/samagotchi/session_metrics.rb +24 -2
- data/lib/samagotchi/terminal_ui/attach_launcher.rb +6 -3
- data/lib/samagotchi/terminal_ui/attached_loop.rb +26 -9
- data/lib/samagotchi/terminal_ui/formatting.rb +1 -1
- data/lib/samagotchi/terminal_ui.rb +57 -14
- data/lib/samagotchi/tool_activity.rb +8 -4
- data/lib/samagotchi/tool_response.rb +5 -4
- data/lib/samagotchi/tool_row_fields.rb +4 -2
- data/lib/samagotchi/tool_runner.rb +16 -3
- data/lib/samagotchi/tools/builtins.rb +9 -2
- data/lib/samagotchi/tools/execute.rb +37 -7
- data/lib/samagotchi/tools/peers.rb +3 -2
- data/lib/samagotchi/tools/registry.rb +5 -3
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/app.rb +20 -5
- data/lib/samagotchi/web/message_parts.rb +17 -9
- data/lib/samagotchi/web/public/activity.js +6 -3
- data/lib/samagotchi/web/public/app.js +106 -106
- data/lib/samagotchi/web/public/card.js +73 -23
- data/lib/samagotchi/web/public/chains.js +24 -24
- data/lib/samagotchi/web/public/command_view.js +39 -35
- data/lib/samagotchi/web/public/context_chips.js +92 -64
- data/lib/samagotchi/web/public/copy.js +7 -15
- data/lib/samagotchi/web/public/diff_view.js +20 -23
- data/lib/samagotchi/web/public/families_view.js +51 -39
- data/lib/samagotchi/web/public/format.js +0 -48
- data/lib/samagotchi/web/public/images.js +12 -16
- data/lib/samagotchi/web/public/index.html +61 -10
- data/lib/samagotchi/web/public/keep_focus.js +24 -0
- data/lib/samagotchi/web/public/lists_view.js +13 -13
- data/lib/samagotchi/web/public/llm_context_chip.js +55 -34
- data/lib/samagotchi/web/public/question_card.js +11 -0
- data/lib/samagotchi/web/public/question_cards.js +63 -7
- data/lib/samagotchi/web/public/read_view.js +10 -9
- data/lib/samagotchi/web/public/ref_menu.js +18 -5
- data/lib/samagotchi/web/public/refs.js +113 -15
- data/lib/samagotchi/web/public/scope.js +23 -0
- data/lib/samagotchi/web/public/scroll.js +42 -0
- data/lib/samagotchi/web/public/stage_model.js +22 -3
- data/lib/samagotchi/web/public/stage_view.js +299 -70
- data/lib/samagotchi/web/public/timing.js +1 -8
- data/lib/samagotchi/web/public/turn_html.js +122 -61
- data/lib/samagotchi/web/public/turn_model.js +49 -0
- data/lib/samagotchi/web/public/turn_view.js +167 -116
- data/lib/samagotchi/web/public/vendor/directive.js +8 -0
- data/lib/samagotchi/web/public/vendor/directives/unsafe-html.js +8 -0
- data/lib/samagotchi/worker.rb +49 -32
- data/lib/samagotchi/worker_inbound.rb +17 -14
- metadata +10 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 20b05cd0da6dfdd621eba3b2add37f00b2abe96c2e3950d8ddd066bdf3078424
|
|
4
|
+
data.tar.gz: ecf5784f9f82c8a8c9e813185570d326a3f4d9ad3a404033f53abf1b62a20902
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 302c8ccf54cc947c9165fe8e30f4d32b4054ee02a1e2d62cbb7d7942a30574af58af84a7eafc5b2daf24a8f167e98024e2798fcacccf597b919435019d498613
|
|
7
|
+
data.tar.gz: b6ac96ff05fb4e52a5705b55de3fa505054860b154cd6622c4badc232c6284bc5e80d57ffc94b13a7eae1384557acd5b697b630a0ed21be1a8e85d99610b3d04
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,94 @@ and commands may change between minor versions. How releases are made:
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.63.0] - 2026-10-13
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- The claude-peer bundle (in the dev profile): pair a chi session with a Claude Code session you work with, and
|
|
16
|
+
the `claude_send` tool sends Claude a part of the work (a plan step, a diff, a finding) to validate, as context or
|
|
17
|
+
with a question; Claude's answer comes back as the `claude-review` context. `/claude validate|context <text>` and
|
|
18
|
+
`/claude last` send without the model, `/claude` shows whether a Claude is paired, and `/claude install-skill`
|
|
19
|
+
installs Claude's `chi-peer` skill, which pairs ("pair with chi <id>"). See docs/plugins.md, "The claude-peer
|
|
20
|
+
bundle".
|
|
21
|
+
- Plugins: `ctx.context.list` gives each source's last `summary:` too. See docs/plugins.md, "Attached context".
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Attached context: a source added with `chi context add NAME --push` now wakes an idle session when its first
|
|
26
|
+
push asks to (`"wake": true`); before, only later pushes could.
|
|
27
|
+
- Plugins: `ctx.context.list` returns `[]` for a new session whose file isn't saved yet (a plugin command before
|
|
28
|
+
the first turn) instead of raising "Session not found".
|
|
29
|
+
- An after_turn hook's file refs on the answer (`event[:refs]`) must be under the session's folder, as a plugin
|
|
30
|
+
tool row's are: a file elsewhere is refused (and logged), and a stored one is dropped when the answer is shown.
|
|
31
|
+
- loop-guard (0.3.8): the card for a turn it stopped prints under the blocked call's row in the terminal, not
|
|
32
|
+
before it.
|
|
33
|
+
- Attached TUI: joining a session whose last turn was images alone (sent from the web) names each image once, not
|
|
34
|
+
twice.
|
|
35
|
+
- Attached TUI: text you had typed when the step-limit question opened comes back at the prompt once you answer
|
|
36
|
+
it, instead of being lost.
|
|
37
|
+
- `chi -p … --non-interactive` says so on stderr and exits 1 when the iteration limit cuts the turn short, instead
|
|
38
|
+
of exiting 0 with the partial text as if it were the answer.
|
|
39
|
+
- `chi --no-shared --resume` drops a question the session's last worker saved and died with, as an attached resume
|
|
40
|
+
does, instead of keeping it in the session file.
|
|
41
|
+
|
|
42
|
+
## [0.62.0] - 2026-10-13
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- Plugins: `chi.tool(…, refs: ->(args) { [...] })` gives a tool call's web row its refs (a ticket, a PR, a file
|
|
47
|
+
under the session's folder) with their URL actions: the row's title opens the first, its `▾` menu offers the
|
|
48
|
+
rest, on a phone too. Saved with the result, so a reload shows them. See docs/plugins.md, "Refs on a tool's
|
|
49
|
+
row".
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Web: the stage view no longer jumps: it keeps its height while a turn runs, its chip stays put when the answer
|
|
54
|
+
arrives, and the finished turn slides away instead of collapsing. The stage floats above the composer (its rising at
|
|
55
|
+
a turn's start moves nothing, and the history behind it glides instead of jumping); content changes inside it (the
|
|
56
|
+
first words of a reply, an answered card, a short answer), so a card you answer stays where it is; it grows with a
|
|
57
|
+
short ease when a card or the answer needs room; its chip is its footer (the steps open right above it); and when
|
|
58
|
+
the turn moves into the history the stage slides away under the composer, then the turn appears there.
|
|
59
|
+
- Web: on a phone the top bar no longer gains a row mid-turn when the hidden strip's pill grows ("· 1 waiting"), which
|
|
60
|
+
pushed the whole session down; the pill drops its session count while it says live or waiting.
|
|
61
|
+
- Web: while a question or approval waits in the stage view, the stage shows the whole text of the reply that asked
|
|
62
|
+
it, not only its last sentence.
|
|
63
|
+
- Web: the model's question or its own approval, once answered, keeps the reply that asked it (a delegate's relayed
|
|
64
|
+
approval, a hook's question and the step limit don't): two muted lines under its `question → answer` line, the
|
|
65
|
+
whole text when the card is open, live and after a reload.
|
|
66
|
+
- Web: a finished turn's steps block shows its outline when its steps said something: open, one line per step that
|
|
67
|
+
wrote text (a mid-turn note reads without a click), and each run of tool-only steps folded into one `· N steps`
|
|
68
|
+
line that shows them. Live (both views) and after a reload; a turn whose steps said nothing collapses as before.
|
|
69
|
+
- Web: question and approval cards answer from the keyboard. Enter in the response box or on an option submits
|
|
70
|
+
(never Deny or Dismiss), and a new card takes the focus when the message box is empty.
|
|
71
|
+
- github-pr 0.5.0: a `path:line` it links in an answer is also a file ref, so the web's ref menu offers the file in
|
|
72
|
+
this checkout (editor, show in turn, copy) and a "PR diff" (or "File at head") action. Needs chi 0.61.0; run
|
|
73
|
+
`chi update`.
|
|
74
|
+
- source-links 0.5.0: each ref it links in an answer gets an "Open in <source>" action in the web's ref menu; a
|
|
75
|
+
source's new `kind:` key names its refs' kind (default `issue`). Needs chi 0.61.0; run `chi update`.
|
|
76
|
+
- Chat hosts (`api: openai`) keep the running turn's reasoning across a mid-turn steer under `reasoning_history:
|
|
77
|
+
turn`, as native hosts do: a person's line, a plugin's nudge (check-in, agents-md) or a step-limit Continue's text no
|
|
78
|
+
longer drops the reasoning of the replies before it, so the request after it extends the one before and the
|
|
79
|
+
server's prompt cache holds. A `!cmd` run while the step-limit question stands still starts past itself. On a stock
|
|
80
|
+
Qwen template (Splash) the benefit needs `chat_template_kwargs.preserve_thinking: true`; see
|
|
81
|
+
[docs/configuration.md](docs/configuration.md#reasoning-history).
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
|
|
85
|
+
- A turn run in the REPL (`--no-shared`) keeps the answer's display and refs (source-links' and github-pr's links,
|
|
86
|
+
a hook's `present`), so the web shows them when it opens the session; before, the save dropped them.
|
|
87
|
+
- A command a signal to chi stopped (a worker's TERM, HUP or INT mid-`execute`) says "stopped by a signal to chi",
|
|
88
|
+
not "stopped by the user"; one it kept from starting says "not run, a signal to chi stopped the turn".
|
|
89
|
+
slow-commands 0.2.1 doesn't count either as slow.
|
|
90
|
+
- A turn whose worker was killed (SIGKILL, a crash) keeps its tokens, speed and timings up to its last checkpoint:
|
|
91
|
+
the session's stats count it as a canceled turn (`worker_stopped`); before, they lost it.
|
|
92
|
+
- Web: hovering a ref with a ▾ at the very end of a line no longer pushes it onto the next line.
|
|
93
|
+
- Web: a failed `+ URL` attach keeps the "why" you typed (it was emptied), and a context chip with the keyboard
|
|
94
|
+
focus keeps it when the chips refresh.
|
|
95
|
+
|
|
96
|
+
Update with `chi update`: the system bundle 0.62.0, github-pr 0.5.0, source-links 0.5.0 and slow-commands 0.2.1.
|
|
97
|
+
Then restart `chi web`.
|
|
98
|
+
|
|
11
99
|
## [0.61.0] - 2026-10-12
|
|
12
100
|
|
|
13
101
|
### Added
|
|
@@ -2662,7 +2750,9 @@ and long-lived sessions.
|
|
|
2662
2750
|
- A macOS desktop helper (`chi desktop install`): a "Send to chi" Service and a
|
|
2663
2751
|
hotkey panel that send selected text or the clipboard to your sessions.
|
|
2664
2752
|
|
|
2665
|
-
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.
|
|
2753
|
+
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.63.0...HEAD
|
|
2754
|
+
[0.63.0]: https://github.com/dm1try/samagotchi/compare/v0.62.0...v0.63.0
|
|
2755
|
+
[0.62.0]: https://github.com/dm1try/samagotchi/compare/v0.61.0...v0.62.0
|
|
2666
2756
|
[0.61.0]: https://github.com/dm1try/samagotchi/compare/v0.60.0...v0.61.0
|
|
2667
2757
|
[0.60.0]: https://github.com/dm1try/samagotchi/compare/v0.59.0...v0.60.0
|
|
2668
2758
|
[0.59.0]: https://github.com/dm1try/samagotchi/compare/v0.58.0...v0.59.0
|
data/README.md
CHANGED
|
@@ -150,7 +150,10 @@ task to a child session that runs in parallel and reports back only its final
|
|
|
150
150
|
reply (a normal session: `chi --attach <id>` steers it). With the `coordinator`
|
|
151
151
|
bundle (in `dev`), `/coordinate <goal>` has chi split the work into tasks, each
|
|
152
152
|
in a child session in its own git worktree, check each report and ask you
|
|
153
|
-
before each merge; `/children` shows the children and their state.
|
|
153
|
+
before each merge; `/children` shows the children and their state. With the
|
|
154
|
+
`claude-peer` bundle (in `dev`), chi sends a part of its work to a Claude Code
|
|
155
|
+
session you pair it with, to validate or as context, and Claude answers back
|
|
156
|
+
into chi (`/claude`).
|
|
154
157
|
|
|
155
158
|
`chi send` is the other half: the text goes in as your message, the same as
|
|
156
159
|
typing it in the attached terminal or the web composer, and a turn runs. Piped
|
data/bin/chi
CHANGED
|
@@ -386,8 +386,9 @@ begin
|
|
|
386
386
|
scratch: scratch
|
|
387
387
|
).run
|
|
388
388
|
# `chi -p X </dev/null`: the turn failed (nothing was sent again); -p
|
|
389
|
-
# --non-interactive: the turn ended with no answer
|
|
390
|
-
|
|
389
|
+
# --non-interactive: the turn ended with no answer or at the iteration
|
|
390
|
+
# limit, or Ctrl-C cancelled it.
|
|
391
|
+
exit 1 if %i[turn_failed empty_answer iteration_limit].include?(ended)
|
|
391
392
|
exit Samagotchi::CLI::Exit::INTERRUPTED if ended == :interrupted
|
|
392
393
|
rescue Samagotchi::TerminalUI::SessionBusy, Samagotchi::TerminalUI::SessionNotFound, Samagotchi::ModelProfile::MissingModel => e
|
|
393
394
|
warn "Error: #{e.message}"
|
data/docs/architecture.md
CHANGED
|
@@ -326,6 +326,9 @@ The page's frequent reads of `GET /api/sessions/:id` stay light too:
|
|
|
326
326
|
turn's answer). A plain `?tail=1` (a tab opened before this) gets the whole timing.
|
|
327
327
|
The page binds an answer's `display_refs` to its bubble (`answer_refs.js`: on a reload's render and on this
|
|
328
328
|
read's re-render) and pairs them with the bubble's links and text before the `path:line` scan.
|
|
329
|
+
A plugin tool's row refs (`refs`, `RowRefs`) ride its tool events and, on a reload, its part (saved as
|
|
330
|
+
`tool_refs`); `turn_view.js` binds them to the row's title (`refs.js bindRowRefs`: the first on the title,
|
|
331
|
+
the others in its menu).
|
|
329
332
|
- `?timing=1`: the whole timing (`analytics.json` merged with the worker's `/state`) and
|
|
330
333
|
`turn_count`, when the page's merge came up short.
|
|
331
334
|
- `?cards=1`: the cards, from `/tail`; the session file is only stat'ed for the 404.
|
data/docs/cli.md
CHANGED
|
@@ -250,7 +250,10 @@ Notes:
|
|
|
250
250
|
retry lines and hooks' notices as they come, the after_turn hooks' ones
|
|
251
251
|
(source-links' `sources:`) after the answer; and the error of a failed turn,
|
|
252
252
|
then `chi: the session is kept with your prompt; continue it with: chi
|
|
253
|
-
--resume ID` (exit 1).
|
|
253
|
+
--resume ID` (exit 1). A turn the iteration limit (`turn.max_iterations`)
|
|
254
|
+
cut short prints what the model wrote so far, then `chi: the iteration limit
|
|
255
|
+
(N) was reached before the turn finished; continue it with: chi --resume ID`
|
|
256
|
+
on stderr (exit 1). Ctrl-C saves the session with the prompt and a
|
|
254
257
|
cancel note and exits 130.
|
|
255
258
|
Nobody can answer there: an approval is denied, and a question the model
|
|
256
259
|
asks (`ask_user_question`) is dismissed at once (one line on stderr), never
|
|
@@ -689,14 +692,23 @@ the step's reasoning), the running tool with what it does, and the last
|
|
|
689
692
|
three calls. A plugin's or hook's notice and a plugin's nudge ("check-in
|
|
690
693
|
nudged the model") show ahead of those calls for about 4 s, as their rows
|
|
691
694
|
wait in the closed block. A card that needs you (a question, an approval, check-in)
|
|
692
|
-
sits in the stage too.
|
|
693
|
-
|
|
695
|
+
sits in the stage too. While a question or approval waits, the stage shows
|
|
696
|
+
the whole text of the reply that asked it (in place of its newest
|
|
697
|
+
sentence) above the card, until you answer. Once answered, the model's
|
|
698
|
+
question or its own approval keeps that reply (a delegate's relayed
|
|
699
|
+
approval, a hook's question and the step limit don't): two muted lines
|
|
700
|
+
under its `question → answer` line, the whole text when you open the card,
|
|
701
|
+
in both views and after a reload. The chip at the stage's bottom edge, `N steps · M tool
|
|
702
|
+
calls` with one tick per call, opens the turn view's block right above it (newest step first
|
|
694
703
|
while it runs; a tick opens its step). `▾` folds the stage to its status
|
|
695
|
-
row, remembered in this browser.
|
|
704
|
+
row, remembered in this browser. The stage keeps its height while a turn
|
|
705
|
+
runs: it grows, with a short ease, when a card or the answer needs room and gives the room back
|
|
706
|
+
only when the turn moves into the history. When the turn ends the answer shows in
|
|
696
707
|
the stage, and the whole turn moves up into the history once you are not
|
|
697
708
|
using the stage (the pointer over it, a touch or scroll in the last 4 s,
|
|
698
|
-
keyboard focus or a selection keep it) for 1.5 s
|
|
699
|
-
|
|
709
|
+
keyboard focus or a selection keep it) for 1.5 s: the stage slides away
|
|
710
|
+
under the composer, then the turn appears in the history. Sending the next
|
|
711
|
+
message moves it at once. The history is never scrolled while a turn runs, and only
|
|
700
712
|
follows the hand-off if you were at its end. The `/` command list opens
|
|
701
713
|
over the stage's lower edge.
|
|
702
714
|
|
|
@@ -714,9 +726,14 @@ again). When a step ends its thinking closes to a plain `thinking` line
|
|
|
714
726
|
(unless you opened it); a step that only thought shows that line alone. The
|
|
715
727
|
live narration is a box of about three lines that fills sentence by
|
|
716
728
|
sentence (a sentence shows once it is complete) and scrolls to the newest
|
|
717
|
-
when full. When the turn ends the block
|
|
718
|
-
|
|
719
|
-
|
|
729
|
+
when full. When the turn ends the block shows its outline when any of its steps said
|
|
730
|
+
something: it stays open on one line per step that wrote text (that text's
|
|
731
|
+
first line, so a mid-turn note reads without a click), and each run of steps
|
|
732
|
+
that only called tools or thought sits behind one `· N steps` line that
|
|
733
|
+
shows them; old turns open the same way after a reload. A turn whose steps
|
|
734
|
+
said nothing collapses the block to its summary (`3 steps
|
|
735
|
+
· 8 tool calls · execute ×7 · read ×1`). Either way the answer expands from
|
|
736
|
+
the box into a normal bubble under it (Markdown, annotate). A plain answer
|
|
720
737
|
without tools ends exactly as it does today. Rows the code collapses stay
|
|
721
738
|
as you toggled them. A reloaded session shows the same block
|
|
722
739
|
from the saved messages (each step's thinking, narration, tool parameters
|
data/docs/configuration.md
CHANGED
|
@@ -521,9 +521,10 @@ What each backend gets:
|
|
|
521
521
|
|
|
522
522
|
On chat hosts: llama.cpp honours both off switches but ignores the effort (when its `/props` says
|
|
523
523
|
`chat_template_caps.supports_reasoning_effort: false`, chi says so once per session and host, from the `/props`
|
|
524
|
-
answer the turn already fetched for the window); Splash
|
|
525
|
-
|
|
526
|
-
|
|
524
|
+
answer the turn already fetched for the window); Splash honours both off switches and passes the effort to the
|
|
525
|
+
model's template, which decides: Qwen3.6's ignores it (`low`, `medium` and `high` think the same), and the server's
|
|
526
|
+
`--default-reasoning-effort` decides what `default` means there; OpenRouter translates `reasoning_effort` per model
|
|
527
|
+
(some can't turn thinking off: Qwen3-30B-A3B thinks anyway, gpt-oss refuses).
|
|
527
528
|
|
|
528
529
|
When the model thinks although the level is `off`, chi says so once per session and host
|
|
529
530
|
(`thinking> warning: off wasn't honoured by … (N chars of thinking)`) and logs `thinking_not_honoured` each time.
|
|
@@ -558,26 +559,39 @@ hosts:
|
|
|
558
559
|
url: https://api.deepseek.com/v1
|
|
559
560
|
api: openai
|
|
560
561
|
api_key_env: DEEPSEEK_API_KEY
|
|
561
|
-
reasoning_history: all # its API wants every earlier reply's reasoning
|
|
562
|
+
reasoning_history: all # with tools its API wants every earlier reply's reasoning: under turn, turn 2 fails
|
|
562
563
|
models:
|
|
563
564
|
some-model:
|
|
564
565
|
reasoning_history: drop
|
|
565
566
|
```
|
|
566
567
|
|
|
567
|
-
- `turn` (the default) sends the running turn's reasoning: each reply since the
|
|
568
|
-
|
|
569
|
-
(
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
568
|
+
- `turn` (the default) sends the running turn's reasoning: each reply since the turn's start carries its reasoning
|
|
569
|
+
as `reasoning_content` (OpenRouter takes it for DeepSeek, Qwen and other text-reasoning models). A steer, a plugin's
|
|
570
|
+
nudge (check-in, agents-md) or a Continue's text merged into the turn doesn't reset it, as on a native host: the
|
|
571
|
+
request after it is the one before plus the steer, so the server's prompt cache holds. A turn that goes on by itself
|
|
572
|
+
(a reminder, a context wake, a delegate report's wake) sends nothing of the one before it, an interrupted reply's
|
|
573
|
+
partial thought included. A **step-limit Continue** is the same turn going on: it keeps the reasoning of the run it
|
|
574
|
+
continues (back to the first run of a chain of Continues), so its first request matches the last one before the
|
|
575
|
+
limit and the server's prompt cache stays warm; Continue's text keeps it too. A `!cmd` run while the step-limit
|
|
576
|
+
question stands is a user message added after the run: the reasoning before it goes, and that Continue reads the
|
|
577
|
+
conversation again once (a re-prefill on a local server). After a `/model` change while the question stands the
|
|
578
|
+
Continue starts afresh (no other model's reasoning is sent).
|
|
579
|
+
- **A stock Qwen template (Splash, vLLM, SGLang; llama.cpp with Qwen's own template)** renders an earlier reply's
|
|
580
|
+
reasoning only after the last user message: a steer hides the reasoning before it whatever chi sends, and the
|
|
581
|
+
prompt changes there. `sampling: {chat_template_kwargs: {preserve_thinking: true}}` on the host renders every
|
|
582
|
+
reasoning chi sends (a reply sent without any renders an empty think block; adding it restarts the prompt cache
|
|
583
|
+
once). What it costs by level, with it on: under `turn` a steer no longer re-reads the turn, but each new turn still
|
|
584
|
+
reads the conversation again from the previous turn's first reply (that turn's reasoning leaves the request); under
|
|
585
|
+
`all` every request extends the one before (append-only), at the cost of a prompt that keeps the reasoning of every
|
|
586
|
+
turn. Without it (the template's default) both re-read from the reply before each user message. A strict server
|
|
587
|
+
that rejects unknown fields ("Unrecognized request argument supplied: chat_template_kwargs": OpenAI proper, some
|
|
588
|
+
gateways) fails every request with it, so set it only on a host you know takes it.
|
|
589
|
+
- A **direct DeepSeek API** host (`api.deepseek.com`) with tools wants the reasoning of every earlier reply, earlier
|
|
590
|
+
turns included, and answers HTTP 400 without it: under `turn` every turn after one that thought fails. Set
|
|
591
|
+
`reasoning_history: all` there (the example above). DeepSeek through OpenRouter takes `turn`.
|
|
578
592
|
- `drop` sends none (what chi did before this setting).
|
|
579
593
|
- `all` sends every reply's reasoning, earlier turns too. It sends only the field: a local template that leaves out
|
|
580
|
-
earlier turns' reasoning (Qwen's) needs `
|
|
594
|
+
earlier turns' reasoning (Qwen's) needs `preserve_thinking` as well (above).
|
|
581
595
|
- Order, first set wins: the session's own level, `SAMAGOTCHI_REASONING_HISTORY` (the whole process; for A/B runs),
|
|
582
596
|
the `models:` entry (found the way `profile:` is), the `hosts:` entry, then `turn`. Anything else than a level warns
|
|
583
597
|
once and counts as unset. A host's level reaches a worker when it starts, as its `sampling:` does.
|
|
@@ -597,9 +611,8 @@ models:
|
|
|
597
611
|
| to or from `all`, once an earlier reply has thinking | every earlier reply gains or loses its reasoning: a server that renders it (hosted APIs, llama.cpp's default template) reads the conversation again from the first earlier thought |
|
|
598
612
|
| nothing thought yet, the same level, or a native host | none |
|
|
599
613
|
|
|
600
|
-
- The native loop (`/completion`) ignores it: it always keeps the running turn's reasoning, a mid-turn steer included
|
|
601
|
-
|
|
602
|
-
a mid-turn steer's earlier ones included.
|
|
614
|
+
- The native loop (`/completion`) ignores it: it always keeps the running turn's reasoning, a mid-turn steer included,
|
|
615
|
+
and a step-limit Continue keeps the thoughts of the run it continues, a mid-turn steer's earlier ones included.
|
|
603
616
|
- When a host answers a request that sent reasoning back with an HTTP 400 about reasoning, chi asks again without it,
|
|
604
617
|
sends none to that model from then on (until the worker restarts) and says so once. If the request without it is
|
|
605
618
|
refused too, the thinking fields get the same fallback ("Thinking") and the reasoning goes back on the next step.
|
|
@@ -1337,7 +1350,7 @@ column says so, a `--kebab-name` flag. The maps (`hosts:`, `models:`,
|
|
|
1337
1350
|
| `memory.index_warn_tokens` | `2500` | yes | The tokens one scope's memory index (project or system; sent with every prompt) may hold before a `memory_write`, `write` or `edit` that takes it over gets a note asking the model to tighten long index descriptions; `0`: no note. Estimated as characters / `context.chars_per_token`. `memory:` is its own section, not the `memories:` preload list. See [Memory](memory.md). |
|
|
1338
1351
|
| `context.status_thresholds` | `20,40,60,80` | yes | Percentages that put the estimate into a bucket; the rise into a guidance bucket (from the second up) leaves the model its own `[CONTEXT: …]` line, and the bucket decides the guidance. |
|
|
1339
1352
|
| `context.every_seconds` | `300` | | How often an attached context source's command runs when it has no `--every` (seconds, at least 30). See [Attached context](context.md). |
|
|
1340
|
-
| `context.wake` | `true` | yes | A source whose update says `wake: true` may start a turn in a live, idle session (one per source per 10 minutes, within `session.max_wakes`); `false`: updates wait as notes for the next turn. See [Waking](context.md#waking). |
|
|
1353
|
+
| `context.wake` | `true` | yes | A source whose update says `wake: true` may start a turn in a live, idle session (one per source per 10 minutes, within `session.max_wakes`); so may a session's pushed source's first push. `false`: updates wait as notes for the next turn. See [Waking](context.md#waking). |
|
|
1341
1354
|
| `thinking.turn_preamble` | `true` | yes | Ask a `qwen36` model to open its thinking with a short `TURN:` line (the step label). |
|
|
1342
1355
|
| `reasoning_history` | `turn` | | Which of its reasoning a chat host's model gets back: `drop`, `turn`, `all`; environment only (`SAMAGOTCHI_REASONING_HISTORY`), below a session's own level (`/reasoning-history`), above the `models:`/`hosts:` entries. See "Reasoning history". |
|
|
1343
1356
|
| `thinking.level` | `default` | `--thinking` | `off`, `low`, `medium`, `high` or `default` for every model; the flag and env outrank the `models:`/`hosts:` entries, the file's value doesn't; a session's own level outranks them all, and `--thinking` sets it on a session run (on `chi web` it sets this). See "Thinking". |
|
data/docs/context.md
CHANGED
|
@@ -123,6 +123,11 @@ chi context add clip --push --project
|
|
|
123
123
|
pbpaste | chi context push clip --project
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
A Claude Code session can be a pushed source too: the
|
|
127
|
+
[claude-peer bundle](plugins.md#the-claude-peer-bundle)'s `pair` script attaches
|
|
128
|
+
`claude-inbox` (Claude's inbox socket as the hint) and `claude-review`, where
|
|
129
|
+
Claude pushes its answers as JSON with `wake: true`.
|
|
130
|
+
|
|
126
131
|
### A stream: chat, a log, a feed
|
|
127
132
|
|
|
128
133
|
A source's text is a snapshot, not a log: each run replaces it. For
|
|
@@ -233,6 +238,10 @@ you're away from the terminal. All of these must hold:
|
|
|
233
238
|
- the source asked (`"wake": true`; a plain-text source never does), in
|
|
234
239
|
any change since the session last heard of it: a later change that doesn't
|
|
235
240
|
ask doesn't take the wake back;
|
|
241
|
+
- it's a change, not the source's first text, except for a session's pushed
|
|
242
|
+
source (`chi context add NAME --push`, attached empty): its first push can
|
|
243
|
+
wake too. A command or URL source's first fetch runs as you attach it, and a
|
|
244
|
+
project source's first text may predate the session, so neither wakes;
|
|
236
245
|
- `context.wake` is on (default `true`);
|
|
237
246
|
- the session's worker is up and idle: no turn running, nothing queued, no
|
|
238
247
|
question or continue offer waiting, not just started;
|
|
@@ -242,15 +251,16 @@ you're away from the terminal. All of these must hold:
|
|
|
242
251
|
- the source hasn't woken the session in the last 10 minutes.
|
|
243
252
|
|
|
244
253
|
Otherwise the change arrives as a note, as above. The turn starts with the
|
|
245
|
-
update note, whose last
|
|
254
|
+
update note, or, for a session's pushed source, its attached note, whose last
|
|
255
|
+
line becomes:
|
|
246
256
|
|
|
247
257
|
> chi started this turn because the source changed; your user didn't write anything. Tell your user in a sentence or two what changed and what it may mean for their work. Don't run commands, change files or reply on the source for it: wait for your user to ask.
|
|
248
258
|
|
|
249
259
|
Every UI labels the turn `context <name> changed`, and the web's
|
|
250
260
|
notifications count it as a finished turn however short.
|
|
251
261
|
|
|
252
|
-
A wake turn that fails goes back to before it and keeps
|
|
253
|
-
plain
|
|
262
|
+
A wake turn that fails goes back to before it and keeps its note as a
|
|
263
|
+
plain one; the model reads `[SYSTEM: the previous turn failed before any
|
|
254
264
|
answer: … The wake turn for the change in attached context <name> was not
|
|
255
265
|
answered; chi starts no other wake turn until the user writes.]`.
|
|
256
266
|
|
|
@@ -346,6 +356,14 @@ show the answer as it is.
|
|
|
346
356
|
at the PR's head commit (a removed one: at its base), which has every
|
|
347
357
|
line.
|
|
348
358
|
- Code blocks, markdown links and URLs are left alone.
|
|
359
|
+
- **The ref menu**: each linked reference is also a
|
|
360
|
+
[file ref](hooks.md#refs-on-the-answer-display-only) on the answer: the
|
|
361
|
+
file in this checkout (the repository's root + the PR's path), so its
|
|
362
|
+
menu has the editor, show-in-turn and copy targets, plus **PR diff** (or
|
|
363
|
+
**File at head**, **File at base** for a removed file), the link's URL.
|
|
364
|
+
Only for a PR of this checkout's repository (one of its git remotes
|
|
365
|
+
names it on github.com): another project's PR keeps its links only.
|
|
366
|
+
Bundle 0.5.0, chi 0.61.0.
|
|
349
367
|
- The PR's files are read with `gh api` in the background when a turn
|
|
350
368
|
starts (and when a PR is attached while it runs), at most once a minute,
|
|
351
369
|
and read again only when the PR's head moved; the answer is linked from
|
data/docs/guardrails.md
CHANGED
|
@@ -35,7 +35,8 @@ Approve tool call?
|
|
|
35
35
|
|
|
36
36
|
In a terminal, answer with a number, the exact label, `y` (Allow once) or `n`
|
|
37
37
|
(Deny); add `; reason` to tell the model why (`n; open a PR instead`). An empty
|
|
38
|
-
answer, Ctrl-C, the web's Deny button or a cancelled turn deny it
|
|
38
|
+
answer, Ctrl-C, the web's Deny button or a cancelled turn deny it (on the web card, Enter in the reason box or
|
|
39
|
+
on an option submits, never denies). The prompt stays open during turns: when the question comes up it turns
|
|
39
40
|
into a yellow `? `, with the call and the options listed under it; only a line
|
|
40
41
|
submitted there answers it (never one typed before), and what you had typed comes back
|
|
41
42
|
once it closes. On a short terminal the list shrinks (the hint row, then the `in`/`why`
|
data/docs/hooks.md
CHANGED
|
@@ -301,9 +301,12 @@ end
|
|
|
301
301
|
keywords only (String or Symbol keys inside `target` and `actions`).
|
|
302
302
|
- `match`: the text in the answer the ref stands for (at most 500 characters).
|
|
303
303
|
- `kind`: a short lowercase word. `"file"` takes `target: {path:, line:, end_line:}`
|
|
304
|
-
(the lines optional);
|
|
305
|
-
folder,
|
|
306
|
-
`
|
|
304
|
+
(the lines optional); the path is absolute or relative to the session's
|
|
305
|
+
folder, and must be **under** it (its own spelling or its real path:
|
|
306
|
+
`/tmp/x` or `/private/tmp/x`), as a plugin tool row's file refs
|
|
307
|
+
([plugins.md](plugins.md)): a file elsewhere is refused. It is kept under
|
|
308
|
+
the folder's real path. Any other kind (`"issue"`, `"commit"`, …) takes
|
|
309
|
+
`target: {id:}`.
|
|
307
310
|
- `label`: what a UI shows for it (optional, at most 200 characters).
|
|
308
311
|
- `actions`: links a UI offers on top of the kind's own, each
|
|
309
312
|
`{id:, label:, url:}`; http(s) URLs only, without userinfo (`user:pass@`),
|
|
@@ -636,6 +639,7 @@ bundles:
|
|
|
636
639
|
pattern: '\bGH-(\d+)\b' # full form: a regex
|
|
637
640
|
url: 'https://github.com/org/repo/issues/{match}'
|
|
638
641
|
case_insensitive: false # optional, default false
|
|
642
|
+
kind: issue # optional: the refs' kind, default issue
|
|
639
643
|
max: 10 # optional: refs per line, default 10
|
|
640
644
|
note: false # optional: no sources line, default true
|
|
641
645
|
```
|
|
@@ -654,6 +658,13 @@ text ([`fallback_for: :display`](#what-a-hook-can-do-the-runtime)); it shows
|
|
|
654
658
|
when it names one the answer doesn't link (a ref only in code, two sources on
|
|
655
659
|
one ref) and whenever markdown is off. Bundle 0.4.0 needs chi 0.35.0 for that.
|
|
656
660
|
|
|
661
|
+
Each ref the answer links is also a [ref on the
|
|
662
|
+
answer](#refs-on-the-answer-display-only): kind `issue` (or the source's
|
|
663
|
+
`kind:`, a short lowercase word other than `file`), target `{id: "JIRA-123"}`,
|
|
664
|
+
label `JIRA JIRA-123`, and one action, **Open in JIRA** (the source's name),
|
|
665
|
+
its URL. The web's ref menu on the link shows it. A ref whose URL isn't
|
|
666
|
+
http(s) stays a markdown link only. Bundle 0.5.0 needs chi 0.61.0 for that.
|
|
667
|
+
|
|
657
668
|
The `prefix:` form compiles to `\b<prefix>-(\d+)\b` and the URL is
|
|
658
669
|
`base_url` + the full ref text (`JIRA-123`). The `pattern:` form takes a
|
|
659
670
|
regex and a `url:` template with placeholders (below). `case_insensitive:
|
data/docs/internals/engine.md
CHANGED
|
@@ -196,14 +196,15 @@ The differences from the native loop:
|
|
|
196
196
|
- A model turn's saved reasoning (`thinking:`) goes back as `reasoning_content` per the turn's
|
|
197
197
|
`TurnSettings#reasoning_history` (`ReasoningHistory.resolve`, the session's own level first:
|
|
198
198
|
`Session#reasoning_history`, `/reasoning-history`): `all` on every model message, `turn` past
|
|
199
|
-
`ChatLoop#reasoning_boundary`: the
|
|
200
|
-
the
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
`
|
|
206
|
-
|
|
199
|
+
`ChatLoop#reasoning_boundary`: the Run's `@reasoning_start`, fixed once per Run by `ReasoningHistory.run_start`
|
|
200
|
+
(the rule `KernelLoop#start_turn` uses too) from the Run's start (the conversation length at `#complete`), so a
|
|
201
|
+
continue turn (reminder, context wake, delegate report wake) replays nothing of the run before. Entries the Run
|
|
202
|
+
merges (a person's line, a plugin's steer, a Continue's text) don't move it, as natively (nothing re-sanitizes
|
|
203
|
+
within a run): the request after a steer extends the one before. A step-limit Continue's Run starts where the run
|
|
204
|
+
it resumes did: `#complete`'s `reasoning_since:` (the Engine's `resume_from`, checked against the messages' length
|
|
205
|
+
in `#resumed_run_start`), past a user entry added after that run's last reply (a `!cmd`'s output). Without
|
|
206
|
+
`since:` (`#reasoning_chars` from outside a Run) the boundary is the last query (a `role: "user"` or `turn_start`
|
|
207
|
+
entry). `Run#prompt_chars` counts it (`#reasoning_chars`).
|
|
207
208
|
- A 400 about reasoning (`BadRequest#reasoning_refused?`) for a request that sent reasoning back asks the step again
|
|
208
209
|
without it; when that goes through, `#reasoning_history_refused!` marks the model (worker lifetime) and
|
|
209
210
|
`:reasoning_history_refused` goes out. When it is refused too, the thinking-fields fallback (`#thinking_refused!`,
|
|
@@ -240,13 +241,22 @@ One iteration with tool calls:
|
|
|
240
241
|
- Runs the gate first, so `:tool_call_started` shows the call that will run (a before_tool_call hook may
|
|
241
242
|
replace it; known-names corrects a misspelled name this way, and the model gets one line saying what ran).
|
|
242
243
|
- Emits `:tool_call_started` {iteration, call_count, call_index, tool, call, params, label (plugin tools),
|
|
243
|
-
title, called_as, view, ref}. The row fields (title, called_as, view, ref) come from `ToolRowFields.for`, which the
|
|
244
|
+
title, called_as, view, ref, refs}. The row fields (title, called_as, view, ref) come from `ToolRowFields.for`, which the
|
|
244
245
|
reload (`Web::MessageParts#tool_part`) calls too. `ToolRowFields::ACTIVITY_KEYS` (title, called_as) travel
|
|
245
|
-
inside `activity` on the completed event; `EVENT_KEYS` (view, ref) go top-level on both events.
|
|
246
|
+
inside `activity` on the completed event; `EVENT_KEYS` (view, ref, refs) go top-level on both events.
|
|
246
247
|
`Bridge::TurnAccumulator` (snapshot and replay) and the web (`activity.js` `ACTIVITY_FIELDS` /
|
|
247
248
|
`EVENT_FIELDS`) copy them by these lists, so a new row field is added there. `ref` is `FileRef.for` (a
|
|
248
249
|
read/write/edit's file against the cwd, `{kind: "file", path, line?, end_line?}`); the web opens it in the editor
|
|
249
250
|
that `Web::Editor` (web.editor) names, for a local viewer only (`App#viewer_capabilities`).
|
|
251
|
+
`refs` is a plugin tool's row refs: its registry entry's `refs` (chi.tool's `refs:` lambda, `Api.per_call`), run
|
|
252
|
+
once per call by `RowRefs.for` (never raises: a raise or a non-list gives none, `tool_refs_failed`; each entry a
|
|
253
|
+
`Ref`, a bad one dropped, `tool_refs_rejected`; a relative file resolved against the session's folder
|
|
254
|
+
(`KernelLoop#session_cwd`, else the process's), one outside it (its spelling or its real path) dropped, a kept one
|
|
255
|
+
stored under the real path; at most `RowRefs::MAX_REFS` and `MAX_BYTES`). `ToolRowFields.for` can't build it (no plugins on a reload), so the run carries it
|
|
256
|
+
as `refs:`, saved with the result as `tool_refs` (`ToolResponse::SAVED_KEYS`, never sent), and
|
|
257
|
+
`MessageParts#tool_part` reads it back through `RowRefs.for_display` (checked again). The page binds them to the
|
|
258
|
+
row's title (`refs.js bindRowRefs`, from `turn_view.js` live and on a reload): the first ref on it, the rest in its
|
|
259
|
+
menu.
|
|
250
260
|
- Settles an ask verdict after `:tool_call_started`, so a UI shows the tool line and then the approval.
|
|
251
261
|
- Dispatches through `KernelLoop#dispatch_tool_call`, or writes the denial text. Unknown tools are answered in
|
|
252
262
|
`KernelLoop#dispatch` ("Error: no such tool ...", never repeating the wrong name).
|
|
@@ -319,7 +329,10 @@ end
|
|
|
319
329
|
boundary) copies it, with the lines that boundary merges, into `Session#turn_checkpoint` (`TurnCheckpoint`):
|
|
320
330
|
every save while the turn runs writes that copy with an `interrupted_turn` mark instead of the session's
|
|
321
331
|
messages, written at the first boundary and then at most every 10 s, so a killed worker loses at most that much
|
|
322
|
-
of its turn. `session.messages` itself is untouched until the turn ends.
|
|
332
|
+
of its turn. `session.messages` itself is untouched until the turn ends. When the checkpoint writes, the worker
|
|
333
|
+
also calls `Engine#checkpoint_metrics` (`SessionMetrics#persist(running_turn: true)`): `analytics.json` gets the
|
|
334
|
+
running turn's record so far as a killed turn's (canceled, `worker_stopped`), which the next worker loads; the
|
|
335
|
+
turn's end writes over it.
|
|
323
336
|
|
|
324
337
|
### GenerationPhase
|
|
325
338
|
|
|
@@ -127,7 +127,12 @@ is prefilled once. The native and the chat loop use the same plan.
|
|
|
127
127
|
a per-session value in the stable part. A guard spec checks that model, location and session are the last
|
|
128
128
|
sections (`spec/system_prompt_model_spec.rb`).
|
|
129
129
|
2. **History is append-only.** Never rewrite an earlier message. Add a note at the tail instead. If a model's
|
|
130
|
-
spec forces a rewrite (e.g. stripping previous-turn thinking), accept the re-prefill and note it.
|
|
130
|
+
spec forces a rewrite (e.g. stripping previous-turn thinking), accept the re-prefill and note it. Within a
|
|
131
|
+
turn both loops keep the turn's replies as sent across a mid-turn steer, a plugin's nudge and a Continue's text
|
|
132
|
+
(`ReasoningHistory.run_start` fixes where the run's reasoning starts), so the request after a steer is the one
|
|
133
|
+
before plus the steer; a new turn drops the previous turn's reasoning under `turn` (one re-prefill from its
|
|
134
|
+
first reply, on a server that renders it; a stock Qwen template without `preserve_thinking` re-renders from the
|
|
135
|
+
reply before every user message whatever chi sends). A worker's
|
|
131
136
|
mid-turn checkpoint (`TurnCheckpoint`) is append-only too (the history plus what the loop appended) and
|
|
132
137
|
never changes the request bytes.
|
|
133
138
|
3. **Deterministic order.** Tools, memory lists and anything else that's rendered from a hash or a set needs a
|
data/docs/memory.md
CHANGED
|
@@ -270,7 +270,7 @@ profiles, meta bundles that install a set of them:
|
|
|
270
270
|
| profile | bundles |
|
|
271
271
|
|---|---|
|
|
272
272
|
| `core` | loop-guard, check-in, guardrails, slow-commands, agents-md: the recommended safety set |
|
|
273
|
-
| `dev` | known-names, mcp, btw, skills, source-links, github-pr, coordinator |
|
|
273
|
+
| `dev` | known-names, mcp, btw, skills, source-links, github-pr, coordinator, claude-peer |
|
|
274
274
|
|
|
275
275
|
`chi bootstrap` installs `core` and, on a terminal, offers `dev`. An existing
|
|
276
276
|
install gets neither by itself: `chi bundle install core` (or `dev`).
|