lsd-pi 1.1.2 → 1.1.3

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 (183) hide show
  1. package/README.md +2 -1
  2. package/dist/bedrock-auth.d.ts +25 -0
  3. package/dist/bedrock-auth.js +59 -0
  4. package/dist/headless.js +8 -3
  5. package/dist/loader.js +1 -0
  6. package/dist/onboarding-llm.d.ts +37 -0
  7. package/dist/onboarding-llm.js +64 -0
  8. package/dist/onboarding.d.ts +2 -14
  9. package/dist/onboarding.js +146 -71
  10. package/dist/pi-migration.js +1 -0
  11. package/dist/resources/extensions/memory/auto-extract.js +21 -3
  12. package/dist/resources/extensions/memory/dream.js +703 -0
  13. package/dist/resources/extensions/memory/extension-manifest.json +2 -2
  14. package/dist/resources/extensions/memory/index.js +115 -8
  15. package/dist/resources/extensions/slash-commands/extension-manifest.json +10 -10
  16. package/dist/resources/extensions/slash-commands/index.js +0 -4
  17. package/dist/resources/extensions/slash-commands/plan.js +181 -45
  18. package/dist/resources/extensions/subagent/agents.js +14 -1
  19. package/dist/resources/extensions/subagent/configured-model.js +3 -2
  20. package/dist/resources/extensions/subagent/index.js +34 -28
  21. package/dist/resources/extensions/subagent/launch-helpers.js +24 -0
  22. package/dist/resources/extensions/subagent/model-resolution.js +41 -3
  23. package/dist/resources/extensions/usage/extension-manifest.json +11 -0
  24. package/dist/resources/extensions/usage/index.js +346 -0
  25. package/{src/resources/skills/create-gsd-extension → dist/resources/skills/create-lsd-extension}/SKILL.md +6 -6
  26. package/{src/resources/skills/create-gsd-extension → dist/resources/skills/create-lsd-extension}/references/custom-tools.md +1 -1
  27. package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extension-lifecycle.md +2 -2
  28. package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensioncontext-reference.md +1 -1
  29. package/{src/resources/skills/create-gsd-extension → dist/resources/skills/create-lsd-extension}/references/key-rules-gotchas.md +4 -4
  30. package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/packaging-distribution.md +6 -6
  31. package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/create-extension.md +3 -3
  32. package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/debug-extension.md +5 -5
  33. package/dist/resources/skills/teams-debug/SKILL.md +5 -6
  34. package/dist/resources/skills/teams-document/SKILL.md +1 -2
  35. package/dist/resources/skills/teams-plan/SKILL.md +3 -4
  36. package/dist/resources/skills/teams-run/SKILL.md +3 -4
  37. package/dist/resources/skills/teams-verify/SKILL.md +4 -5
  38. package/dist/startup-model-validation.js +1 -0
  39. package/dist/welcome-screen.js +13 -11
  40. package/dist/wizard.js +12 -0
  41. package/package.json +1 -1
  42. package/packages/pi-ai/dist/models.generated.d.ts +688 -409
  43. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  44. package/packages/pi-ai/dist/models.generated.js +761 -488
  45. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  46. package/packages/pi-ai/scripts/generate-models.ts +40 -18
  47. package/packages/pi-ai/src/models.generated.ts +759 -486
  48. package/packages/pi-coding-agent/dist/cli/config-selector.js +1 -1
  49. package/packages/pi-coding-agent/dist/cli/config-selector.js.map +1 -1
  50. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -2
  51. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  52. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -30
  53. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  54. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +6 -0
  55. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  56. package/packages/pi-coding-agent/dist/core/settings-manager.js +44 -1
  57. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  58. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +9 -5
  59. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  60. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  61. package/packages/pi-coding-agent/dist/core/skills.js +3 -2
  62. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  63. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  64. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  65. package/packages/pi-coding-agent/dist/index.js +1 -1
  66. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  67. package/packages/pi-coding-agent/dist/main.js +1 -1
  68. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  69. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -2
  70. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  71. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  72. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +15 -12
  73. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  74. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +6 -0
  75. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  76. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +25 -1
  77. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  78. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  79. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  80. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  81. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +10 -0
  82. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  83. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +1 -1
  84. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  85. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  86. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +31 -22
  87. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  88. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +18 -5
  89. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  90. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +139 -20
  91. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  92. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  93. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +4 -0
  94. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  95. package/packages/pi-coding-agent/package.json +1 -1
  96. package/packages/pi-coding-agent/src/cli/config-selector.ts +1 -1
  97. package/packages/pi-coding-agent/src/core/agent-session.ts +5 -28
  98. package/packages/pi-coding-agent/src/core/settings-manager.ts +52 -1
  99. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +18 -5
  100. package/packages/pi-coding-agent/src/core/skills.ts +3 -2
  101. package/packages/pi-coding-agent/src/index.ts +1 -1
  102. package/packages/pi-coding-agent/src/main.ts +1 -1
  103. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +2 -2
  104. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +12 -13
  105. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +39 -1
  106. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  107. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +10 -0
  108. package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
  109. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +46 -20
  110. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +171 -20
  111. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -0
  112. package/packages/pi-tui/dist/components/editor.d.ts +1 -0
  113. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  114. package/packages/pi-tui/dist/components/editor.js +23 -0
  115. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  116. package/packages/pi-tui/src/components/editor.ts +23 -0
  117. package/pkg/dist/modes/interactive/theme/theme.d.ts +18 -5
  118. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  119. package/pkg/dist/modes/interactive/theme/theme.js +139 -20
  120. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  121. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  122. package/pkg/dist/modes/interactive/theme/themes.js +4 -0
  123. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  124. package/pkg/package.json +1 -1
  125. package/src/resources/extensions/memory/auto-extract.ts +23 -3
  126. package/src/resources/extensions/memory/dream.ts +814 -0
  127. package/src/resources/extensions/memory/extension-manifest.json +2 -2
  128. package/src/resources/extensions/memory/index.ts +134 -13
  129. package/src/resources/extensions/memory/tests/auto-extract.test.ts +10 -2
  130. package/src/resources/extensions/memory/tests/dream.test.ts +142 -0
  131. package/src/resources/extensions/slash-commands/extension-manifest.json +10 -10
  132. package/src/resources/extensions/slash-commands/index.ts +3 -7
  133. package/src/resources/extensions/slash-commands/plan.ts +192 -46
  134. package/src/resources/extensions/subagent/agents.ts +11 -1
  135. package/src/resources/extensions/subagent/configured-model.ts +3 -2
  136. package/src/resources/extensions/subagent/index.ts +38 -30
  137. package/src/resources/extensions/subagent/launch-helpers.ts +30 -0
  138. package/src/resources/extensions/subagent/model-resolution.ts +40 -3
  139. package/src/resources/extensions/usage/extension-manifest.json +11 -0
  140. package/src/resources/extensions/usage/index.ts +441 -0
  141. package/{dist/resources/skills/create-gsd-extension → src/resources/skills/create-lsd-extension}/SKILL.md +6 -6
  142. package/{dist/resources/skills/create-gsd-extension → src/resources/skills/create-lsd-extension}/references/custom-tools.md +1 -1
  143. package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extension-lifecycle.md +2 -2
  144. package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensioncontext-reference.md +1 -1
  145. package/{dist/resources/skills/create-gsd-extension → src/resources/skills/create-lsd-extension}/references/key-rules-gotchas.md +4 -4
  146. package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/packaging-distribution.md +6 -6
  147. package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/create-extension.md +3 -3
  148. package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/debug-extension.md +5 -5
  149. package/src/resources/skills/teams-debug/SKILL.md +5 -6
  150. package/src/resources/skills/teams-document/SKILL.md +1 -2
  151. package/src/resources/skills/teams-plan/SKILL.md +3 -4
  152. package/src/resources/skills/teams-run/SKILL.md +3 -4
  153. package/src/resources/skills/teams-verify/SKILL.md +4 -5
  154. package/dist/resources/extensions/slash-commands/create-extension.js +0 -264
  155. package/dist/resources/extensions/slash-commands/create-slash-command.js +0 -208
  156. package/src/resources/extensions/slash-commands/create-extension.ts +0 -297
  157. package/src/resources/extensions/slash-commands/create-slash-command.ts +0 -234
  158. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/compaction-session-control.md +0 -0
  159. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-commands.md +0 -0
  160. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-rendering.md +0 -0
  161. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-ui.md +0 -0
  162. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/events-reference.md +0 -0
  163. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensionapi-reference.md +0 -0
  164. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/mode-behavior.md +0 -0
  165. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/model-provider-management.md +0 -0
  166. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/remote-execution-overrides.md +0 -0
  167. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/state-management.md +0 -0
  168. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/system-prompt-modification.md +0 -0
  169. /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/add-capability.md +0 -0
  170. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/compaction-session-control.md +0 -0
  171. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-commands.md +0 -0
  172. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-rendering.md +0 -0
  173. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-ui.md +0 -0
  174. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/events-reference.md +0 -0
  175. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensionapi-reference.md +0 -0
  176. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/mode-behavior.md +0 -0
  177. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/model-provider-management.md +0 -0
  178. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/remote-execution-overrides.md +0 -0
  179. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/state-management.md +0 -0
  180. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/system-prompt-modification.md +0 -0
  181. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/templates/extension-skeleton.ts +0 -0
  182. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/templates/stateful-tool-skeleton.ts +0 -0
  183. /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/add-capability.md +0 -0
