@oh-my-pi/pi-coding-agent 15.5.13 → 15.6.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.
Files changed (192) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/dist/types/cli/classify-install-target.d.ts +0 -10
  3. package/dist/types/cli/initial-message.d.ts +1 -1
  4. package/dist/types/cli/tiny-models-cli.d.ts +9 -0
  5. package/dist/types/commands/tiny-models.d.ts +22 -0
  6. package/dist/types/commit/analysis/conventional.d.ts +1 -1
  7. package/dist/types/commit/analysis/summary.d.ts +1 -1
  8. package/dist/types/commit/changelog/generate.d.ts +1 -1
  9. package/dist/types/commit/changelog/index.d.ts +2 -2
  10. package/dist/types/commit/map-reduce/map-phase.d.ts +1 -1
  11. package/dist/types/commit/map-reduce/reduce-phase.d.ts +1 -1
  12. package/dist/types/config/model-id-affixes.d.ts +10 -0
  13. package/dist/types/config/model-registry.d.ts +1 -1
  14. package/dist/types/config/models-config-schema.d.ts +2 -0
  15. package/dist/types/config/settings-schema.d.ts +233 -17
  16. package/dist/types/discovery/helpers.d.ts +1 -1
  17. package/dist/types/discovery/substitute-plugin-root.d.ts +0 -4
  18. package/dist/types/eval/__tests__/llm-bridge.test.d.ts +1 -0
  19. package/dist/types/eval/js/shared/rewrite-imports.d.ts +16 -1
  20. package/dist/types/eval/llm-bridge.d.ts +25 -0
  21. package/dist/types/export/html/template.generated.d.ts +1 -1
  22. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +15 -0
  23. package/dist/types/internal-urls/agent-protocol.d.ts +2 -1
  24. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -1
  25. package/dist/types/internal-urls/local-protocol.d.ts +2 -1
  26. package/dist/types/internal-urls/memory-protocol.d.ts +2 -1
  27. package/dist/types/internal-urls/omp-protocol.d.ts +2 -1
  28. package/dist/types/internal-urls/router.d.ts +8 -1
  29. package/dist/types/internal-urls/rule-protocol.d.ts +2 -1
  30. package/dist/types/internal-urls/skill-protocol.d.ts +2 -1
  31. package/dist/types/internal-urls/types.d.ts +26 -0
  32. package/dist/types/memory-backend/index.d.ts +1 -0
  33. package/dist/types/memory-backend/resolve.d.ts +2 -1
  34. package/dist/types/memory-backend/types.d.ts +7 -1
  35. package/dist/types/mnemosyne/backend.d.ts +4 -0
  36. package/dist/types/mnemosyne/config.d.ts +29 -0
  37. package/dist/types/mnemosyne/index.d.ts +3 -0
  38. package/dist/types/mnemosyne/state.d.ts +72 -0
  39. package/dist/types/modes/components/custom-editor.d.ts +2 -3
  40. package/dist/types/modes/components/hook-selector.d.ts +27 -0
  41. package/dist/types/modes/components/index.d.ts +1 -0
  42. package/dist/types/modes/components/status-line/context-thresholds.d.ts +6 -0
  43. package/dist/types/modes/components/tiny-title-download-progress.d.ts +11 -0
  44. package/dist/types/modes/components/welcome.d.ts +1 -0
  45. package/dist/types/modes/controllers/extension-ui-controller.d.ts +4 -1
  46. package/dist/types/modes/gradient-highlight.d.ts +23 -0
  47. package/dist/types/modes/interactive-mode.d.ts +4 -2
  48. package/dist/types/modes/internal-url-autocomplete.d.ts +43 -0
  49. package/dist/types/modes/orchestrate.d.ts +10 -0
  50. package/dist/types/modes/theme/defaults/index.d.ts +8406 -8406
  51. package/dist/types/modes/theme/theme.d.ts +2 -1
  52. package/dist/types/modes/ultrathink.d.ts +3 -3
  53. package/dist/types/modes/utils/keybinding-matchers.d.ts +5 -0
  54. package/dist/types/sdk.d.ts +3 -0
  55. package/dist/types/session/agent-session.d.ts +35 -0
  56. package/dist/types/system-prompt.d.ts +2 -0
  57. package/dist/types/task/executor.d.ts +2 -0
  58. package/dist/types/task/render.d.ts +5 -1
  59. package/dist/types/tiny/models.d.ts +185 -0
  60. package/dist/types/tiny/text.d.ts +4 -0
  61. package/dist/types/tiny/title-client.d.ts +24 -0
  62. package/dist/types/tiny/title-protocol.d.ts +74 -0
  63. package/dist/types/tiny/worker.d.ts +2 -0
  64. package/dist/types/tools/bash.d.ts +3 -1
  65. package/dist/types/tools/index.d.ts +7 -4
  66. package/dist/types/tools/memory-edit.d.ts +40 -0
  67. package/dist/types/tools/{hindsight-recall.d.ts → memory-recall.d.ts} +6 -6
  68. package/dist/types/tools/{hindsight-reflect.d.ts → memory-reflect.d.ts} +6 -6
  69. package/dist/types/tools/memory-render.d.ts +60 -0
  70. package/dist/types/tools/{hindsight-retain.d.ts → memory-retain.d.ts} +6 -6
  71. package/dist/types/tools/todo-write.d.ts +8 -0
  72. package/dist/types/tools/tool-result.d.ts +2 -0
  73. package/dist/types/utils/title-generator.d.ts +3 -0
  74. package/package.json +18 -14
  75. package/scripts/build-binary.ts +1 -0
  76. package/src/cli/tiny-models-cli.ts +127 -0
  77. package/src/cli-commands.ts +1 -0
  78. package/src/cli.ts +8 -8
  79. package/src/commands/tiny-models.ts +36 -0
  80. package/src/config/model-equivalence.ts +43 -2
  81. package/src/config/model-id-affixes.ts +64 -0
  82. package/src/config/model-registry.ts +166 -8
  83. package/src/config/models-config-schema.ts +1 -1
  84. package/src/config/settings-schema.ts +206 -14
  85. package/src/edit/hashline/diff.ts +5 -7
  86. package/src/eval/__tests__/llm-bridge.test.ts +297 -0
  87. package/src/eval/__tests__/shared-executors.test.ts +36 -0
  88. package/src/eval/js/shared/local-module-loader.ts +13 -1
  89. package/src/eval/js/shared/prelude.txt +8 -0
  90. package/src/eval/js/shared/rewrite-imports.ts +31 -26
  91. package/src/eval/js/tool-bridge.ts +4 -0
  92. package/src/eval/llm-bridge.ts +181 -0
  93. package/src/eval/py/prelude.py +52 -31
  94. package/src/export/html/template.generated.ts +1 -1
  95. package/src/export/html/template.js +0 -13
  96. package/src/extensibility/plugins/legacy-pi-compat.ts +60 -23
  97. package/src/internal-urls/agent-protocol.ts +18 -1
  98. package/src/internal-urls/artifact-protocol.ts +19 -1
  99. package/src/internal-urls/docs-index.generated.ts +5 -4
  100. package/src/internal-urls/local-protocol.ts +14 -1
  101. package/src/internal-urls/memory-protocol.ts +6 -1
  102. package/src/internal-urls/omp-protocol.ts +5 -1
  103. package/src/internal-urls/router.ts +20 -1
  104. package/src/internal-urls/rule-protocol.ts +8 -1
  105. package/src/internal-urls/skill-protocol.ts +8 -1
  106. package/src/internal-urls/types.ts +27 -0
  107. package/src/lsp/render.ts +1 -1
  108. package/src/main.ts +4 -0
  109. package/src/mcp/oauth-flow.ts +2 -2
  110. package/src/memory-backend/index.ts +1 -0
  111. package/src/memory-backend/resolve.ts +4 -1
  112. package/src/memory-backend/types.ts +8 -1
  113. package/src/mnemosyne/backend.ts +374 -0
  114. package/src/mnemosyne/config.ts +160 -0
  115. package/src/mnemosyne/index.ts +3 -0
  116. package/src/mnemosyne/state.ts +548 -0
  117. package/src/modes/acp/acp-agent.ts +11 -6
  118. package/src/modes/components/agent-dashboard.ts +4 -4
  119. package/src/modes/components/custom-editor.ts +3 -2
  120. package/src/modes/components/diff.ts +2 -2
  121. package/src/modes/components/extensions/extension-list.ts +3 -2
  122. package/src/modes/components/footer.ts +5 -6
  123. package/src/modes/components/history-search.ts +3 -3
  124. package/src/modes/components/hook-selector.ts +94 -8
  125. package/src/modes/components/index.ts +1 -0
  126. package/src/modes/components/mcp-add-wizard.ts +3 -3
  127. package/src/modes/components/model-selector.ts +124 -26
  128. package/src/modes/components/oauth-selector.ts +3 -3
  129. package/src/modes/components/session-observer-overlay.ts +19 -13
  130. package/src/modes/components/session-selector.ts +3 -3
  131. package/src/modes/components/settings-defs.ts +7 -0
  132. package/src/modes/components/status-line/context-thresholds.ts +11 -0
  133. package/src/modes/components/status-line/presets.ts +1 -0
  134. package/src/modes/components/status-line/segments.ts +25 -2
  135. package/src/modes/components/tiny-title-download-progress.ts +90 -0
  136. package/src/modes/components/tips.txt +12 -0
  137. package/src/modes/components/tool-execution.ts +67 -3
  138. package/src/modes/components/tree-selector.ts +3 -3
  139. package/src/modes/components/user-message-selector.ts +3 -3
  140. package/src/modes/components/welcome.ts +55 -1
  141. package/src/modes/controllers/command-controller.ts +16 -1
  142. package/src/modes/controllers/extension-ui-controller.ts +3 -1
  143. package/src/modes/controllers/input-controller.ts +57 -0
  144. package/src/modes/gradient-highlight.ts +70 -0
  145. package/src/modes/interactive-mode.ts +80 -196
  146. package/src/modes/internal-url-autocomplete.ts +143 -0
  147. package/src/modes/orchestrate.ts +36 -0
  148. package/src/modes/prompt-action-autocomplete.ts +12 -0
  149. package/src/modes/theme/theme.ts +7 -0
  150. package/src/modes/ultrathink.ts +9 -53
  151. package/src/modes/utils/keybinding-matchers.ts +11 -0
  152. package/src/prompts/system/memory-consolidation-system.md +8 -0
  153. package/src/prompts/system/memory-extraction-system.md +26 -0
  154. package/src/prompts/{commands/orchestrate.md → system/orchestrate-notice.md} +5 -16
  155. package/src/prompts/system/system-prompt.md +2 -0
  156. package/src/prompts/system/tiny-title-system.md +8 -0
  157. package/src/prompts/tools/eval.md +2 -0
  158. package/src/prompts/tools/memory-edit.md +8 -0
  159. package/src/prompts/tools/task.md +4 -7
  160. package/src/sdk.ts +8 -6
  161. package/src/session/agent-session.ts +147 -44
  162. package/src/session/session-manager.ts +47 -0
  163. package/src/slash-commands/builtin-registry.ts +10 -1
  164. package/src/system-prompt.ts +4 -0
  165. package/src/task/commands.ts +1 -5
  166. package/src/task/executor.ts +8 -0
  167. package/src/task/index.ts +2 -0
  168. package/src/task/render.ts +69 -26
  169. package/src/tiny/models.ts +217 -0
  170. package/src/tiny/text.ts +19 -0
  171. package/src/tiny/title-client.ts +340 -0
  172. package/src/tiny/title-protocol.ts +51 -0
  173. package/src/tiny/worker.ts +523 -0
  174. package/src/tools/bash.ts +58 -16
  175. package/src/tools/browser/tab-worker.ts +1 -1
  176. package/src/tools/eval.ts +24 -48
  177. package/src/tools/index.ts +17 -15
  178. package/src/tools/memory-edit.ts +59 -0
  179. package/src/tools/memory-recall.ts +100 -0
  180. package/src/tools/memory-reflect.ts +88 -0
  181. package/src/tools/memory-render.ts +185 -0
  182. package/src/tools/memory-retain.ts +91 -0
  183. package/src/tools/renderers.ts +4 -2
  184. package/src/tools/todo-write.ts +128 -29
  185. package/src/tools/tool-result.ts +8 -0
  186. package/src/utils/title-generator.ts +115 -13
  187. package/dist/types/tools/calculator.d.ts +0 -77
  188. package/src/prompts/tools/calculator.md +0 -10
  189. package/src/tools/calculator.ts +0 -541
  190. package/src/tools/hindsight-recall.ts +0 -69
  191. package/src/tools/hindsight-reflect.ts +0 -58
  192. package/src/tools/hindsight-retain.ts +0 -57
