@slope-dev/slope 1.52.0 → 1.53.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 (36) hide show
  1. package/dist/cli/commands/memory.d.ts +14 -0
  2. package/dist/cli/commands/memory.d.ts.map +1 -0
  3. package/dist/cli/commands/memory.js +230 -0
  4. package/dist/cli/commands/memory.js.map +1 -0
  5. package/dist/cli/commands/review-state.d.ts.map +1 -1
  6. package/dist/cli/commands/review-state.js +9 -1
  7. package/dist/cli/commands/review-state.js.map +1 -1
  8. package/dist/cli/guards/claim-required.d.ts +6 -0
  9. package/dist/cli/guards/claim-required.d.ts.map +1 -1
  10. package/dist/cli/guards/claim-required.js +13 -3
  11. package/dist/cli/guards/claim-required.js.map +1 -1
  12. package/dist/cli/index.js +7 -0
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/cli/registry.d.ts.map +1 -1
  15. package/dist/cli/registry.js +21 -0
  16. package/dist/cli/registry.js.map +1 -1
  17. package/dist/core/auto-memory.d.ts +19 -0
  18. package/dist/core/auto-memory.d.ts.map +1 -0
  19. package/dist/core/auto-memory.js +142 -0
  20. package/dist/core/auto-memory.js.map +1 -0
  21. package/dist/core/index.d.ts +3 -0
  22. package/dist/core/index.d.ts.map +1 -1
  23. package/dist/core/index.js +4 -0
  24. package/dist/core/index.js.map +1 -1
  25. package/dist/core/memory.d.ts +57 -0
  26. package/dist/core/memory.d.ts.map +1 -0
  27. package/dist/core/memory.js +217 -0
  28. package/dist/core/memory.js.map +1 -0
  29. package/dist/core/pi-settings.d.ts.map +1 -1
  30. package/dist/core/pi-settings.js +4 -0
  31. package/dist/core/pi-settings.js.map +1 -1
  32. package/dist/core/review.d.ts.map +1 -1
  33. package/dist/core/review.js +5 -0
  34. package/dist/core/review.js.map +1 -1
  35. package/package.json +1 -1
  36. package/packages/pi-extension/dist/index.js +96 -2
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Cross-session memory storage core.
3
+ * Persistent learned patterns, preferences, and project quirks in .slope/memories.json
4
+ */
5
+ import { existsSync, readFileSync, writeFileSync, renameSync, copyFileSync, mkdirSync } from 'node:fs';
6
+ import { randomUUID } from 'node:crypto';
7
+ import { join } from 'node:path';
8
+ /**
9
+ * Detect probable secrets in a memory's text. Used as a guardrail before
10
+ * writing memories that auto-inject into briefings (S73-3).
11
+ *
12
+ * Detects: sk-* (OpenAI/Anthropic), ghp_* / gho_* (GitHub), AWS access keys
13
+ * (AKIA prefix + 16 chars), JWT-shaped 3-part dot-separated base64, and
14
+ * generic hex/base64 strings ≥ 32 chars after `password=`/`token=` etc.
15
+ */
16
+ const SECRET_PATTERNS = [
17
+ /\bsk-[A-Za-z0-9_-]{20,}\b/,
18
+ /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/,
19
+ /\bAKIA[0-9A-Z]{16}\b/,
20
+ /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/,
21
+ /\b(?:password|secret|token|api[-_]?key|access[-_]?key)\s*[:=]\s*['"]?[A-Za-z0-9+/=_-]{16,}['"]?/i,
22
+ ];
23
+ export function detectSecret(text) {
24
+ for (const re of SECRET_PATTERNS) {
25
+ if (re.test(text))
26
+ return re.source;
27
+ }
28
+ return null;
29
+ }
30
+ // ── Constants ───────────────────────────────────────
31
+ const MEMORIES_FILE = 'memories.json';
32
+ const CURRENT_VERSION = 1;
33
+ // ── Internal helpers ────────────────────────────────
34
+ function getPath(cwd) {
35
+ return join(cwd, '.slope', MEMORIES_FILE);
36
+ }
37
+ function generateId() {
38
+ return randomUUID();
39
+ }
40
+ function now() {
41
+ return new Date().toISOString();
42
+ }
43
+ function validateMemory(m) {
44
+ if (!m || typeof m !== 'object') {
45
+ throw new TypeError('Memory must be an object');
46
+ }
47
+ const mem = m;
48
+ const validCategories = ['workflow', 'style', 'project', 'hazard', 'other'];
49
+ const validSources = ['manual', 'auto-guard', 'auto-workflow'];
50
+ const category = mem.category ?? 'other';
51
+ const source = mem.source ?? 'manual';
52
+ if (!validCategories.includes(category)) {
53
+ throw new TypeError(`Invalid memory category: ${category}`);
54
+ }
55
+ if (!validSources.includes(source)) {
56
+ throw new TypeError(`Invalid memory source: ${source}`);
57
+ }
58
+ const weight = typeof mem.weight === 'number' ? mem.weight : 5;
59
+ const clampedWeight = Math.max(1, Math.min(10, weight));
60
+ return {
61
+ id: typeof mem.id === 'string' ? mem.id : generateId(),
62
+ text: typeof mem.text === 'string' ? mem.text : '',
63
+ category,
64
+ weight: clampedWeight,
65
+ source,
66
+ createdAt: typeof mem.createdAt === 'string' ? mem.createdAt : now(),
67
+ updatedAt: typeof mem.updatedAt === 'string' ? mem.updatedAt : now(),
68
+ ...(typeof mem.sourceSessionId === 'string' ? { sourceSessionId: mem.sourceSessionId } : {}),
69
+ };
70
+ }
71
+ /** Public for callers that want to validate before pushing (e.g. import). */
72
+ export { validateMemory };
73
+ function migrateV0toV1(raw) {
74
+ // v0: plain array of memories without version wrapper
75
+ if (Array.isArray(raw)) {
76
+ return {
77
+ version: 1,
78
+ memories: raw.map(validateMemory),
79
+ };
80
+ }
81
+ // Unknown shape — start fresh
82
+ return { version: 1, memories: [] };
83
+ }
84
+ // ── Public API ──────────────────────────────────────
85
+ export function loadMemories(cwd) {
86
+ const path = getPath(cwd);
87
+ if (!existsSync(path)) {
88
+ return { version: CURRENT_VERSION, memories: [] };
89
+ }
90
+ try {
91
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
92
+ if (raw && typeof raw === 'object' && 'version' in raw) {
93
+ const version = Number(raw.version);
94
+ if (version === 1) {
95
+ const memories = Array.isArray(raw.memories)
96
+ ? raw.memories.map(validateMemory)
97
+ : [];
98
+ return { version: CURRENT_VERSION, memories };
99
+ }
100
+ // Unknown future version — back up before returning empty so we don't silently nuke user data
101
+ const backupPath = `${path}.v${version}.bak`;
102
+ try {
103
+ copyFileSync(path, backupPath);
104
+ console.error(`SLOPE memory: unknown memories.json version=${version}; backed up to ${backupPath} and starting fresh.`);
105
+ }
106
+ catch (err) {
107
+ console.error(`SLOPE memory: unknown memories.json version=${version}; backup failed (${err.message}). Starting fresh — original file untouched until next write.`);
108
+ }
109
+ return { version: CURRENT_VERSION, memories: [] };
110
+ }
111
+ // No version field — try v0 migration
112
+ return migrateV0toV1(raw);
113
+ }
114
+ catch (err) {
115
+ console.error(`SLOPE memory: failed to parse ${path} (${err.message}). Treating as empty.`);
116
+ return { version: CURRENT_VERSION, memories: [] };
117
+ }
118
+ }
119
+ /**
120
+ * Atomic write: write to temp file then rename. Reduces (but doesn't eliminate)
121
+ * the multi-agent last-write-wins window — concurrent writers each load,
122
+ * mutate, and write, so the loser's changes can still be lost. A future
123
+ * follow-up should layer this on the store interface with proper locking.
124
+ */
125
+ export function saveMemories(cwd, data) {
126
+ const path = getPath(cwd);
127
+ mkdirSync(join(cwd, '.slope'), { recursive: true });
128
+ const tmp = `${path}.tmp.${process.pid}`;
129
+ writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n');
130
+ renameSync(tmp, path);
131
+ }
132
+ export class SecretDetectedError extends Error {
133
+ pattern;
134
+ constructor(pattern) {
135
+ super(`Memory text matches secret pattern (${pattern}); refusing to persist. Pass allowSecrets:true to override.`);
136
+ this.pattern = pattern;
137
+ this.name = 'SecretDetectedError';
138
+ }
139
+ }
140
+ export function addMemory(cwd, text, options = {}) {
141
+ if (!options.allowSecrets) {
142
+ const matched = detectSecret(text);
143
+ if (matched)
144
+ throw new SecretDetectedError(matched);
145
+ }
146
+ const data = loadMemories(cwd);
147
+ const memory = {
148
+ id: generateId(),
149
+ text,
150
+ category: options.category ?? 'other',
151
+ weight: Math.max(1, Math.min(10, options.weight ?? 8)),
152
+ source: options.source ?? 'manual',
153
+ createdAt: now(),
154
+ updatedAt: now(),
155
+ ...(options.sourceSessionId ? { sourceSessionId: options.sourceSessionId } : {}),
156
+ };
157
+ data.memories.push(memory);
158
+ saveMemories(cwd, data);
159
+ return memory;
160
+ }
161
+ export function removeMemory(cwd, id) {
162
+ const data = loadMemories(cwd);
163
+ const idx = data.memories.findIndex(m => m.id === id);
164
+ if (idx === -1)
165
+ return false;
166
+ data.memories.splice(idx, 1);
167
+ saveMemories(cwd, data);
168
+ return true;
169
+ }
170
+ export function updateMemory(cwd, id, updates) {
171
+ const data = loadMemories(cwd);
172
+ const mem = data.memories.find(m => m.id === id);
173
+ if (!mem)
174
+ return null;
175
+ if (updates.text !== undefined)
176
+ mem.text = updates.text;
177
+ if (updates.category !== undefined)
178
+ mem.category = updates.category;
179
+ if (updates.weight !== undefined)
180
+ mem.weight = Math.max(1, Math.min(10, updates.weight));
181
+ mem.updatedAt = now();
182
+ saveMemories(cwd, data);
183
+ return mem;
184
+ }
185
+ export function searchMemories(cwd, options = {}) {
186
+ const data = loadMemories(cwd);
187
+ let results = data.memories;
188
+ if (options.category) {
189
+ results = results.filter(m => m.category === options.category);
190
+ }
191
+ if (options.source) {
192
+ results = results.filter(m => m.source === options.source);
193
+ }
194
+ if (options.minWeight !== undefined) {
195
+ const min = options.minWeight;
196
+ results = results.filter(m => m.weight >= min);
197
+ }
198
+ if (options.query) {
199
+ const q = options.query.toLowerCase();
200
+ results = results.filter(m => m.text.toLowerCase().includes(q));
201
+ }
202
+ // Sort by weight desc, then recency desc
203
+ results.sort((a, b) => {
204
+ if (b.weight !== a.weight)
205
+ return b.weight - a.weight;
206
+ return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
207
+ });
208
+ if (options.limit) {
209
+ results = results.slice(0, options.limit);
210
+ }
211
+ return results;
212
+ }
213
+ export function getMemoryById(cwd, id) {
214
+ const data = loadMemories(cwd);
215
+ return data.memories.find(m => m.id === id);
216
+ }
217
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/core/memory.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pi-settings.d.ts","sourceRoot":"","sources":["../../src/core/pi-settings.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACxC;AAsCD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAetD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI,CAItE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAI/F;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,UAAU,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAM/G"}
1
+ {"version":3,"file":"pi-settings.d.ts","sourceRoot":"","sources":["../../src/core/pi-settings.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACxC;AA0CD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAetD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI,CAItE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAI/F;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,UAAU,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAM/G"}
@@ -33,6 +33,10 @@ const DEFAULT_SETTINGS = {
33
33
  enabled: false,
34
34
  description: 'Live performance dashboard (requires manual `slope dashboard` start)',
35
35
  },
36
+ memory: {
37
+ enabled: true,
38
+ description: 'Cross-session memory: inject relevant memories into briefing, /slope-memory command',
39
+ },
36
40
  },
37
41
  };