@@ -5,7 +5,7 @@
5
5
  "description": "Persistent file-based memory across sessions",
6
6
  "tier": "bundled",
7
7
  "provides": {
8
- "hooks": ["session_start", "before_agent_start", "session_shutdown"],
9
- "commands": ["memories", "remember", "forget"]
8
+ "hooks": ["session_start", "before_agent_start", "turn_end", "tool_call", "session_shutdown"],
9
+ "commands": ["memories", "remember", "forget", "dream", "auto-dream"]
10
10
  }
11
11
  }
@@ -8,27 +8,33 @@
8
8
  * indexed by a MEMORY.md entrypoint that is always loaded into context.
9
9
  */
10
10
 
11
- import type { ExtensionAPI, ExtensionContext } from '@gsd/pi-coding-agent';
11
+ import {
12
+ isToolCallEventType,
13
+ type ExtensionAPI,
14
+ } from '@gsd/pi-coding-agent';
12
15
  import { readFileSync, existsSync, writeFileSync } from 'node:fs';
13
16
  import { getMemoryDir, getMemoryEntrypoint, ensureMemoryDir } from './memory-paths.js';
14
17
  import {
15
- MEMORY_TYPES,
16
18
  MEMORY_FRONTMATTER_EXAMPLE,
17
19
  TYPES_SECTION,
18
20
  WHAT_NOT_TO_SAVE_SECTION,
19
21
  WHEN_TO_ACCESS_SECTION,
20
22
  TRUSTING_RECALL_SECTION,
21
23
  } from './memory-types.js';
