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.
- package/README.md +2 -1
- package/dist/bedrock-auth.d.ts +25 -0
- package/dist/bedrock-auth.js +59 -0
- package/dist/headless.js +8 -3
- package/dist/loader.js +1 -0
- package/dist/onboarding-llm.d.ts +37 -0
- package/dist/onboarding-llm.js +64 -0
- package/dist/onboarding.d.ts +2 -14
- package/dist/onboarding.js +146 -71
- package/dist/pi-migration.js +1 -0
- package/dist/resources/extensions/memory/auto-extract.js +21 -3
- package/dist/resources/extensions/memory/dream.js +703 -0
- package/dist/resources/extensions/memory/extension-manifest.json +2 -2
- package/dist/resources/extensions/memory/index.js +115 -8
- package/dist/resources/extensions/slash-commands/extension-manifest.json +10 -10
- package/dist/resources/extensions/slash-commands/index.js +0 -4
- package/dist/resources/extensions/slash-commands/plan.js +181 -45
- package/dist/resources/extensions/subagent/agents.js +14 -1
- package/dist/resources/extensions/subagent/configured-model.js +3 -2
- package/dist/resources/extensions/subagent/index.js +34 -28
- package/dist/resources/extensions/subagent/launch-helpers.js +24 -0
- package/dist/resources/extensions/subagent/model-resolution.js +41 -3
- package/dist/resources/extensions/usage/extension-manifest.json +11 -0
- package/dist/resources/extensions/usage/index.js +346 -0
- package/{src/resources/skills/create-gsd-extension → dist/resources/skills/create-lsd-extension}/SKILL.md +6 -6
- package/{src/resources/skills/create-gsd-extension → dist/resources/skills/create-lsd-extension}/references/custom-tools.md +1 -1
- package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extension-lifecycle.md +2 -2
- package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensioncontext-reference.md +1 -1
- package/{src/resources/skills/create-gsd-extension → dist/resources/skills/create-lsd-extension}/references/key-rules-gotchas.md +4 -4
- package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/packaging-distribution.md +6 -6
- package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/create-extension.md +3 -3
- package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/debug-extension.md +5 -5
- package/dist/resources/skills/teams-debug/SKILL.md +5 -6
- package/dist/resources/skills/teams-document/SKILL.md +1 -2
- package/dist/resources/skills/teams-plan/SKILL.md +3 -4
- package/dist/resources/skills/teams-run/SKILL.md +3 -4
- package/dist/resources/skills/teams-verify/SKILL.md +4 -5
- package/dist/startup-model-validation.js +1 -0
- package/dist/welcome-screen.js +13 -11
- package/dist/wizard.js +12 -0
- package/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +688 -409
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +761 -488
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +40 -18
- package/packages/pi-ai/src/models.generated.ts +759 -486
- package/packages/pi-coding-agent/dist/cli/config-selector.js +1 -1
- package/packages/pi-coding-agent/dist/cli/config-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -2
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +6 -30
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +44 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +9 -5
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +3 -2
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +1 -1
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +15 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +10 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +31 -22
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +18 -5
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +139 -20
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/cli/config-selector.ts +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +5 -28
- package/packages/pi-coding-agent/src/core/settings-manager.ts +52 -1
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +18 -5
- package/packages/pi-coding-agent/src/core/skills.ts +3 -2
- package/packages/pi-coding-agent/src/index.ts +1 -1
- package/packages/pi-coding-agent/src/main.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +12 -13
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +39 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +46 -20
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +171 -20
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -0
- package/packages/pi-tui/dist/components/editor.d.ts +1 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +23 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/src/components/editor.ts +23 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts +18 -5
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +139 -20
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +4 -0
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/memory/auto-extract.ts +23 -3
- package/src/resources/extensions/memory/dream.ts +814 -0
- package/src/resources/extensions/memory/extension-manifest.json +2 -2
- package/src/resources/extensions/memory/index.ts +134 -13
- package/src/resources/extensions/memory/tests/auto-extract.test.ts +10 -2
- package/src/resources/extensions/memory/tests/dream.test.ts +142 -0
- package/src/resources/extensions/slash-commands/extension-manifest.json +10 -10
- package/src/resources/extensions/slash-commands/index.ts +3 -7
- package/src/resources/extensions/slash-commands/plan.ts +192 -46
- package/src/resources/extensions/subagent/agents.ts +11 -1
- package/src/resources/extensions/subagent/configured-model.ts +3 -2
- package/src/resources/extensions/subagent/index.ts +38 -30
- package/src/resources/extensions/subagent/launch-helpers.ts +30 -0
- package/src/resources/extensions/subagent/model-resolution.ts +40 -3
- package/src/resources/extensions/usage/extension-manifest.json +11 -0
- package/src/resources/extensions/usage/index.ts +441 -0
- package/{dist/resources/skills/create-gsd-extension → src/resources/skills/create-lsd-extension}/SKILL.md +6 -6
- package/{dist/resources/skills/create-gsd-extension → src/resources/skills/create-lsd-extension}/references/custom-tools.md +1 -1
- package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extension-lifecycle.md +2 -2
- package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensioncontext-reference.md +1 -1
- package/{dist/resources/skills/create-gsd-extension → src/resources/skills/create-lsd-extension}/references/key-rules-gotchas.md +4 -4
- package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/packaging-distribution.md +6 -6
- package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/create-extension.md +3 -3
- package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/debug-extension.md +5 -5
- package/src/resources/skills/teams-debug/SKILL.md +5 -6
- package/src/resources/skills/teams-document/SKILL.md +1 -2
- package/src/resources/skills/teams-plan/SKILL.md +3 -4
- package/src/resources/skills/teams-run/SKILL.md +3 -4
- package/src/resources/skills/teams-verify/SKILL.md +4 -5
- package/dist/resources/extensions/slash-commands/create-extension.js +0 -264
- package/dist/resources/extensions/slash-commands/create-slash-command.js +0 -208
- package/src/resources/extensions/slash-commands/create-extension.ts +0 -297
- package/src/resources/extensions/slash-commands/create-slash-command.ts +0 -234
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/compaction-session-control.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-commands.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-rendering.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-ui.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/events-reference.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensionapi-reference.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/mode-behavior.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/model-provider-management.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/remote-execution-overrides.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/state-management.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/references/system-prompt-modification.md +0 -0
- /package/dist/resources/skills/{create-gsd-extension → create-lsd-extension}/workflows/add-capability.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/compaction-session-control.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-commands.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-rendering.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/custom-ui.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/events-reference.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/extensionapi-reference.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/mode-behavior.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/model-provider-management.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/remote-execution-overrides.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/state-management.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/references/system-prompt-modification.md +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/templates/extension-skeleton.ts +0 -0
- /package/src/resources/skills/{create-gsd-extension → create-lsd-extension}/templates/stateful-tool-skeleton.ts +0 -0
- /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
|
|
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
|
|
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
|
|
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
|
|
153
|
-
* /remember
|
|
154
|
-
* /forget
|
|
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
|
|
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,
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
clearCommand(pi);
|
|
13
|
-
planCommand(pi);
|
|
7
|
+
auditCommand(pi);
|
|
8
|
+
clearCommand(pi);
|
|
9
|
+
planCommand(pi);
|
|
14
10
|
}
|