38
42
  const SETTINGS_FILE = '.slope/pi-settings.json';
@@ -1 +1 @@
1
- {"version":3,"file":"pi-settings.js","sourceRoot":"","sources":["../../src/core/pi-settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pi-settings.js","sourceRoot":"","sources":["../../src/core/pi-settings.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/core/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAC;AAOpB,4FAA4F;AAC5F,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,oBAAoB,EAAE,CA4DrF;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAOjE;AAID,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,KAAK,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,UAAU,CAAC;QACxB,QAAQ,EAAE,cAAc,CAAC;KAC1B,CAAC,CAAC;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,aAAa,EAAE,GACxB,WAAW,CAiEb"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/core/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAC;AAOpB,4FAA4F;AAC5F,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,oBAAoB,EAAE,CA4DrF;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAOjE;AAID,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,KAAK,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,UAAU,CAAC;QACxB,QAAQ,EAAE,cAAc,CAAC;KAC1B,CAAC,CAAC;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,aAAa,EAAE,GACxB,WAAW,CAyEb"}
@@ -82,6 +82,11 @@ export function findingToHazard(finding) {
82
82
  * Recomputes stats, score, and score_label via buildScorecard().
83
83
  */
84
84
  export function amendScorecardWithFindings(scorecard, findings) {
85
+ if (!Array.isArray(scorecard.shots)) {
86
+ throw new Error(`Scorecard for sprint ${scorecard.sprint_number} has no \`shots\` array — ` +
87
+ `likely a sub-sprint parent stub or malformed file. ` +
88
+ `Pass --sprint=<id> for the sub-sprint scorecard, or check the on-disk file.`);
89
+ }
85
90
  const scoreBefore = scorecard.score;
86
91
  const labelBefore = scorecard.score_label;
87
92
  const amendments = [];
@@ -1 +1 @@
1
- {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/core/review.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/core/review.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slope-dev/slope",
3
- "version": "1.52.0",
3
+ "version": "1.53.0",
4
4
  "description": "Quantified sprint metrics for AI-assisted development. Scorecards, handicap tracking, and real-time agent guidance for Claude Code, Cursor, Windsurf, Cline, and OpenCode.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -8,7 +8,7 @@ import { execSync } from 'node:child_process';
8
8
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
10
  import { Type } from '@sinclair/typebox';
11
- import { InterviewStateMachine, buildInterviewContext, generateInterviewSteps, initFromAnswers, loadPiSettings, savePiSettings, isSkillEnabled, setSkillEnabled, listSkills, } from '@slope-dev/slope';
11
+ import { InterviewStateMachine, buildInterviewContext, generateInterviewSteps, initFromAnswers, loadPiSettings, savePiSettings, isSkillEnabled, setSkillEnabled, listSkills, searchMemories, addMemory, removeMemory, } from '@slope-dev/slope';
12
12
  // ── Helpers ─────────────────────────────────────────
13
13
  function slopeCmd(args, cwd) {
14
14
  try {
@@ -257,6 +257,57 @@ export default function slopeExtension(pi, _cwdOverride) {
257
257
  },
258
258
  });
259
259
  } // end review skill
260
+ if (isSkillEnabled(settings, 'memory')) {
261
+ pi.registerTool({
262
+ name: 'slope_memory',
263
+ label: 'Slope Memory',
264
+ description: 'List, add, search, or remove cross-session memories stored in .slope/memories.json',
265
+ parameters: Type.Object({
266
+ action: Type.Union([Type.Literal('list'), Type.Literal('add'), Type.Literal('search'), Type.Literal('remove')], { description: 'Memory action' }),
267
+ text: Type.Optional(Type.String({ description: 'Memory text (for add)' })),
268
+ query: Type.Optional(Type.String({ description: 'Search query (for search)' })),
269
+ id: Type.Optional(Type.String({ description: 'Memory ID (for remove)' })),
270
+ category: Type.Optional(Type.String({ description: 'Category filter' })),
271
+ limit: Type.Optional(Type.Number({ description: 'Max results' })),
272
+ }),
273
+ async execute(_id, params, _signal, _update, ctx) {
274
+ switch (params.action) {
275
+ case 'list': {
276
+ const results = searchMemories(ctx.cwd, {
277
+ category: params.category,
278
+ limit: params.limit ?? 10,
279
+ });
280
+ const lines = results.map(m => `[${m.category}] w:${m.weight} ${m.text.slice(0, 80)}`);
281
+ return { content: [{ type: 'text', text: lines.join('\n') || 'No memories.' }], details: {} };
282
+ }
283
+ case 'add': {
284
+ if (!params.text)
285
+ return { content: [{ type: 'text', text: 'Error: text required for add' }], details: {} };
286
+ const mem = addMemory(ctx.cwd, params.text, {
287
+ category: params.category,
288
+ source: 'manual',
289
+ });
290
+ return { content: [{ type: 'text', text: `Added: ${mem.id.slice(0, 12)}… [${mem.category}]` }], details: {} };
291
+ }
292
+ case 'search': {
293
+ const results = searchMemories(ctx.cwd, {
294
+ query: params.query,
295
+ category: params.category,
296
+ limit: params.limit ?? 10,
297
+ });
298
+ const lines = results.map(m => `[${m.category}] w:${m.weight} ${m.text.slice(0, 80)}`);
299
+ return { content: [{ type: 'text', text: lines.join('\n') || 'No memories found.' }], details: {} };
300
+ }
301
+ case 'remove': {
302
+ if (!params.id)
303
+ return { content: [{ type: 'text', text: 'Error: id required for remove' }], details: {} };
304
+ const ok = removeMemory(ctx.cwd, params.id);
305
+ return { content: [{ type: 'text', text: ok ? 'Removed.' : 'Memory not found.' }], details: {} };
306
+ }
307
+ }
308
+ },
309
+ });
310
+ } // end memory skill
260
311
  if (isSkillEnabled(settings, 'guards')) {
261
312
  pi.registerTool({
262
313
  name: 'slope_guard_metrics',
@@ -364,6 +415,38 @@ export default function slopeExtension(pi, _cwdOverride) {
364
415
  ctx.ui.notify(output, 'info');
365
416
  },
366
417
  });
418
+ if (isSkillEnabled(settings, 'memory')) {
419
+ pi.registerCommand('slope-memory', {
420
+ description: 'List or add cross-session memories',
421
+ handler: async (args, ctx) => {
422
+ const tokens = (args ?? '').trim().split(/\s+/).filter(Boolean);
423
+ const sub = tokens[0];
424
+ if (sub === 'add') {
425
+ const text = tokens.slice(1).join(' ').trim();
426
+ if (!text) {
427
+ ctx.ui.notify('Usage: /slope-memory add <text>', 'info');
428
+ return;
429
+ }
430
+ try {
431
+ const mem = addMemory(ctx.cwd, text, { source: 'manual' });
432
+ ctx.ui.notify(`Memory added: ${mem.id.slice(0, 12)}…`, 'info');
433
+ }
434
+ catch (err) {
435
+ ctx.ui.notify(`Memory not added: ${err.message}`, 'warning');
436
+ }
437
+ }
438
+ else {
439
+ const results = searchMemories(ctx.cwd, { limit: 10 });
440
+ if (results.length === 0) {
441
+ ctx.ui.notify('No memories stored.', 'info');
442
+ return;
443
+ }
444
+ const lines = results.map(m => `[${m.category}] w:${m.weight} ${m.text.slice(0, 60)}`);
445
+ ctx.ui.notify(`Memories:\n${lines.join('\n')}`, 'info');
446
+ }
447
+ },
448
+ });
449
+ } // end memory slash command
367
450
  // Settings command
368
451
  registerSettingsCommand(pi, settings, cwd);
369
452
  // ── Session Start: Inject Briefing on First Turn ──
@@ -447,10 +530,21 @@ export default function slopeExtension(pi, _cwdOverride) {
447
530
  },
448
531
  };
449
532
  }
533
+ // Inject top memories if memory skill is enabled
534
+ let memoryContext = '';
535
+ if (isSkillEnabled(settings, 'memory')) {
536
+ try {
537
+ const memories = searchMemories(ctx.cwd, { limit: 5, minWeight: 5 });
538
+ if (memories.length > 0) {
539
+ memoryContext = '\n\n📌 Relevant Memories:\n' + memories.map(m => ` • [${m.category}] ${m.text.slice(0, 100)}`).join('\n');
540
+ }
541
+ }
542
+ catch { /* ignore memory errors */ }
543
+ }
450
544
  return {
451
545
  message: {
452
546
  customType: 'slope-briefing',
453
- content: `SLOPE Session Briefing:\n${briefing}`,
547
+ content: `SLOPE Session Briefing:\n${briefing}${memoryContext}`,
454
548
  display: true,
455
549
  },
456
550
  };