22
- import { scanMemoryFiles, formatMemoryManifest } from './memory-scan.js';
24
+ import { scanMemoryFiles } from './memory-scan.js';
23
25
  import { memoryAge } from './memory-age.js';
24
- import { findRelevantMemories } from './memory-recall.js';
25
26
  import { extractMemories } from './auto-extract.js';
27
+ import {
28
+ formatDreamStatus,
29
+ isMaintenanceModeToolAllowed,
30
+ maybeStartAutoDream,
31
+ readAutoDreamSettings,
32
+ setProjectAutoDreamEnabled,
33
+ startDream,
34
+ } from './dream.js';
26
35
 
27
36
  // ── Constants ────────────────────────────────────────────────────────
28
37
 
29
- /** Name of the entrypoint file that indexes all memories. */
30
- const ENTRYPOINT_NAME = 'MEMORY.md';
31
-
32
38
  /** Maximum number of lines loaded from MEMORY.md into context. */
33
39
  const MAX_ENTRYPOINT_LINES = 200;
34
40
 
@@ -144,14 +150,17 @@ ${MEMORY_FRONTMATTER_EXAMPLE.join('\n')}
144
150
  * Memory extension for LSD.
145
151
  *
146
152
  * Lifecycle:
147
- * session_start → bootstrap memory directory & MEMORY.md
153
+ * session_start → bootstrap memory directory & MEMORY.md
148
154
  * before_agent_start → inject memory system prompt