@@ -144,6 +144,7 @@ export type SymbolKey =
144
144
  | "md.quoteBorder"
145
145
  | "md.hrChar"
146
146
  | "md.bullet"
147
+ | "md.colorSwatch"
147
148
  // Language/file type icons
148
149
  | "lang.default"
149
150
  | "lang.typescript"
@@ -308,6 +309,7 @@ const UNICODE_SYMBOLS: SymbolMap = {
308
309
  "md.quoteBorder": "▏",
309
310
  "md.hrChar": "─",
310
311
  "md.bullet": "•",
312
+ "md.colorSwatch": "■",
311
313
  // Language/file icons (emoji-centric, no Nerd Font required)
312
314
  "lang.default": "⌘",
313
315
  "lang.typescript": "🟦",
@@ -568,6 +570,8 @@ const NERD_SYMBOLS: SymbolMap = {
568
570
  "md.hrChar": "─",
569
571
  // pick:  | alt:  •
570
572
  "md.bullet": "\uf111",
573
+ // pick: ■ | alt: (U+F096)
574
+ "md.colorSwatch": "■",
571
575
  // Language icons (nerd font devicons)
572
576
  "lang.default": "",
573
577
  "lang.typescript": "\u{E628}",
@@ -730,6 +734,7 @@ const ASCII_SYMBOLS: SymbolMap = {
730
734
  "md.quoteBorder": "|",
731
735
  "md.hrChar": "-",
732
736
  "md.bullet": "*",
737
+ "md.colorSwatch": "[]",
733
738
  // Language icons (ASCII uses abbreviations)
734
739
  "lang.default": "code",
735
740
  "lang.typescript": "ts",
@@ -1519,6 +1524,7 @@ export class Theme {
1519
1524
  quoteBorder: this.#symbols["md.quoteBorder"],
1520
1525
  hrChar: this.#symbols["md.hrChar"],
1521
1526
  bullet: this.#symbols["md.bullet"],
1527
+ colorSwatch: this.#symbols["md.colorSwatch"],
1522
1528
  };
1523
1529
  }
1524
1530
 
@@ -2340,6 +2346,7 @@ export function getSymbolTheme(): SymbolTheme {
2340
2346
  table: theme.boxSharp,
2341
2347
  quoteBorder: theme.md.quoteBorder,
2342
2348
  hrChar: theme.md.hrChar,
2349
+ colorSwatch: theme.md.colorSwatch,
2343
2350
  spinnerFrames: theme.getSpinnerFrames("activity"),
2344
2351
  };
2345
2352
  }
@@ -1,5 +1,5 @@
1
1
  import ultrathinkNotice from "../prompts/system/ultrathink-notice.md" with { type: "text" };
2
- import { theme } from "./theme/theme";
2
+ import { createGradientHighlighter } from "./gradient-highlight";
3
3
 
4
4
  /**
5
5
  * "ultrathink" keyword support, mirroring Claude Code's affordance.
@@ -11,12 +11,8 @@ import { theme } from "./theme/theme";
11
11
  * "ultrathinking"/"ultrathinks" never trigger either behavior.
12
12
  */
13
13
 
14
- // Cheap, stateless presence probe used to skip the boundary regex on most lines.
15
- const ULTRATHINK_PROBE = /ultrathink/i;
16
14
  // Detection: standalone keyword, any case. Non-global so `.test` stays stateless.
17
15
  const ULTRATHINK_WORD = /\bultrathink\b/i;
18
- // Highlight: global so `.replace` walks every occurrence.
19
- const ULTRATHINK_HIGHLIGHT = /\bultrathink\b/gi;
20
16
 
21
17
  /** Hidden system notice appended after a user message that mentions "ultrathink". */
22
18
  export const ULTRATHINK_NOTICE: string = ultrathinkNotice.trim();
@@ -26,54 +22,14 @@ export function containsUltrathink(text: string): boolean {
26
22
  return ULTRATHINK_WORD.test(text);
27
23
  }
28
24
 
29
- const FG_RESET = "\x1b[39m";
30
- // Hue stops swept across the visible spectrum. More stops than the keyword has
31
- // letters so the gradient resolves smoothly regardless of casing/match length.
32
- const RAINBOW_STOPS = 14;
33
-
34
- let cachedMode: string | undefined;
35
- let cachedPalette: readonly string[] | undefined;
36
-
37
- /** Rainbow foreground escapes for the active color mode, compiled once per mode. */
38
- function rainbowPalette(): readonly string[] {
39
- const mode = theme.getColorMode();
40
- if (cachedPalette && cachedMode === mode) return cachedPalette;
41
- const format = mode === "truecolor" ? "ansi-16m" : "ansi-256";
42
- const palette: string[] = [];
43
- for (let i = 0; i < RAINBOW_STOPS; i++) {
44
- // Sweep red→violet (0..330°), stopping short of the wrap back to red.
45
- const hue = Math.round((i / RAINBOW_STOPS) * 330);
46
- palette.push(Bun.color(`hsl(${hue}, 90%, 62%)`, format) ?? "");
47
- }
48
- cachedMode = mode;
49
- cachedPalette = palette;
50
- return palette;
51
- }
52
-
53
- /** Paint each character of `word` with the next rainbow stop, resetting fg after. */
54
- function rainbow(word: string): string {
55
- const palette = rainbowPalette();
56
- const n = word.length;
57
- let out = "";
58
- let prev = "";
59
- for (let i = 0; i < n; i++) {
60
- const color = palette[Math.floor((i / n) * palette.length)] ?? palette[0] ?? "";
61
- // Coalesce consecutive characters that resolve to the same stop.
62
- if (color !== prev) {
63
- out += color;
64
- prev = color;
65
- }
66
- out += word[i];
67
- }
68
- return `${out}${FG_RESET}`;
69
- }
70
-
71
25
  /**
72
26
  * Rainbow-highlight every standalone "ultrathink" in `text` for editor display.
73
- * Adds only zero-width SGR escapes the visible width is unchanged and returns
74
- * the input untouched when the keyword is absent.
27
+ * Sweeps red→violet (hue 0..330), stopping short of the wrap back to red so the
28
+ * gradient resolves smoothly regardless of casing or match length.
75
29
  */
76
- export function highlightUltrathink(text: string): string {
77
- if (!ULTRATHINK_PROBE.test(text)) return text;
78
- return text.replace(ULTRATHINK_HIGHLIGHT, rainbow);
79
- }
30
+ export const highlightUltrathink: (text: string) => string = createGradientHighlighter({
31
+ probe: /ultrathink/i,
32
+ highlight: /\bultrathink\b/gi,
33
+ stops: 14,
34
+ hue: t => t * 330,
35
+ });
@@ -16,10 +16,21 @@ export function matchesAppInterrupt(data: string): boolean {
16
16
  return matchesKey(data, "escape") || matchesKey(data, "esc");
17
17
  }
18
18
 
19
+ /** Match the generic selector cancel keybinding. */
19
20
  export function matchesSelectCancel(data: string): boolean {
20
21
  return getKeybindings().matches(data, "tui.select.cancel");
21
22
  }
22
23
 
24
+ /** Match the generic selector up-navigation keybinding. */
25
+ export function matchesSelectUp(data: string): boolean {
26
+ return getKeybindings().matches(data, "tui.select.up");
27
+ }
28
+
29
+ /** Match the generic selector down-navigation keybinding. */
30
+ export function matchesSelectDown(data: string): boolean {
31
+ return getKeybindings().matches(data, "tui.select.down");
32
+ }
33
+
23
34
  export function matchesAppExternalEditor(data: string): boolean {
24
35
  const keybindings = getKeybindings();
25
36
  const externalEditorKeys = keybindings.getKeys("app.editor.external");
@@ -0,0 +1,8 @@
1
+ Summarize the memories below into 1-3 concise sentences.
2
+
3
+ Preserve every fact, name, number, version, date, and decision exactly. Merge duplicates and near-duplicates; never repeat the same point. When memories conflict, state only the most recent as current. Do not invent, infer, or add anything that is not present in the memories. Output only the summary sentences, nothing else.
4
+
5
+ Memories:
6
+ {memories}
7
+
8
+ Summary:
@@ -0,0 +1,26 @@
1
+ Extract durable, long-term memory items from the user message below.
2
+
3
+ Output ONE item per line as a short plain-text statement: no JSON, no bullets, no numbering, no field labels.
4
+ Capture only persistent, reusable information:
5
+ - facts (name, role, employer, config, ports, versions, numbers)
6
+ - explicit instructions to the assistant
7
+ - stable preferences
8
+ - dated events or deadlines
9
+
10
+ Keep names, numbers, versions, and dates exact, in the message's original language. When a value is updated, output only the latest value. Ignore greetings, acknowledgements, small talk, weather, and one-off remarks.
11
+ If nothing qualifies, output exactly: NO_FACTS
12
+
13
+ Example
14
+ Message: My name is Sam, I work at Globex, and I always use 2-space indents.
15
+ Items:
16
+ name is Sam
17
+ works at Globex
18
+ prefers 2-space indents
19
+
20
+ Example
21
+ Message: lol nice weather today, might grab a coffee later
22
+ Items:
23
+ NO_FACTS
24
+
25
+ Message: {text}
26
+ Items:
@@ -1,17 +1,5 @@
1
- ---
2
- name: orchestrate
3
- description: Drive a multi-phase task to completion via parallel subagents
4
- ---
5
-
6
- # Task
7
-
8
- $@
9
-
10
- ---
11
-
12
- # Orchestration Contract
13
-
14
- You are the **orchestrator** for the task above. Read it once, then execute under the rules below. The contract overrides any default tendency to yield early, narrate, or do work yourself.
1
+ <system-notice>
2
+ The user's message above is an **orchestration request**. Execute it as the orchestrator under the contract below. This contract overrides any default tendency to yield early, narrate, or do the work yourself.
15
3
 
16
4
  <role>
17
5
  You decompose, dispatch, verify, and iterate. You do **not** edit code. Every file mutation goes through a `task` subagent. Your tool budget is: reading for planning, `task` for dispatch, verification (`bun check`, `bun test`, `recipe`, `lsp diagnostics`), git via `bash`, and `todo_write` for tracking.
@@ -19,11 +7,11 @@ You decompose, dispatch, verify, and iterate. You do **not** edit code. Every fi
19
7
 
20
8
  <rules>
21
9
  1. **Do not yield until everything is closed.** A phase finishing is *not* a yield point — launch the next phase in the same turn. Stop only when every requested item is verifiably done, or you hit a concrete [blocked] state that genuinely requires the user.
22
- 2. **Enumerate the full surface before dispatching.** If the task references audits, plans, checklists, phase lists, or file lists, expand them into a flat set of items in `todo_write`. "Most of them" or "the important ones" is failure. Re-read the source documents — do not work from memory.
10
+ 2. **Enumerate the full surface before dispatching.** If the request references audits, plans, checklists, phase lists, or file lists, expand them into a flat set of items in `todo_write`. "Most of them" or "the important ones" is failure. Re-read the source documents — do not work from memory.
23
11
  3. **Parallelize maximally.** Every set of edits with disjoint file scope MUST ship as one `task` batch. Serialize only when one subagent produces a contract (types, schema, shared module) the next consumes — and state the dependency when you do.
24
12
  4. **Each `task` assignment is self-contained.** Subagents have no shared context. Spell out: target files (≤3–5 explicit paths, no globs), the change with APIs and patterns, edge cases, and observable acceptance criteria. Do not assume they read the same plan you did.
25
13
  5. **Verify after every phase before launching the next.** Run the appropriate gate: `bun check` for types, package-scoped `bun test` for behavior, `lsp diagnostics` for changed files. If a phase introduced breakage, dispatch fix-up subagents *before* moving on. Never declare a phase done on a red tree.
26
- 6. **Commit policy.** If the task asks for commits or the repo workflow expects them, commit after each green phase with a focused message. Never commit a red tree. Never commit work the user did not ask to commit.
14
+ 6. **Commit policy.** If the request asks for commits or the repo workflow expects them, commit after each green phase with a focused message. Never commit a red tree. Never commit work the user did not ask to commit.
27
15
  7. **Respawn, do not absorb.** If a subagent returns incomplete or wrong work, spawn a corrective subagent with the specific gap — do not silently fix it yourself.
28
16
  8. **No scope creep, no scope shrink.** Do not add work the user did not ask for. Do not relabel unfinished items as "follow-up", "v1", or "MVP" to imply completion.
29
17
  9. **Subagents do not verify, lint, or format.** Every `task` assignment MUST instruct the subagent to skip all gates and formatters. Their job is the edit only. You — the orchestrator — run verification and formatting **once** at the end of the phase across the union of changed files. Avoids redundant runs and racing formatter passes.
@@ -47,3 +35,4 @@ You decompose, dispatch, verify, and iterate. You do **not** edit code. Every fi
47
35
  - Marking todos done based on subagent self-reports without verifying the gate.
48
36
  - Summarizing progress in chat instead of advancing to the next phase.
49
37
  </anti-patterns>
38
+ </system-notice>
@@ -54,7 +54,9 @@ With most FS/bash-like tools, static references to them will automatically resol
54
54
  - `skill://<name>`: Skill instructions
55
55
  - `/<path>`: File within a skill
56
56
  - `rule://<name>`: Rule details
57
+ {{#if hasMemoryRoot}}
57
58
  - `memory://root`: Project memory summary
59
+ {{/if}}
58
60
  - `agent://<id>`: Full agent output artifact
59
61
  - `/<path>`: JSON field extraction
60
62
  - `artifact://<id>`: Artifact content
@@ -0,0 +1,8 @@
1
+ You generate concise terminal session titles.
2
+
3
+ Input is one user message inside `<user-message>` tags.
4
+
5
+ Return one specific 3-6 word title.
6
+ Continue the assistant response after `<title>` and close it with `</title>`.
7
+
8
+ NEVER include quotes, punctuation, markdown, commentary, or a second line.
@@ -44,6 +44,8 @@ output(*ids, format?="raw", query?=None, offset?=None, limit?=None) → str | di
44
44
  Read task/agent output by ID. Single id returns text/dict; multiple ids return a list.
45
45
  tool.<name>(args) → unknown
46
46
  Invoke any session tool by name. `args` is the tool's parameter object.
47
+ llm(prompt, model?="default", system?=None, schema?=None) → str | dict
48
+ Oneshot, stateless LLM call (no history, no tools). `model` picks a tier: "smol" (fast), "default" (this session's model), "slow" (most capable). Pass `system` for a system prompt. Pass a JSON-Schema `schema` to force structured output and get the parsed object back; otherwise returns the completion text.
47
49
  ```
48
50
  </prelude>
49
51
 
@@ -0,0 +1,8 @@
1
+ Edit Mnemosyne long-term memories by id.
2
+
3
+ Use only with ids returned by the `recall` tool. Operations:
4
+ - `update`: replace content and/or importance for a working memory.
5
+ - `forget`: permanently delete a working memory.
6
+ - `invalidate`: softly supersede a working or episodic memory, optionally pointing at `replacement_id`.
7
+
8
+ Prefer `invalidate` when a memory became stale but its history may still be useful. Use `forget` only for content that should be hard-deleted.
@@ -30,15 +30,12 @@ Subagents have no conversation history. Every fact, file path, and direction the
30
30
  </parameters>
31
31
 
32
32
  <rules>
33
+ - **Maximize batch width.** Spawn the widest parallel set the work decomposes into. NEVER spawn a single-task batch for divisible work, or defer work that could have been concurrent.
33
34
  - NEVER assign tasks to run project-wide build/test/lint. Caller verifies after the batch.
34
35
  - **Subagents do not verify, lint, or format.** Every assignment MUST instruct the subagent to skip all gates and formatters. You run them once at the end across the union of changed files — avoids redundant runs and racing formatter passes.
35
- {{#if ircEnabled}}
36
- - Each task: ≤3–5 explicit files. Overlapping file sets are tolerable when peers can coordinate via `irc`, but still fan out to a cluster when the scopes are cleanly separable.
37
- - No globs, no "update all", no package-wide scope.
38
- {{else}}
39
- - Each task: ≤3–5 explicit files. No globs, no "update all", no package-wide scope. Fan out to a cluster instead.
40
- {{/if}}
41
- - Pass large payloads via `local://<path>` URIs, not inline.
36
+ - No globs, no "update all", no package-wide scope. Fan out.
37
+ - Do not concern yourself with how agents might overlap on certain actions. Never use it as an excuse to go slower: they can resolve collisions in real-time with the harness facilities.
38
+ - Pass large payloads via `local://<path>` URIs, not inline. {{#if contextEnabled}} (other than the context){{/if}}
42
39
  {{#if contextEnabled}}- Put shared constraints in `context` once; do not duplicate across assignments.{{/if}}
43
40
  - Prefer agents that investigate **and** edit in one pass; only spin a read-only discovery step when affected files are genuinely unknown.
44
41
  </rules>
package/src/sdk.ts CHANGED
@@ -86,8 +86,8 @@ import type { HindsightSessionState } from "./hindsight/state";
86
86
  import { LocalProtocolHandler, type LocalProtocolOptions } from "./internal-urls";
87
87
  import { LSP_STARTUP_EVENT_CHANNEL, type LspStartupEvent } from "./lsp/startup-events";
88
88
  import { discoverAndLoadMCPTools, MCPManager, type MCPToolsLoadResult } from "./mcp";
89
-
90
89
  import { resolveMemoryBackend } from "./memory-backend";
90
+ import { getMnemosyneSessionState, type MnemosyneSessionState } from "./mnemosyne/state";
91
91
  import asyncResultTemplate from "./prompts/tools/async-result.md" with { type: "text" };
92
92
  import { AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
93
93
  import {
@@ -313,6 +313,8 @@ export interface CreateAgentSessionOptions {
313
313
  taskDepth?: number;
314
314
  /** Parent Hindsight state to alias for subagent memory tools. */
315
315
  parentHindsightSessionState?: HindsightSessionState;
316
+ /** Parent Mnemosyne state to alias for subagent memory tools. */
317
+ parentMnemosyneSessionState?: MnemosyneSessionState;
316
318
  /** Pre-allocated agent identity for IRC routing. Default: "0-Main" for top-level, parentTaskPrefix-derived for sub. */
317
319
  agentId?: string;
318
320
  /** Display name for the agent in IRC. Default: "main" or "sub". */
@@ -1187,6 +1189,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1187
1189
  session ? session.trackEvalExecution(execution, abortController) : execution,
1188
1190
  getSessionId: () => sessionManager.getSessionId?.() ?? null,
1189
1191
  getHindsightSessionState: () => session?.getHindsightSessionState(),
1192
+ getMnemosyneSessionState: () => getMnemosyneSessionState(session),
1190
1193
  getAgentId: () => resolvedAgentId,
1191
1194
  getToolByName: name => session?.getToolByName(name),
1192
1195
  agentRegistry,
@@ -1593,11 +1596,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1593
1596
  const promptTools = buildSystemPromptToolMetadata(tools, {
1594
1597
  search_tool_bm25: { description: renderSearchToolBm25Description(discoverableToolsForDesc) },
1595
1598
  });
1596
- const memoryInstructions = await resolveMemoryBackend(settings).buildDeveloperInstructions(
1597
- agentDir,
1598
- settings,
1599
- session,
1600
- );
1599
+ const memoryBackend = resolveMemoryBackend(settings);
1600
+ const memoryInstructions = await memoryBackend.buildDeveloperInstructions(agentDir, settings, session);
1601
1601
 
1602
1602
  // Build combined append prompt: memory instructions + MCP server instructions
1603
1603
  const serverInstructions = mcpManager?.getServerInstructions();
@@ -1634,6 +1634,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1634
1634
  eagerTasks,
1635
1635
  secretsEnabled,
1636
1636
  workspaceTree: workspaceTreePromise,
1637
+ memoryRootEnabled: memoryBackend.id === "local",
1637
1638
  });
1638
1639
 
1639
1640
  if (options.systemPrompt === undefined) {
@@ -2123,6 +2124,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2123
2124
  agentDir,
2124
2125
  taskDepth,
2125
2126
  parentHindsightSessionState: options.parentHindsightSessionState,
2127
+ parentMnemosyneSessionState: options.parentMnemosyneSessionState,
2126
2128
  }),
2127
2129
  ),
2128
2130
  );