mirror-mind 0.34.0 → 0.36.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.
- package/.pi/skills/mm-build/SKILL.md +1 -1
- package/.pi/skills/mm-explore/SKILL.md +1 -1
- package/.pi/skills/mm-help/SKILL.md +2 -2
- package/.pi/skills/mm-soul/SKILL.md +1 -1
- package/AGENTS.md +7 -6
- package/README.md +5 -6
- package/docs/releases/index.md +2 -0
- package/docs/releases/v0.35.0.md +199 -0
- package/docs/releases/v0.36.0.md +222 -0
- package/package.json +2 -4
- package/plugins/mirror-mind/.claude-plugin/plugin.json +1 -1
- package/plugins/mirror-mind/agy/pre-invocation.sh +92 -0
- package/plugins/mirror-mind/agy/session-start.sh +92 -0
- package/plugins/mirror-mind/agy/stop.sh +92 -0
- package/plugins/mirror-mind/hooks.json +26 -0
- package/plugins/mirror-mind/mcp_config.json +11 -0
- package/plugins/mirror-mind/plugin.json +14 -0
- package/plugins/mirror-mind/rules/AGENTS.md +189 -0
- package/plugins/mirror-mind/skills/mm-build/SKILL.md +1 -1
- package/ts/src/conversation/agyTranscript.ts +105 -0
- package/ts/src/conversation/commandTurn.ts +1 -1
- package/ts/src/conversation/deferredCloseTail.ts +2 -2
- package/ts/src/conversation/logger.ts +1 -1
- package/ts/src/conversation/runtimePolicy.ts +36 -4
- package/ts/src/docs/docsLint.ts +14 -1
- package/ts/src/extensions/bindings.ts +53 -2
- package/ts/src/extensions/catalogCommands.ts +82 -23
- package/ts/src/extensions/catalogWrites.ts +12 -0
- package/ts/src/extensions/contextRuntime.ts +36 -1
- package/ts/src/extensions/dispatch.ts +43 -10
- package/ts/src/extensions/extensionPlugin.ts +325 -0
- package/ts/src/extensions/manifest.ts +7 -1
- package/ts/src/extensions/settings.ts +147 -0
- package/ts/src/frontDoor/cli.ts +16 -1
- package/ts/src/frontDoor/extensionCatalogRoute.ts +8 -2
- package/ts/src/frontDoor/runtimeRoute.ts +11 -0
- package/ts/src/frontDoor/stdinSource.ts +2 -2
- package/ts/src/guards/claudePlugin.ts +91 -0
- package/ts/src/guards/packContents.ts +3 -2
- package/ts/src/guards/piSourcedSkills.ts +1 -1
- package/ts/src/guards/retiredSurfaces.ts +31 -0
- package/ts/src/hooks/agy.ts +229 -0
- package/ts/src/hooks/claude.ts +6 -0
- package/ts/src/hooks/main.ts +23 -16
- package/ts/src/hooks/payload.ts +8 -15
- package/ts/src/hooks/runtime.ts +11 -10
- package/ts/src/runtime/brokenPipe.ts +52 -0
- package/ts/src/runtime/diagnose.ts +122 -13
- package/ts/src/runtime/extensionPluginWiring.ts +222 -0
- package/ts/src/runtime/pluginWiring.ts +168 -29
- package/ts/src/runtime/status.ts +28 -1
- package/ts/src/runtime/update.ts +25 -11
- package/ts/src/runtime/wiring.ts +149 -35
- package/.gemini/hooks/log-assistant.sh +0 -85
- package/.gemini/hooks/log-user.sh +0 -85
- package/.gemini/hooks/session-end.sh +0 -85
- package/.gemini/hooks/session-start.sh +0 -85
- package/ts/src/hooks/gemini.ts +0 -128
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "mm-help"
|
|
3
|
-
description: Shows available Mirror Mind commands on Pi
|
|
3
|
+
description: Shows available Mirror Mind commands on Pi
|
|
4
4
|
user-invocable: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Help
|
|
8
8
|
|
|
9
|
-
Show the user the available commands
|
|
9
|
+
Show the user the available commands:
|
|
10
10
|
|
|
11
11
|
## Operating Modes
|
|
12
12
|
|
package/AGENTS.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Mirror Mind — Operating Instructions
|
|
2
2
|
|
|
3
3
|
<!-- This file ships in the mirror-mind package and is read by every runtime:
|
|
4
|
-
Pi and Codex read it from the project root natively, Claude Code
|
|
5
|
-
|
|
6
|
-
package's Pi session receives it from the extension
|
|
4
|
+
Pi and Codex read it from the project root natively, Claude Code through
|
|
5
|
+
the @AGENTS.md import in CLAUDE.md, Antigravity as the plugin's rules, and
|
|
6
|
+
an installed package's Pi session receives it from the extension
|
|
7
|
+
(CV22.DS10.US3, D13).
|
|
7
8
|
It holds nothing about this repository; that is CLAUDE.md's part. -->
|
|
8
9
|
|
|
9
10
|
---
|
|
@@ -17,9 +18,9 @@ Applies to all sessions, regardless of project.
|
|
|
17
18
|
The mirror operates in four modes, chosen automatically based on context:
|
|
18
19
|
Mirror, Builder, Explorer, and Soul.
|
|
19
20
|
|
|
20
|
-
Each skill below is named three ways: `/mm-<skill>` in Pi and
|
|
21
|
-
`$mm-<skill>` in Codex, `/mm:<skill>` in Claude Code. A **plugin** install
|
|
22
|
-
|
|
21
|
+
Each skill below is named three ways: `/mm-<skill>` in Pi and Grok Build,
|
|
22
|
+
`$mm-<skill>` in Codex, `/mm:<skill>` in Claude Code. A **plugin** install prefixes the plugin's
|
|
23
|
+
name — `/mirror-mind:mm:<skill>` in Claude Code's menu and in Antigravity,
|
|
23
24
|
`$mirror-mind:mm:<skill>` in Codex, `mirror-mind:mm-<skill>` as the skill's own
|
|
24
25
|
name — and the forms below refer to the same skill.
|
|
25
26
|
|
package/README.md
CHANGED
|
@@ -60,8 +60,8 @@ This is not a chatbot with memory. This is a mirror — and yours.
|
|
|
60
60
|
|
|
61
61
|
## How It Works
|
|
62
62
|
|
|
63
|
-
Local-first. SQLite.
|
|
64
|
-
|
|
63
|
+
Local-first. SQLite. Five supported runtimes: Pi, Claude Code, Codex,
|
|
64
|
+
Antigravity, Grok Build. One TypeScript core, run by Node.js. Jungian architecture: Self, Ego,
|
|
65
65
|
Personas, Shadow.
|
|
66
66
|
Context-activated modes — Mirror, Builder, Explorer, and Soul. The identity lives
|
|
67
67
|
in your machine, not a server.
|
|
@@ -79,9 +79,8 @@ in your machine, not a server.
|
|
|
79
79
|
- [OpenRouter](https://openrouter.ai) account with at least $5 in credits —
|
|
80
80
|
embeddings, memory extraction, and multi-LLM
|
|
81
81
|
- An AI runtime subscription:
|
|
82
|
-
[Codex Plus](https://openai.com/codex/) (recommended)
|
|
83
|
-
[Claude Code Pro](https://code.claude.com/docs)
|
|
84
|
-
[Gemini AI Pro](https://geminicli.com/)
|
|
82
|
+
[Codex Plus](https://openai.com/codex/) (recommended) or
|
|
83
|
+
[Claude Code Pro](https://code.claude.com/docs)
|
|
85
84
|
- [Pi](https://github.com/earendil-works/pi/tree/main/packages/coding-agent)
|
|
86
85
|
— recommended harness (multi-model, not locked to one provider)
|
|
87
86
|
|
|
@@ -111,7 +110,7 @@ this repository, turning a personal experiment into a reusable framework:
|
|
|
111
110
|
|
|
112
111
|
- **English** — full migration from Portuguese across code, CLI, schema, identity, and docs
|
|
113
112
|
- **Framework/user separation** — user identity and memory live privately under `~/.mirror/<user>/`, outside the repository
|
|
114
|
-
- **Multi-runtime** — from Claude Code only to
|
|
113
|
+
- **Multi-runtime** — from Claude Code only to Pi, Claude Code, Codex, Antigravity, and Grok Build
|
|
115
114
|
- **Multi-user** — independent mirrors for multiple users on the same machine
|
|
116
115
|
- **Multi-session** — concurrent sessions tracked safely in a database-backed session registry
|
|
117
116
|
- **Intelligence depth** — hybrid semantic and lexical search, honest reinforcement, two-pass extraction, memory consolidation, and shadow cultivation
|
package/docs/releases/index.md
CHANGED
|
@@ -12,6 +12,8 @@ Future release notes should use the structure defined in [Release Notes](../proc
|
|
|
12
12
|
|
|
13
13
|
## Releases
|
|
14
14
|
|
|
15
|
+
- [v0.36.0 — Five Runtimes, and a Home's Extensions on Every One](v0.36.0.md) — minor release closing CV21.DS10: Grok Build is the fifth runtime, at its honest L3 through the canonical plugin in two printed steps, measured live on grok 1.0.62. With it, CV21.DS5.US2: a home's installed extensions reach Claude Code, Codex, Antigravity, and Grok Build as one generated plugin per home, chosen by measurement on all four. Three Change Requests found by use: an extension's settings file (`extensions/<id>.env`, merged under the environment for the one spawned process), a quiet exit on a closed pipe, and a `bind` that refuses what it cannot bind. No migration.
|
|
16
|
+
- [v0.35.0 — Four Runtimes, One Successor](v0.35.0.md) — minor release closing CV21.DS8: the Gemini CLI integration no longer ships and Antigravity stands in its place, the gate met by DS7's live L4 on agy 1.4.2. Four runtimes — Pi, Claude Code, Codex, Antigravity — named everywhere; the cutoff recorded in full, with the four hook entries a Gemini CLI user deletes and v0.34.0 as the last release that carries the integration; a retired-surface guard keeps it removed. No migration.
|
|
15
17
|
- [v0.34.0 — Codex Through the Canonical Plugin](v0.34.0.md) — minor release closing CV21.DS4: Codex runs Mirror through the canonical plugin, installed in two commands from a marketplace the package ships, measured live at L4 on Codex 0.163.0. The v0.32.1 wrapper wiring no longer ships; `runtime diagnose` and `runtime update` say when Codex's cached plugin copy is behind and name the re-add that brings it level. No migration.
|
|
16
18
|
- [v0.33.4 — A Name Is a Key](v0.33.4.md) — patch release of three first-run corrections: two from a contributor's PR #43 and CR141, which its review opened. `init --help` created a home named `--help`, `init ../escaped` created one outside `.mirror-minds`, and `init "My User"` put a space into `MIRROR_USER`; a user name is now a kebab-case key like a journey slug or a persona id, refused otherwise with a name that would work and nothing created. `identity edit` on Windows opens Notepad when no editor is named. Existing homes untouched. No migration.
|
|
17
19
|
- [v0.33.3 — Mirror Finds Itself Under Any Path](v0.33.3.md) — patch release of one Change Request, CR140, carried by a contributor's PR #42: Mirror read its own install path from `URL.pathname`, so a checkout or package under a path with a space or a non-ASCII character read as `Install: unknown`, the welcome card showed no update, and `runtime update` refused. The path is now a filesystem path, a guard keeps the idiom out, and an `unknown` install names the path it looked up from. On Windows, npm's global layout is recognized and npm runs with no shell, verified on Windows in CI for the two files they touch; there is still no Windows product. Affected installs update once by hand. No migration.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
digest: >
|
|
3
|
+
v0.35.0 is a minor release closing CV21.DS8: the Gemini CLI integration no
|
|
4
|
+
longer ships, and Antigravity stands in its place. Mirror Mind supports four
|
|
5
|
+
runtimes — Pi, Claude Code, Codex, Antigravity — and every document says so.
|
|
6
|
+
The removal waited for its gate: DS7 measured Antigravity at L4 on agy 1.4.2,
|
|
7
|
+
all five bar items, so a Gemini CLI user who moves loses nothing and gains
|
|
8
|
+
MCP. The cutoff is recorded here in full — what no longer exists, why, what
|
|
9
|
+
to do instead, what still works, and what a user who does nothing will see —
|
|
10
|
+
with the four hook entries to delete named, and v0.34.0 named as the last
|
|
11
|
+
release that carries the integration. A retired-surface guard keeps the
|
|
12
|
+
removal removed. No migration: homes, memories, journeys, and the
|
|
13
|
+
conversations logged as gemini_cli are untouched.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# v0.35.0 — Four Runtimes, One Successor
|
|
17
|
+
|
|
18
|
+
**Date:** 2026-10-18
|
|
19
|
+
|
|
20
|
+
## Highlights
|
|
21
|
+
|
|
22
|
+
- **Gemini CLI is no longer a Mirror runtime; Antigravity is its successor**
|
|
23
|
+
([decision](../project/decisions.md#gemini-cli-is-retired-and-antigravity-is-its-successor)).
|
|
24
|
+
The four `.gemini/hooks` wrappers, the `gemini:*` hook family, the two
|
|
25
|
+
Gemini CLI steps `mirror init` printed, and the Gemini smoke no longer ship
|
|
26
|
+
(CV21.DS8.US1). The package's description and keywords, and every
|
|
27
|
+
runtime-facing document, name Pi, Claude Code, Codex, and Antigravity
|
|
28
|
+
(CV21.DS8.US2).
|
|
29
|
+
- **The gate was met first.** v0.33.0 gave notice that the integration would
|
|
30
|
+
be removed "only once Antigravity gives a Gemini CLI user what they have
|
|
31
|
+
now". CV21.DS7.US4 measured that on agy 1.4.2, live: all of Mirror's
|
|
32
|
+
skills, the Operating Instructions at session start, Mirror Mode context
|
|
33
|
+
injected once per user turn, every turn logged and the conversation closed,
|
|
34
|
+
setup in one step against Gemini CLI's two — and MCP reachable, which the
|
|
35
|
+
Gemini CLI wiring never had.
|
|
36
|
+
- **The cutoff is written where a user reads it before it happens to them**:
|
|
37
|
+
the section below, the Antigravity section of
|
|
38
|
+
[Getting Started](../getting-started.md#antigravity), and a
|
|
39
|
+
[troubleshooting entry](../process/troubleshooting.md#gemini-cli-runs-a-mirror-hook-that-no-longer-exists)
|
|
40
|
+
for the symptom a Gemini CLI user would meet.
|
|
41
|
+
- **A retired-surface guard keeps the removal removed.** `.gemini/` can never
|
|
42
|
+
ship again from this package: the row is enforced on every push and by the
|
|
43
|
+
release tripwire. That matters because `mirror init` once told users to
|
|
44
|
+
write absolute paths into that directory into their settings — a standing
|
|
45
|
+
instruction to execute whatever a later release might put there.
|
|
46
|
+
|
|
47
|
+
## Where We Started
|
|
48
|
+
|
|
49
|
+
v0.32.1 shipped Gemini CLI as one of four supported runtimes, at L4 parity,
|
|
50
|
+
wired by two documented steps. On 2026-09-25 the Navigator retired it —
|
|
51
|
+
Google had set a deprecation date for the Gemini Code Assist backend for
|
|
52
|
+
individuals, and Antigravity, which imports Claude-format plugins, was the
|
|
53
|
+
successor — but the call lived in one story's notes while the release kept
|
|
54
|
+
advertising the runtime. The decision was recorded on 2026-10-13, with a
|
|
55
|
+
condition: the integration goes only behind a documented cutoff, and only
|
|
56
|
+
once Antigravity meets the bar a Gemini CLI user already had. DS7 built the
|
|
57
|
+
agy-native layer and measured the bar. DS8 is the cutoff.
|
|
58
|
+
|
|
59
|
+
## What Changed
|
|
60
|
+
|
|
61
|
+
**The integration is gone from the package.** No `.gemini/hooks`, no `gemini`
|
|
62
|
+
entry in the wiring `mirror init` prints, no `gemini:*` hook names — an
|
|
63
|
+
unknown name is noted in `hooks.log` and the turn proceeds, as any unknown
|
|
64
|
+
name does. The Gemini smoke and the npm smoke's Gemini section retired with
|
|
65
|
+
it; the hook payload reader dropped the one field only Gemini CLI supplied.
|
|
66
|
+
|
|
67
|
+
**The docs say what ships.** Twenty files: README, Getting Started,
|
|
68
|
+
REFERENCE, the Operating Instructions and their plugin copy, the
|
|
69
|
+
runtime-interface spec, the welcome spec, the architecture, and the skills
|
|
70
|
+
that said "Pi and Gemini CLI". Where a runtime list, a wiring step, or a
|
|
71
|
+
parity table had Gemini CLI, it has Antigravity. Where a lesson says what
|
|
72
|
+
Gemini CLI taught — the payload-shape bug its smoke caught, the one-JSON-
|
|
73
|
+
object rule its hook entries kept — the lesson stays, in the past tense.
|
|
74
|
+
Getting Started's subscription table no longer carries a Gemini AI Pro row
|
|
75
|
+
and invents no Antigravity row: what Antigravity requires is Google's to
|
|
76
|
+
say, and Mirror needs only the `agy` command on your PATH.
|
|
77
|
+
|
|
78
|
+
**Antigravity's own documentation is unchanged** beyond taking Gemini CLI's
|
|
79
|
+
place: DS7 wrote it and measured it.
|
|
80
|
+
|
|
81
|
+
## The Cutoff: Gemini CLI
|
|
82
|
+
|
|
83
|
+
**What you keep.** Everything that is yours. Your `~/.mirror-minds/<user>`
|
|
84
|
+
home, your identity, your memories, your journeys, and every conversation
|
|
85
|
+
you logged — including the ones labelled `gemini_cli`, which stay readable
|
|
86
|
+
in `mm-conversations` and `mm-recall` and are never migrated or relabelled.
|
|
87
|
+
Only the runtime that reads them changes.
|
|
88
|
+
|
|
89
|
+
**Removed.** The four `.gemini/hooks` wrappers (`session-start.sh`,
|
|
90
|
+
`log-user.sh`, `log-assistant.sh`, `session-end.sh`) and the `gemini:*` hook
|
|
91
|
+
family behind them; the two Gemini CLI steps `mirror init` printed (the
|
|
92
|
+
skills link, the four hooks merged into `~/.gemini/settings.json`); the
|
|
93
|
+
Gemini smoke; the runtime from the package's description and keywords and
|
|
94
|
+
from every runtime-facing document.
|
|
95
|
+
|
|
96
|
+
**Why.** Google deprecated the Gemini Code Assist backend for individuals
|
|
97
|
+
(2026-06-18). Antigravity is its successor and imports Claude-format
|
|
98
|
+
plugins — the one plugin Mirror already ships. The removal waited for
|
|
99
|
+
DS7.US4's measurement on agy 1.4.2: all five items of the bar DS12.TS3 set
|
|
100
|
+
PASS, with per-turn injection — the cost the decision feared losing —
|
|
101
|
+
carried by agy's `PreInvocation` hook. The one difference that did
|
|
102
|
+
materialize: agy has no session-end signal, so a conversation closes when
|
|
103
|
+
your next session starts rather than at exit (as Codex's does); logging
|
|
104
|
+
parity holds, and memories extract after the close.
|
|
105
|
+
|
|
106
|
+
**What to do instead.** Install Antigravity, then the one step `mirror init`
|
|
107
|
+
prints when it finds `agy` on your PATH:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
agy plugin install "<pkg>/plugins/mirror-mind" # <pkg> = $(npm root -g)/mirror-mind
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Your home carries over unchanged — nothing to export, nothing to re-seed.
|
|
114
|
+
Same home, same memory, different door. The skills carry the plugin's name:
|
|
115
|
+
`/mirror-mind:mm:mirror`, `/mirror-mind:mm:journeys`, and so on.
|
|
116
|
+
|
|
117
|
+
**What still works.** Gemini *models*. Memory extraction runs on
|
|
118
|
+
`google/gemini-2.5-flash-lite` through OpenRouter, and `consult` reaches the
|
|
119
|
+
`gemini` family as before. Those are model choices, not the runtime.
|
|
120
|
+
|
|
121
|
+
**If you do nothing.** After the update, the four `mirror-*` hook commands in
|
|
122
|
+
your `~/.gemini/settings.json` point at files that no longer exist, while the
|
|
123
|
+
links in `~/.gemini/skills/` still resolve — `.pi/skills` keeps shipping. So
|
|
124
|
+
Gemini CLI keeps Mirror's skills and loses logging and Mirror Mode injection.
|
|
125
|
+
Said plainly: your Gemini CLI sessions stop being logged and Mirror Mode
|
|
126
|
+
stops being injected, and nothing on screen says so. Measured on Gemini CLI
|
|
127
|
+
0.61.0 in headless mode (`gemini -p`), 2026-10-18: a registered hook whose
|
|
128
|
+
command is missing is skipped silently; the session proceeds. The entries to
|
|
129
|
+
delete, in `~/.gemini/settings.json`: `mirror-session-start` (under
|
|
130
|
+
`SessionStart`), `mirror-log-user` (`BeforeAgent`), `mirror-log-assistant`
|
|
131
|
+
(`AfterAgent`), `mirror-session-end` (`SessionEnd`); and the `mm-*` links in
|
|
132
|
+
`~/.gemini/skills/`. Mirror never wrote those files and does not edit them.
|
|
133
|
+
Whether Antigravity also reads `~/.gemini/skills/` — which would show a
|
|
134
|
+
migrated user the stale links as duplicate skills — was not measured;
|
|
135
|
+
remove the links either way.
|
|
136
|
+
|
|
137
|
+
**To stay on Gemini CLI a while longer.** `npm install -g mirror-mind@0.34.0`
|
|
138
|
+
is the last release that carries the integration. The welcome card and
|
|
139
|
+
`runtime update` will keep offering the newer version every session; the pin
|
|
140
|
+
is a choice to make knowingly, not a quiet state.
|
|
141
|
+
|
|
142
|
+
## Upgrading
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npm install -g mirror-mind@latest # or: mirror runtime update
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**If you used Gemini CLI:** read the cutoff above; the steps are in Getting
|
|
149
|
+
Started's Antigravity section. **Every other runtime:** nothing to do. No
|
|
150
|
+
migration. Existing homes, sessions, and memories are untouched.
|
|
151
|
+
|
|
152
|
+
## Also In This Release
|
|
153
|
+
|
|
154
|
+
- **Typecheck is green on `main` again.** DS7.TS3 left one early return in
|
|
155
|
+
`hooks/agy.ts` without the field it had just added; `tsc --noEmit`, a CI
|
|
156
|
+
gate, refused since. Found by DS8.US1's validation, paid in its own commit.
|
|
157
|
+
- **The docs link check is green again.** The plugin's byte copy of the
|
|
158
|
+
Operating Instructions carries a root-relative link that cannot resolve
|
|
159
|
+
under `rules/`; the checker reported it on every `.md` push since DS7.US1.
|
|
160
|
+
The copy's links now resolve where the source lives — not skipped: a link
|
|
161
|
+
the source cannot resolve still fails through the copy.
|
|
162
|
+
- **The P1 redaction invariant outlives the runtime it was written against.**
|
|
163
|
+
"A failed hook never writes the prompt or the reply to `hooks.log`" was
|
|
164
|
+
tested through the Gemini CLI hooks; it now runs through the Claude-family
|
|
165
|
+
hooks every plugin runtime shares.
|
|
166
|
+
|
|
167
|
+
## Conscious Exclusions
|
|
168
|
+
|
|
169
|
+
- **No second cutoff document.** CV22 needed `pending-cutoffs.md` for eleven
|
|
170
|
+
cutoffs in one release; DS8 has one, and this note is its record.
|
|
171
|
+
- **Mirror does not edit `~/.gemini/settings.json` or `~/.gemini/skills/`.**
|
|
172
|
+
It never wrote them. The note and the guidance name what to remove.
|
|
173
|
+
- **The Claude plugin smoke's negative probe** still cannot run on a machine
|
|
174
|
+
with a globally installed `mirror-hook` (CR142, D-031): pre-existing,
|
|
175
|
+
local-only, carried.
|
|
176
|
+
- **DS5, DS10, DS11** — user extensions on every runtime, Grok through the
|
|
177
|
+
plugin, the contract and docs refresh — are CV21's remaining stories, not
|
|
178
|
+
this release's.
|
|
179
|
+
|
|
180
|
+
## What We Learned
|
|
181
|
+
|
|
182
|
+
A retirement that lives in a decision while the release advertises the
|
|
183
|
+
runtime has not happened; it happened here in three stories, in order:
|
|
184
|
+
remove, then make the tree say so, then tell the user — and the guard that
|
|
185
|
+
proves each step split by story, so nothing went red between them. The
|
|
186
|
+
sweep found what the inventory missed (a spec line, a history link), which
|
|
187
|
+
is what a guard is for. And the one fact this note most needed — what a
|
|
188
|
+
user who does nothing will see — turned out to be *nothing*: Gemini CLI
|
|
189
|
+
skips a missing hook in silence. That is the strongest reason the cutoff is
|
|
190
|
+
written where the user looks, not only here.
|
|
191
|
+
|
|
192
|
+
## Next Horizon
|
|
193
|
+
|
|
194
|
+
DS8 closes with this release, and with it the runtime set CV21 set out to
|
|
195
|
+
reach: the canonical plugin on Claude Code, Codex, and Antigravity, Pi
|
|
196
|
+
through its extension. What remains in CV21 is pulled deliberately from the
|
|
197
|
+
CV21 index: user extensions on every runtime (DS5), Grok through the plugin
|
|
198
|
+
(DS10), and the contract and docs refresh that folds all of it into one
|
|
199
|
+
account (DS11).
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
digest: >
|
|
3
|
+
v0.36.0 is a minor release closing CV21.DS10: Grok Build is Mirror Mind's
|
|
4
|
+
fifth runtime, at its honest L3 through the canonical plugin, in two steps
|
|
5
|
+
`mirror init` prints and `runtime diagnose` understands. With it ships
|
|
6
|
+
CV21.DS5.US2: a home's installed extensions reach Claude Code, Codex,
|
|
7
|
+
Antigravity, and Grok Build as one generated plugin per home, the shape
|
|
8
|
+
DS5.TS1 chose by measurement on all four. Three Change Requests ride along,
|
|
9
|
+
each found by using the product: an extension's installation settings get a
|
|
10
|
+
file Mirror reads for them (`extensions/<id>.env`), a closed pipe ends a
|
|
11
|
+
command quietly instead of with a stack trace, and `bind` refuses what it
|
|
12
|
+
cannot bind instead of writing a row that does nothing. No migration.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# v0.36.0 — Five Runtimes, and a Home's Extensions on Every One
|
|
16
|
+
|
|
17
|
+
**Date:** 2026-10-20
|
|
18
|
+
|
|
19
|
+
## Highlights
|
|
20
|
+
|
|
21
|
+
- **Grok Build is the fifth runtime** (CV21.DS10). Two printed steps — a
|
|
22
|
+
trusted plugin install and a home rule for the Operating Instructions — and
|
|
23
|
+
Grok has Mirror's skills, its hooks, and its MCP server. Measured live on
|
|
24
|
+
grok 1.0.62: the rule reaches the model, `/mm-mirror` answers signed by a
|
|
25
|
+
persona, every turn is logged as `grok_build`, the close fits Grok's 1.5 s
|
|
26
|
+
bound. Honest ceiling, written where a user reads it: Grok adds nothing to
|
|
27
|
+
the model's context per turn, so Mirror Mode lasts as long as the skill's
|
|
28
|
+
own instructions do.
|
|
29
|
+
- **A home's extensions reach every plugin runtime** (CV21.DS5.US2).
|
|
30
|
+
`mirror extensions install` and `uninstall` regenerate one small plugin per
|
|
31
|
+
Mirror home, `runtime/plugin/mirror-ext-<user>/`, and print the one wiring
|
|
32
|
+
step a runtime on the `PATH` still needs. Chosen over two other shapes by a
|
|
33
|
+
measured table on claude 2.1.296, codex 0.163.0, agy 1.4.2, and grok 1.0.62
|
|
34
|
+
([decision](../project/decisions.md#user-extensions-reach-every-runtime-as-a-per-home-plugin)).
|
|
35
|
+
`runtime diagnose` names a stale copy and the command that brings it level.
|
|
36
|
+
- **An extension's installation settings have a home**
|
|
37
|
+
([CR145](../project/refinement/rs011-extension-contract-completeness/cr145-an-extension-s-installation-settings-have-nowhere-to-live-but-the-login-shell.md)).
|
|
38
|
+
`~/.mirror-minds/<user>/extensions/<id>.env`, merged *under* the environment
|
|
39
|
+
for the one process Mirror spawns — subcommand or context provider — and
|
|
40
|
+
nothing else. The reason it had to be Mirror: Node reads
|
|
41
|
+
`NODE_EXTRA_CA_CERTS` before any extension code runs, so only the spawner can
|
|
42
|
+
set it, and the alternative was the login shell, where it broke every other
|
|
43
|
+
Postgres client on the machine.
|
|
44
|
+
- **Two front-door manners** ([CR148](../project/refinement/rs010-cv22-oracle-and-port-hygiene/cr148-the-front-door-dies-with-a-stack-trace-when-its-stdout-closes-early.md),
|
|
45
|
+
[CR149](../project/refinement/rs010-cv22-oracle-and-port-hygiene/cr149-bind-accepts-a-persona-or-journey-that-does-not-exist.md)).
|
|
46
|
+
`mirror … | head -1` exits 0 in silence instead of dying of `EPIPE` with a
|
|
47
|
+
stack trace — on the hook entry too, where exit 1 was the one code it
|
|
48
|
+
promised never to return. And `mirror ext <id> bind` checks the extension,
|
|
49
|
+
the capability, and the persona or journey before writing a row, refusing
|
|
50
|
+
with the fix in the line: `no persona 'engine' (mirror list personas shows
|
|
51
|
+
this home's)`.
|
|
52
|
+
|
|
53
|
+
## Where We Started
|
|
54
|
+
|
|
55
|
+
v0.35.0 closed CV21's runtime set at four — Pi, Claude Code, Codex,
|
|
56
|
+
Antigravity — with Grok Build and user extensions named as what remained.
|
|
57
|
+
Grok had been reading Mirror's skills by accident since DS12, through its
|
|
58
|
+
Claude compatibility, with no hooks and no logging, and DS12.TS4 had left the
|
|
59
|
+
MCP attachment as a contradiction: the server ready with its seven tools in
|
|
60
|
+
Grok's own view, every session created with `mcp_server_count: 0`. User
|
|
61
|
+
extensions reached Claude Code through `expose-claude` and Pi through its
|
|
62
|
+
catalog, and nothing else; DS12.TS5 had measured that and left the exposure
|
|
63
|
+
as a choice among three shapes, deciding none.
|
|
64
|
+
|
|
65
|
+
Then the product was used. An extension built for a private journey needed a
|
|
66
|
+
TLS mode and a certificate that belonged to the machine, and the only place
|
|
67
|
+
the contract left for them was `~/.zshrc`. A mistyped `tail -` produced a
|
|
68
|
+
Node stack trace from the front door. A mistyped persona was bound without a
|
|
69
|
+
word. Three Change Requests, two days.
|
|
70
|
+
|
|
71
|
+
## What Changed
|
|
72
|
+
|
|
73
|
+
**Grok Build, in four stories on one day** (2026-10-18, grok 1.0.62).
|
|
74
|
+
CV21.DS10.US1 measured five install shapes and chose two printed steps:
|
|
75
|
+
`grok plugin install "<pkg>/plugins/mirror-mind" --trust`, and the Operating
|
|
76
|
+
Instructions linked as a rule at `~/.grok/rules/mirror-mind.md` — Grok shows a
|
|
77
|
+
session-start hook's context on screen only, so the rule is how the
|
|
78
|
+
instructions reach the model. US1 also found that the root `plugin.json`
|
|
79
|
+
marker DS7 had added was hiding the plugin's version and MCP server from
|
|
80
|
+
Grok; it now carries both, one server on all four plugin runtimes. TS2
|
|
81
|
+
closed DS12's contradiction: the server attaches, its tools sit behind Grok's
|
|
82
|
+
`search_tool` and `use_tool` meta-tools (as `mirror-mind__list_journeys`), and
|
|
83
|
+
the zero count was a snapshot taken while the server was `pending`. US3
|
|
84
|
+
measured L3 with an ablation — remove the rule and the model loses the
|
|
85
|
+
instructions; the hook canaries never reached it — and the deferred close
|
|
86
|
+
tail finished at the next start, DS4.TS2's design on Grok's bound. TS4 wrote
|
|
87
|
+
it: the contract's Grok reference implementation, README, Getting Started,
|
|
88
|
+
REFERENCE, and the Operating Instructions name Grok Build as the fifth
|
|
89
|
+
runtime with its two steps and its ceiling. Paid on the way, CR143: the
|
|
90
|
+
inject hook returns at once on Grok instead of spending 2–3 s per load on a
|
|
91
|
+
context Grok discards.
|
|
92
|
+
|
|
93
|
+
**User extensions, chosen then built** (2026-10-19). CV21.DS5.TS1 measured
|
|
94
|
+
the three shapes DS12.TS5 had left — user-level skill roots, a per-home
|
|
95
|
+
generated plugin, MCP prompts — in scratch homes on all four runtimes, each
|
|
96
|
+
cell read by the runtime's own listing and then by one headless turn asking
|
|
97
|
+
for a canary, with every tool call classified so a find reached by searching
|
|
98
|
+
the disk did not count. Only the per-home plugin qualified on all four: the
|
|
99
|
+
skill roots are three roots that no runtime set reads in common, and MCP
|
|
100
|
+
prompts attached everywhere and reached no model. US2 built it.
|
|
101
|
+
`mirror extensions install`, `uninstall`, and `sync` regenerate
|
|
102
|
+
`runtime/plugin/mirror-ext-<user>/` in the canonical plugin's format,
|
|
103
|
+
version `0.1.<generation>`, carrying each extension's `claude` skill as its
|
|
104
|
+
manifest already declares it — no manifest rewritten. The install prints what
|
|
105
|
+
a runtime on the `PATH` still needs: a link for Claude Code, two commands for
|
|
106
|
+
Codex, one for Antigravity, one with `--trust` for Grok (and the line that
|
|
107
|
+
there is nothing for `--trust` to activate). After a change, the three
|
|
108
|
+
runtimes that copy a plugin hold a stale copy until one command each, which
|
|
109
|
+
the verbs print and `runtime diagnose` raises as five `ext_plugin_*` findings,
|
|
110
|
+
each with its repair. Two homes wire beside each other. `runtime status`
|
|
111
|
+
gained `Extensions plugin: mirror-ext-<user> <version> (<n> skills)`.
|
|
112
|
+
|
|
113
|
+
**The settings file** (CR145). `mirror-cli-v1` handed a subcommand the five
|
|
114
|
+
`MIRROR_*` variables and whatever environment `mirror` had; `mirror-context-v1`
|
|
115
|
+
handed a provider the environment untouched. Now both read
|
|
116
|
+
`extensions/<id>.env` — dotenv, the parser behind Mirror's own `.env` — and
|
|
117
|
+
merge it *under* the process environment: an explicit export still wins, the
|
|
118
|
+
five `MIRROR_*` names can never come from the file, and the result reaches
|
|
119
|
+
that one process. The file sits beside the installed directory, not inside
|
|
120
|
+
it: `install` rewrites the directory, and in a development home the directory
|
|
121
|
+
is a symlink into the extension's own repository. `mirror ext <id>` ends its
|
|
122
|
+
listing with the file's absolute path and one of four states — the variable
|
|
123
|
+
*names* it carries, `no variables`, `not present` with what to do, or
|
|
124
|
+
`unreadable` with the reason — and says when other users can read it. A file
|
|
125
|
+
that exists and cannot be read refuses the subcommand (one line, exit 1,
|
|
126
|
+
nothing spawned) and skips the provider with a `settings_unreadable`
|
|
127
|
+
diagnostic. A full `uninstall` keeps the file and says so. The contract
|
|
128
|
+
reference has the rules in full.
|
|
129
|
+
|
|
130
|
+
**A closed pipe** (CR148). One listener at each entry — `mirror` and
|
|
131
|
+
`mirror-hook` — on `EPIPE`: exit 0, write nothing. `npm`, `cargo`, and
|
|
132
|
+
`kubectl`'s choice over git's 141, because under `set -o pipefail` 141 fails a
|
|
133
|
+
pipeline a person wrote on purpose. Anything that is not `EPIPE` is rethrown.
|
|
134
|
+
The hook leaves one line in `hooks.log` first, `stdout closed early`, because
|
|
135
|
+
its try/catch could never see a stream's `error` event, and a runtime that
|
|
136
|
+
gives up on a hook closes its pipe. Stop means stop: work after the reader
|
|
137
|
+
closes is abandoned, as `SIGPIPE` abandons git's.
|
|
138
|
+
|
|
139
|
+
**`bind` checks what it binds** (CR149). Four checks before the one insert,
|
|
140
|
+
outside in: the id against the manifest's grammar, the extension installed,
|
|
141
|
+
the capability declared (the validator first, then the context reader for the
|
|
142
|
+
list), the persona or journey present in the identity rows a load is later
|
|
143
|
+
matched against. Each refusal is one line on stdout at exit 1 and writes no
|
|
144
|
+
row. `unbind` and `bindings` are untouched: removing a row that points at
|
|
145
|
+
nothing is the repair. A deliberate divergence from the Python oracle; the
|
|
146
|
+
bindings golden kept every byte, with its world given what the checks need.
|
|
147
|
+
|
|
148
|
+
## Upgrading
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npm install -g mirror-mind@latest # or: mirror runtime update
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
No migration. Existing homes, sessions, memories, and bindings are untouched.
|
|
155
|
+
|
|
156
|
+
**Grok Build:** `mirror init` prints the two steps when it finds `grok` on
|
|
157
|
+
your `PATH`; Getting Started's Grok Build section has them with what they
|
|
158
|
+
cost. If you had wired Claude Code, Grok already read the skills from that
|
|
159
|
+
link; after the plugin install each skill appears twice in Grok's menu, and
|
|
160
|
+
the hooks run once.
|
|
161
|
+
|
|
162
|
+
**If you have extensions installed:** the per-home plugin is generated by the
|
|
163
|
+
next `extensions` verb, not by the update. Re-install any one extension —
|
|
164
|
+
`mirror extensions install <id> --extensions-root <root>` from its source, or
|
|
165
|
+
from the home's own `~/.mirror-minds/<user>/extensions` — and the report
|
|
166
|
+
prints the one wiring step each runtime on your `PATH` still needs. Pi needs
|
|
167
|
+
nothing; its catalog path is unchanged.
|
|
168
|
+
|
|
169
|
+
**If an extension of yours reads machine settings from your shell profile:**
|
|
170
|
+
move them to `~/.mirror-minds/<user>/extensions/<id>.env`, `chmod 600` it,
|
|
171
|
+
and `mirror ext <id>` will show the keys it carries. Then delete the exports
|
|
172
|
+
— they reached every other program you run.
|
|
173
|
+
|
|
174
|
+
## Conscious Exclusions
|
|
175
|
+
|
|
176
|
+
- **DS5 is not closed.** US3 — `review-copy` invoked live on each runtime
|
|
177
|
+
from the shipped package, with version, binary, and date — and TS4 — the
|
|
178
|
+
contract, extension docs, Getting Started, and REFERENCE saying how an
|
|
179
|
+
extension reaches each runtime — remain. Until TS4, the install's printed
|
|
180
|
+
steps and the contract's per-home plugin section are the documentation.
|
|
181
|
+
- **DS11**, the contract and docs refresh that folds all five runtimes into
|
|
182
|
+
one parity matrix, is not this release's.
|
|
183
|
+
- **An extension cannot yet declare the settings it expects** (CR146), so the
|
|
184
|
+
settings file is written from the extension's README, not from a
|
|
185
|
+
checklist Mirror prints. **`install` shows `suggested_personas` the home does
|
|
186
|
+
not have as if it did** (CR150). **Three copies of the extension-id grammar
|
|
187
|
+
remain, two of them disagreeing** (CR147); CR145 and CR149 used the
|
|
188
|
+
manifest's. All three captured, none done.
|
|
189
|
+
- **Still open from earlier:** the plugin smoke's negative probe on a machine
|
|
190
|
+
with a global `mirror-hook` (CR142); the DS7 routes removing agy's credential
|
|
191
|
+
where 1.3.x kept it (CR144).
|
|
192
|
+
- **141** as the exit on a closed pipe, and `EPIPE` handling inside extension
|
|
193
|
+
subcommands: not chosen, recorded in CR148.
|
|
194
|
+
|
|
195
|
+
## What We Learned
|
|
196
|
+
|
|
197
|
+
Twice in one day a validation route had to be shown failing before it could
|
|
198
|
+
be trusted passing. CR145's first run validated nothing: the `mirror` on the
|
|
199
|
+
Navigator's `PATH` was the published 0.35.0, and the shell wrapped it in the
|
|
200
|
+
very function the CR retires — the workaround, measured where it lived. CR148's
|
|
201
|
+
planned control, `| head -1`, could not fail: a 2 KB listing lands whole in
|
|
202
|
+
the pipe buffer before `head` quits, so there was never an `EPIPE` to handle;
|
|
203
|
+
the reproduction is a reader that closes without reading. A route that names
|
|
204
|
+
the binary by path and a control that has been seen red are now part of what
|
|
205
|
+
a Change Request's validation means.
|
|
206
|
+
|
|
207
|
+
The three CRs came from using the product, not from reading it: a private
|
|
208
|
+
journey's extension, a typo, another typo. The review that preceded each —
|
|
209
|
+
five lenses on CR145, three on CR148, four on CR149 — changed each plan
|
|
210
|
+
before a line was written, and the things it added (a result type instead of
|
|
211
|
+
a throw, a diagnostic kind instead of a generic failure, a check zero on the
|
|
212
|
+
id grammar) are the parts a future reader will be glad of.
|
|
213
|
+
|
|
214
|
+
## Next Horizon
|
|
215
|
+
|
|
216
|
+
DS5.US3 is the recommended pull: the live proof of `review-copy` on all four
|
|
217
|
+
plugin runtimes from the shipped package, through the steps this release
|
|
218
|
+
prints. TS4 writes what US3 measures. DS11 then folds five runtimes into one
|
|
219
|
+
contract and one matrix, and CV21 closes. RS011 — extension contract
|
|
220
|
+
completeness — holds the gaps the contract has, found one extension at a time;
|
|
221
|
+
CR146, a manifest that declares the settings it expects, is its next natural
|
|
222
|
+
candidate.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mirror-mind",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Mirror Mind: a local-first memory and identity framework for agentic AI runtimes (Pi, Claude Code,
|
|
3
|
+
"version": "0.36.0",
|
|
4
|
+
"description": "Mirror Mind: a local-first memory and identity framework for agentic AI runtimes (Pi, Claude Code, Codex, Antigravity)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"agent",
|
|
16
16
|
"pi-package",
|
|
17
17
|
"claude-code",
|
|
18
|
-
"gemini-cli",
|
|
19
18
|
"codex",
|
|
20
19
|
"sqlite",
|
|
21
20
|
"local-first"
|
|
@@ -36,7 +35,6 @@
|
|
|
36
35
|
".pi/extensions",
|
|
37
36
|
".pi/skills",
|
|
38
37
|
".claude/hooks",
|
|
39
|
-
".gemini/hooks",
|
|
40
38
|
"plugins/mirror-mind",
|
|
41
39
|
".agents/plugins",
|
|
42
40
|
"AGENTS.md",
|