155
+ * turn_end → check auto-dream gates and start background consolidation
149
156
  * session_shutdown → fire-and-forget auto-extract of new memories
150
157
  *
151
158
  * Commands:
152
- * /memories — list all saved memories
153
- * /remember — save a memory immediately
154
- * /forget — remove a memory by topic
159
+ * /memories — list all saved memories
160
+ * /remember — save a memory immediately
161
+ * /forget — remove a memory by topic
162
+ * /dream — run memory consolidation now or show dream status
163
+ * /auto-dream — enable/disable/show auto-dream status
155
164
  */
156
165
  export default function memoryExtension(pi: ExtensionAPI) {
157
166
  let memoryCwd: string = '';
@@ -194,11 +203,52 @@ export default function memoryExtension(pi: ExtensionAPI) {
194
203
  };
195
204
  });
196
205
 
206
+ // ── turn_end: check auto-dream gates ───────────────────────────────
207
+ pi.on('turn_end', async (_event, ctx) => {
208
+ if (!memoryCwd) return;
209
+ const result = maybeStartAutoDream(ctx);
210
+ if (result.started) {
211
+ pi.sendMessage({
212
+ customType: 'memory:auto-dream',
213
+ content: result.message,
214
+ display: true,
215
+ });
216
+ }
217
+ });
218
+
219
+ // ── tool_call: restrict background maintenance workers ─────────────
220
+ pi.on('tool_call', async (event, ctx) => {
221
+ if (!(process.env.LSD_MEMORY_EXTRACT === '1' || process.env.LSD_MEMORY_DREAM === '1')) return;
222
+
223
+ if (isMaintenanceModeToolAllowed(event.toolName, event.input as { path?: string; command?: string }, ctx.cwd)) {
224
+ return;
225
+ }
226
+
227
+ if (isToolCallEventType('write', event) || isToolCallEventType('edit', event)) {
228
+ return {
229
+ block: true,
230
+ reason: `Memory maintenance workers may only write inside the memory directory. Blocked path: ${event.input.path}`,
231
+ };
232
+ }
233
+
234
+ if (isToolCallEventType('bash', event)) {
235
+ return {
236
+ block: true,
237
+ reason: 'Memory maintenance workers may only run read-only bash commands.',
238
+ };
239
+ }
240
+
241
+ return {
242
+ block: true,
243
+ reason: `Tool ${event.toolName} is blocked for memory maintenance workers.`,
244
+ };
245
+ });
246
+
197
247
  // ── session_shutdown: trigger auto-extract ────────────────────────
198
248
  pi.on('session_shutdown', async (_event, ctx) => {
199
249
  if (!memoryCwd) return;
200
- // Don't extract if this IS the extraction agent
201
- if (process.env.LSD_MEMORY_EXTRACT === '1') return;
250
+ // Don't extract if this IS the extraction or dream worker
251
+ if (process.env.LSD_MEMORY_EXTRACT === '1' || process.env.LSD_MEMORY_DREAM === '1') return;
202
252
  try {
203
253
  extractMemories(ctx, memoryCwd);
204
254
  } catch {
@@ -260,4 +310,75 @@ export default function memoryExtension(pi: ExtensionAPI) {
260
310
  pi.sendUserMessage(`Please find and remove any memories about: ${topic}`);
261
311
  },
262
312
  });
313
+
314
+ /**
315
+ * /dream — run a consolidation pass now, or show dream status.
316
+ */
317
+ pi.registerCommand('dream', {
318
+ description: 'Run memory consolidation now or show dream status',
319
+ handler: async (args, ctx) => {
320
+ if (!memoryCwd) return;
321
+ const subcommand = args.trim().toLowerCase();
322
+ if (subcommand === 'status') {
323
+ pi.sendMessage({
324
+ customType: 'memory:dream-status',
325
+ content: formatDreamStatus(ctx),
326
+ display: true,
327
+ });
328
+ return;
329
+ }
330
+
331
+ const result = startDream(ctx, { trigger: 'manual' });
332
+ pi.sendMessage({
333
+ customType: 'memory:dream',
334
+ content: result.message,
335
+ display: true,
336
+ });
337
+ },
338
+ });
339
+
340
+ /**
341
+ * /auto-dream — enable, disable, or inspect project auto-dream.
342
+ */
343
+ pi.registerCommand('auto-dream', {
344
+ description: 'Enable, disable, or show project auto-dream status',
345
+ handler: async (args, ctx) => {
346
+ if (!memoryCwd) return;
347
+ const subcommand = args.trim().toLowerCase();
348
+
349
+ if (subcommand === 'on') {
350
+ const settings = setProjectAutoDreamEnabled(memoryCwd, true);
351
+ pi.sendMessage({
352
+ customType: 'memory:auto-dream-settings',
353
+ content: `Auto-dream enabled for this project. Thresholds: ${settings.minHours}h / ${settings.minSessions} sessions.`,
354
+ display: true,
355
+ });
356
+ return;
357
+ }
358
+
359
+ if (subcommand === 'off') {
360
+ const settings = setProjectAutoDreamEnabled(memoryCwd, false);
361
+ pi.sendMessage({
362
+ customType: 'memory:auto-dream-settings',
363
+ content: `Auto-dream disabled for this project. Thresholds remain ${settings.minHours}h / ${settings.minSessions} sessions.`,
364
+ display: true,
365
+ });
366
+ return;
367
+ }
368
+
369
+ const settings = readAutoDreamSettings(memoryCwd);
370
+ pi.sendMessage({
371
+ customType: 'memory:auto-dream-status',
372
+ content: [
373
+ 'Auto-Dream Settings',
374
+ '',
375
+ `- Enabled: ${settings.enabled ? 'yes' : 'no'}`,
376
+ `- Thresholds: ${settings.minHours}h / ${settings.minSessions} sessions`,
377
+ '',
378
+ formatDreamStatus(ctx),
379
+ ].join('\n'),
380
+ display: true,
381
+ });
382
+ },
383
+ });
263
384
  }
@@ -1,9 +1,9 @@
1
1
  import test, { describe } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
- import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
3
+ import { mkdirSync, rmSync } from 'node:fs';
4
4
  import { join } from 'node:path';
5
5
  import { tmpdir } from 'node:os';
6
- import { buildTranscriptSummary, buildExtractionPrompt } from '../auto-extract.js';
6
+ import { buildTranscriptSummary, buildExtractionPrompt, stripAnsiForAutoExtractLog } from '../auto-extract.js';
7
7
 
8
8
  function makeTempDir(): string {
9
9
  const dir = join(tmpdir(), `mem-extract-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
@@ -97,6 +97,14 @@ describe('buildTranscriptSummary', () => {
97
97
  });
98
98
 
99
99
  describe('buildExtractionPrompt', () => {
100
+ test('strips ANSI codes so session-end and cache-timer lines can be classified', () => {
101
+ const coloredSessionEnd = '\u001b[36m[agent] Session ended\u001b[0m';
102
+ const coloredCacheTimer = '\u001b[36m[phase] cache-timer\u001b[0m';
103
+
104
+ assert.equal(stripAnsiForAutoExtractLog(coloredSessionEnd), '[agent] Session ended');
105
+ assert.equal(stripAnsiForAutoExtractLog(coloredCacheTimer), '[phase] cache-timer');
106
+ });
107
+
100
108
  test('contains the memory directory path in output', () => {
101
109
  const memoryDir = '/tmp/test-memory';
102
110
  const entries = [
@@ -0,0 +1,142 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdirSync, readFileSync, rmSync, statSync, utimesSync, writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import test, { describe } from 'node:test';
6
+ import {
7
+ __testing,
8
+ buildConsolidationPrompt,
9
+ readAutoDreamSettings,
10
+ setProjectAutoDreamEnabled,
11
+ } from '../dream.js';
12
+
13
+ function makeTempDir(): string {
14
+ const dir = join(tmpdir(), `memory-dream-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
15
+ mkdirSync(dir, { recursive: true });
16
+ return dir;
17
+ }
18
+
19
+ describe('buildConsolidationPrompt', () => {
20
+ test('includes the dream consolidation framing and paths', () => {
21
+ const prompt = buildConsolidationPrompt('/tmp/memory', '/tmp/sessions');
22
+ assert.match(prompt, /Dream: Memory Consolidation/);
23
+ assert.match(prompt, /reflective pass over existing memory files/);
24
+ assert.match(prompt, /Validate every MEMORY\.md link and repair or remove broken pointers/);
25
+ assert.match(prompt, /always target absolute paths inside \/tmp\/memory/);
26
+ assert.match(prompt, /\/tmp\/memory/);
27
+ assert.match(prompt, /\/tmp\/sessions/);
28
+ });
29
+ });
30
+
31
+ describe('auto-dream settings', () => {
32
+ test('writes and reads project auto-dream state', () => {
33
+ const cwd = makeTempDir();
34
+ const agentDir = makeTempDir();
35
+ const previous = process.env.LSD_CODING_AGENT_DIR;
36
+ process.env.LSD_CODING_AGENT_DIR = agentDir;
37
+
38
+ try {
39
+ const before = readAutoDreamSettings(cwd);
40
+ assert.equal(before.enabled, false);
41
+ assert.equal(before.minHours, 24);
42
+ assert.equal(before.minSessions, 5);
43
+
44
+ const after = setProjectAutoDreamEnabled(cwd, true);
45
+ assert.equal(after.enabled, true);
46
+ assert.equal(after.minHours, 24);
47
+ assert.equal(after.minSessions, 5);
48
+ } finally {
49
+ if (previous === undefined) {
50
+ delete process.env.LSD_CODING_AGENT_DIR;
51
+ } else {
52
+ process.env.LSD_CODING_AGENT_DIR = previous;
53
+ }
54
+ rmSync(cwd, { recursive: true, force: true });
55
+ rmSync(agentDir, { recursive: true, force: true });
56
+ }
57
+ });
58
+ });
59
+
60
+ describe('listBrokenMemoryIndexEntries', () => {
61
+ test('reports broken MEMORY.md pointers and ignores valid ones', () => {
62
+ const memoryDir = makeTempDir();
63
+ const validFile = join(memoryDir, 'feedback.md');
64
+ const nestedDir = join(memoryDir, 'nested');
65
+ const entrypoint = join(memoryDir, 'MEMORY.md');
66
+
67
+ try {
68
+ mkdirSync(nestedDir, { recursive: true });
69
+ writeFileSync(validFile, 'ok\n', 'utf-8');
70
+ writeFileSync(join(nestedDir, 'present.md'), 'ok\n', 'utf-8');
71
+ writeFileSync(
72
+ entrypoint,
73
+ [
74
+ '- [Valid](feedback.md) — ok',
75
+ '- [Nested](nested/present.md) — ok',
76
+ '- [Missing](missing.md) — missing',
77
+ '- [Escapes](../outside.md) — invalid',
78
+ '- [External](https://example.com) — ignore',
79
+ ].join('\n') + '\n',
80
+ 'utf-8',
81
+ );
82
+
83
+ const broken = __testing.listBrokenMemoryIndexEntries(memoryDir);
84
+ assert.deepEqual(broken, ['../outside.md', 'missing.md']);
85
+ } finally {
86
+ rmSync(memoryDir, { recursive: true, force: true });
87
+ }
88
+ });
89
+
90
+ test('prunes broken MEMORY.md pointers and keeps valid lines', () => {
91
+ const memoryDir = makeTempDir();
92
+ const entrypoint = join(memoryDir, 'MEMORY.md');
93
+ const validFile = join(memoryDir, 'feedback.md');
94
+
95
+ try {
96
+ writeFileSync(validFile, 'ok\n', 'utf-8');
97
+ writeFileSync(
98
+ entrypoint,
99
+ [
100
+ '- [Valid](feedback.md) — ok',
101
+ '- [Missing](missing.md) — missing',
102
+ '- [Escapes](../outside.md) — invalid',
103
+ ].join('\n') + '\n',
104
+ 'utf-8',
105
+ );
106
+
107
+ const pruned = __testing.pruneBrokenMemoryIndexEntries(memoryDir);
108
+ assert.deepEqual(pruned, ['../outside.md', 'missing.md']);
109
+ assert.equal(readFileSync(entrypoint, 'utf-8'), '- [Valid](feedback.md) — ok\n');
110
+ } finally {
111
+ rmSync(memoryDir, { recursive: true, force: true });
112
+ }
113
+ });
114
+ });
115
+
116
+ describe('listSessionsTouchedSince', () => {
117
+ test('counts touched session files and excludes the current session file', () => {
118
+ const sessionDir = makeTempDir();
119
+ const older = join(sessionDir, 'older.jsonl');
120
+ const newer = join(sessionDir, 'newer.jsonl');
121
+ const current = join(sessionDir, 'current.jsonl');
122
+
123
+ try {
124
+ writeFileSync(older, '{}\n', 'utf-8');
125
+ writeFileSync(newer, '{}\n', 'utf-8');
126
+ writeFileSync(current, '{}\n', 'utf-8');
127
+
128
+ const olderTime = Date.now() - 10 * 60 * 1000;
129
+ const newerTime = Date.now() - 60 * 1000;
130
+ utimesSync(older, olderTime / 1000, olderTime / 1000);
131
+ utimesSync(newer, newerTime / 1000, newerTime / 1000);
132
+ utimesSync(current, newerTime / 1000, newerTime / 1000);
133
+
134
+ const sinceMs = statSync(older).mtimeMs + 1000;
135
+ const touched = __testing.listSessionsTouchedSince(sessionDir, sinceMs, current);
136
+ assert.equal(touched.length, 1);
137
+ assert.equal(touched[0], newer);
138
+ } finally {
139
+ rmSync(sessionDir, { recursive: true, force: true });
140
+ }
141
+ });
142
+ });
@@ -1,12 +1,12 @@
1
1
  {
2
- "id": "slash-commands",
3
- "name": "Slash Commands",
4
- "version": "1.0.0",
5
- "description": "Boilerplate generators for slash commands, extensions, and audit tools",
6
- "tier": "bundled",
7
- "requires": { "platform": ">=2.29.0" },
8
- "provides": {
9
- "commands": ["create-slash-command", "create-extension", "audit", "clear", "plan", "execute", "cancel-plan"],
10
- "flags": ["plan"]
11
- }
2
+ "id": "slash-commands",
3
+ "name": "Slash Commands",
4
+ "version": "1.0.0",
5
+ "description": "Bundled slash commands for audit, clearing state, and plan workflows",
6
+ "tier": "bundled",
7
+ "requires": { "platform": ">=2.29.0" },
8
+ "provides": {
9
+ "commands": ["audit", "clear", "plan", "execute", "cancel-plan"],
10
+ "flags": ["plan"]
11
+ }
12
12
  }
@@ -1,14 +1,10 @@
1
1
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
2
- import createSlashCommand from "./create-slash-command.js";
3
- import createExtension from "./create-extension.js";
4
2
  import auditCommand from "./audit.js";
5
3
  import clearCommand from "./clear.js";
6
4
  import planCommand from "./plan.js";
7
5
 
8
6
  export default function slashCommands(pi: ExtensionAPI) {
9
- createSlashCommand(pi);
10
- createExtension(pi);
11
- auditCommand(pi);
12
- clearCommand(pi);
13
- planCommand(pi);
7
+ auditCommand(pi);
8
+ clearCommand(pi);
9
+ planCommand(pi);
14
10
  }