@slope-dev/slope 1.53.0 → 1.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/agent.d.ts +35 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +345 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/briefing.d.ts.map +1 -1
- package/dist/cli/commands/briefing.js +5 -3
- package/dist/cli/commands/briefing.js.map +1 -1
- package/dist/cli/commands/commit-ready.d.ts +29 -0
- package/dist/cli/commands/commit-ready.d.ts.map +1 -0
- package/dist/cli/commands/commit-ready.js +263 -0
- package/dist/cli/commands/commit-ready.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +97 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/gate.d.ts +2 -0
- package/dist/cli/commands/gate.d.ts.map +1 -0
- package/dist/cli/commands/gate.js +175 -0
- package/dist/cli/commands/gate.js.map +1 -0
- package/dist/cli/commands/guard.d.ts.map +1 -1
- package/dist/cli/commands/guard.js +4 -0
- package/dist/cli/commands/guard.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +23 -6
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/pr.d.ts +49 -0
- package/dist/cli/commands/pr.d.ts.map +1 -0
- package/dist/cli/commands/pr.js +214 -0
- package/dist/cli/commands/pr.js.map +1 -0
- package/dist/cli/commands/review-state.d.ts +1 -2
- package/dist/cli/commands/review-state.d.ts.map +1 -1
- package/dist/cli/commands/review-state.js +71 -25
- package/dist/cli/commands/review-state.js.map +1 -1
- package/dist/cli/commands/roadmap.d.ts.map +1 -1
- package/dist/cli/commands/roadmap.js +31 -4
- package/dist/cli/commands/roadmap.js.map +1 -1
- package/dist/cli/commands/sprint-plan.d.ts +21 -0
- package/dist/cli/commands/sprint-plan.d.ts.map +1 -0
- package/dist/cli/commands/sprint-plan.js +226 -0
- package/dist/cli/commands/sprint-plan.js.map +1 -0
- package/dist/cli/commands/sprint.d.ts.map +1 -1
- package/dist/cli/commands/sprint.js +137 -0
- package/dist/cli/commands/sprint.js.map +1 -1
- package/dist/cli/commands/ticket.d.ts +9 -0
- package/dist/cli/commands/ticket.d.ts.map +1 -0
- package/dist/cli/commands/ticket.js +168 -0
- package/dist/cli/commands/ticket.js.map +1 -0
- package/dist/cli/commands/version.d.ts.map +1 -1
- package/dist/cli/commands/version.js +33 -4
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/cli/commands/vision.d.ts.map +1 -1
- package/dist/cli/commands/vision.js +14 -1
- package/dist/cli/commands/vision.js.map +1 -1
- package/dist/cli/guards/branch-before-commit.d.ts.map +1 -1
- package/dist/cli/guards/branch-before-commit.js +2 -1
- package/dist/cli/guards/branch-before-commit.js.map +1 -1
- package/dist/cli/guards/next-action.d.ts.map +1 -1
- package/dist/cli/guards/next-action.js +3 -2
- package/dist/cli/guards/next-action.js.map +1 -1
- package/dist/cli/guards/post-hole-enforcement.d.ts +18 -0
- package/dist/cli/guards/post-hole-enforcement.d.ts.map +1 -0
- package/dist/cli/guards/post-hole-enforcement.js +100 -0
- package/dist/cli/guards/post-hole-enforcement.js.map +1 -0
- package/dist/cli/guards/pr-review.d.ts +16 -1
- package/dist/cli/guards/pr-review.d.ts.map +1 -1
- package/dist/cli/guards/pr-review.js +87 -5
- package/dist/cli/guards/pr-review.js.map +1 -1
- package/dist/cli/guards/roadmap-edit-shipped.d.ts +12 -0
- package/dist/cli/guards/roadmap-edit-shipped.d.ts.map +1 -0
- package/dist/cli/guards/roadmap-edit-shipped.js +155 -0
- package/dist/cli/guards/roadmap-edit-shipped.js.map +1 -0
- package/dist/cli/index.js +40 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/registry.d.ts +1 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/registry.js +57 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/core/analyzers/git.d.ts +14 -0
- package/dist/core/analyzers/git.d.ts.map +1 -1
- package/dist/core/analyzers/git.js +47 -0
- package/dist/core/analyzers/git.js.map +1 -1
- package/dist/core/formatter.d.ts.map +1 -1
- package/dist/core/formatter.js +51 -2
- package/dist/core/formatter.js.map +1 -1
- package/dist/core/guard.d.ts +1 -1
- package/dist/core/guard.d.ts.map +1 -1
- package/dist/core/guard.js +16 -0
- package/dist/core/guard.js.map +1 -1
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/json-memory-backend.d.ts +23 -0
- package/dist/core/json-memory-backend.d.ts.map +1 -0
- package/dist/core/json-memory-backend.js +98 -0
- package/dist/core/json-memory-backend.js.map +1 -0
- package/dist/core/memory-backend.d.ts +30 -0
- package/dist/core/memory-backend.d.ts.map +1 -0
- package/dist/core/memory-backend.js +14 -0
- package/dist/core/memory-backend.js.map +1 -0
- package/dist/core/memory-types.d.ts +25 -0
- package/dist/core/memory-types.d.ts.map +1 -0
- package/dist/core/memory-types.js +4 -0
- package/dist/core/memory-types.js.map +1 -0
- package/dist/core/memory-validation.d.ts +4 -0
- package/dist/core/memory-validation.d.ts.map +1 -0
- package/dist/core/memory-validation.js +35 -0
- package/dist/core/memory-validation.js.map +1 -0
- package/dist/core/memory.d.ts +21 -37
- package/dist/core/memory.d.ts.map +1 -1
- package/dist/core/memory.js +97 -147
- package/dist/core/memory.js.map +1 -1
- package/dist/core/pi-settings.d.ts.map +1 -1
- package/dist/core/pi-settings.js +8 -0
- package/dist/core/pi-settings.js.map +1 -1
- package/dist/core/roadmap.d.ts +16 -2
- package/dist/core/roadmap.d.ts.map +1 -1
- package/dist/core/roadmap.js +81 -24
- package/dist/core/roadmap.js.map +1 -1
- package/dist/core/vision.d.ts +10 -0
- package/dist/core/vision.d.ts.map +1 -1
- package/dist/core/vision.js +68 -1
- package/dist/core/vision.js.map +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +18 -0
- package/dist/store/index.js.map +1 -1
- package/dist/store/sqlite-memory-backend.d.ts +43 -0
- package/dist/store/sqlite-memory-backend.d.ts.map +1 -0
- package/dist/store/sqlite-memory-backend.js +181 -0
- package/dist/store/sqlite-memory-backend.js.map +1 -0
- package/dist/store-pg/index.d.ts.map +1 -1
- package/dist/store-pg/index.js +23 -0
- package/dist/store-pg/index.js.map +1 -1
- package/package.json +1 -1
- package/packages/pi-extension/dist/index.d.ts +19 -0
- package/packages/pi-extension/dist/index.js +339 -15
package/dist/core/memory.js
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cross-session memory storage
|
|
3
|
-
*
|
|
2
|
+
* Cross-session memory storage — public API.
|
|
3
|
+
*
|
|
4
|
+
* As of S90 (GH #294), persistence routes through a MemoryBackend so the
|
|
5
|
+
* memory module no longer writes JSON directly. Behavior:
|
|
6
|
+
*
|
|
7
|
+
* - If `.slope/slope.db` exists, SqliteMemoryBackend is used. On first
|
|
8
|
+
* open it imports any existing `.slope/memories.json` into the store
|
|
9
|
+
* and renames the JSON to `.bak` (one-time migration).
|
|
10
|
+
* - Otherwise JsonMemoryBackend is used (legacy default for repos that
|
|
11
|
+
* haven't initialized the SQLite store).
|
|
12
|
+
*
|
|
13
|
+
* Public API signatures are unchanged — callers (auto-memory hooks, the
|
|
14
|
+
* memory CLI command, briefing) keep working without `await`.
|
|
4
15
|
*/
|
|
5
|
-
import { existsSync
|
|
16
|
+
import { existsSync } from 'node:fs';
|
|
6
17
|
import { randomUUID } from 'node:crypto';
|
|
7
18
|
import { join } from 'node:path';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
*/
|
|
19
|
+
import { JsonMemoryBackend } from './json-memory-backend.js';
|
|
20
|
+
import { SqliteMemoryBackend } from '../store/sqlite-memory-backend.js';
|
|
21
|
+
// Re-export validateMemory + secret detection helpers (still part of public API).
|
|
22
|
+
export { validateMemoryRow as validateMemory } from './memory-validation.js';
|
|
23
|
+
// ── Secret detection (unchanged from pre-S90) ──────────
|
|
16
24
|
const SECRET_PATTERNS = [
|
|
17
25
|
/\bsk-[A-Za-z0-9_-]{20,}\b/,
|
|
18
26
|
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/,
|
|
@@ -27,115 +35,74 @@ export function detectSecret(text) {
|
|
|
27
35
|
}
|
|
28
36
|
return null;
|
|
29
37
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
function generateId() {
|
|
38
|
-
return randomUUID();
|
|
38
|
+
export class SecretDetectedError extends Error {
|
|
39
|
+
pattern;
|
|
40
|
+
constructor(pattern) {
|
|
41
|
+
super(`Memory text matches secret pattern (${pattern}); refusing to persist. Pass allowSecrets:true to override.`);
|
|
42
|
+
this.pattern = pattern;
|
|
43
|
+
this.name = 'SecretDetectedError';
|
|
44
|
+
}
|
|
39
45
|
}
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
// ── Backend resolution ─────────────────────────────────
|
|
47
|
+
/**
|
|
48
|
+
* Pick a backend based on whether a SQLite slope.db exists. Lazy-load the
|
|
49
|
+
* SQLite backend so projects without better-sqlite3 binding (or no slope.db)
|
|
50
|
+
* never try to open one.
|
|
51
|
+
*
|
|
52
|
+
* Memoized per-cwd — repeated calls return the same instance to avoid the
|
|
53
|
+
* overhead of opening a fresh DB connection (and re-running schema/migration
|
|
54
|
+
* checks) on every memory operation. Tests can call `clearMemoryBackendCache()`
|
|
55
|
+
* to reset between fixtures.
|
|
56
|
+
*
|
|
57
|
+
* Override via `SLOPE_MEMORY_BACKEND=json|sqlite` for testing.
|
|
58
|
+
*/
|
|
59
|
+
const _backendCache = new Map();
|
|
60
|
+
export function clearMemoryBackendCache() {
|
|
61
|
+
_backendCache.clear();
|
|
42
62
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
export function getMemoryBackend(cwd) {
|
|
64
|
+
const override = process.env.SLOPE_MEMORY_BACKEND;
|
|
65
|
+
// Cache key includes the override so a test toggling the env between calls
|
|
66
|
+
// doesn't get a stale instance.
|
|
67
|
+
const cacheKey = `${cwd}::${override ?? 'auto'}`;
|
|
68
|
+
const cached = _backendCache.get(cacheKey);
|
|
69
|
+
if (cached)
|
|
70
|
+
return cached;
|
|
71
|
+
if (override === 'json') {
|
|
72
|
+
const b = new JsonMemoryBackend(cwd);
|
|
73
|
+
_backendCache.set(cacheKey, b);
|
|
74
|
+
return b;
|
|
54
75
|
}
|
|
55
|
-
|
|
56
|
-
|
|
76
|
+
const dbPath = join(cwd, '.slope', 'slope.db');
|
|
77
|
+
if (override === 'sqlite' || existsSync(dbPath)) {
|
|
78
|
+
try {
|
|
79
|
+
const b = new SqliteMemoryBackend(cwd, dbPath);
|
|
80
|
+
_backendCache.set(cacheKey, b);
|
|
81
|
+
return b;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
// Distinguish corruption / I/O errors from missing better-sqlite3
|
|
85
|
+
// binding so users can tell which layer is broken (#294 review).
|
|
86
|
+
const msg = err.message ?? String(err);
|
|
87
|
+
const cause = /better-sqlite3|cannot find module/i.test(msg)
|
|
88
|
+
? 'better-sqlite3 binding unavailable'
|
|
89
|
+
: 'SQLite open failed (DB corrupt, locked, or unreadable)';
|
|
90
|
+
console.error(`SLOPE memory: ${cause} — ${msg}; falling back to JSON.`);
|
|
91
|
+
}
|
|
57
92
|
}
|
|
58
|
-
const
|
|
59
|
-
|
|
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
|
-
};
|
|
93
|
+
const fallback = new JsonMemoryBackend(cwd);
|
|
94
|
+
_backendCache.set(cacheKey, fallback);
|
|
95
|
+
return fallback;
|
|
70
96
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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: [] };
|
|
97
|
+
// ── Public API ─────────────────────────────────────────
|
|
98
|
+
function nowISO() {
|
|
99
|
+
return new Date().toISOString();
|
|
83
100
|
}
|
|
84
|
-
// ── Public API ──────────────────────────────────────
|
|
85
101
|
export function loadMemories(cwd) {
|
|
86
|
-
|
|
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
|
-
}
|
|
102
|
+
return getMemoryBackend(cwd).load();
|
|
118
103
|
}
|
|
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
104
|
export function saveMemories(cwd, data) {
|
|
126
|
-
|
|
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
|
-
}
|
|
105
|
+
getMemoryBackend(cwd).saveAll(data);
|
|
139
106
|
}
|
|
140
107
|
export function addMemory(cwd, text, options = {}) {
|
|
141
108
|
if (!options.allowSecrets) {
|
|
@@ -143,54 +110,40 @@ export function addMemory(cwd, text, options = {}) {
|
|
|
143
110
|
if (matched)
|
|
144
111
|
throw new SecretDetectedError(matched);
|
|
145
112
|
}
|
|
146
|
-
const data = loadMemories(cwd);
|
|
147
113
|
const memory = {
|
|
148
|
-
id:
|
|
114
|
+
id: randomUUID(),
|
|
149
115
|
text,
|
|
150
116
|
category: options.category ?? 'other',
|
|
151
117
|
weight: Math.max(1, Math.min(10, options.weight ?? 8)),
|
|
152
118
|
source: options.source ?? 'manual',
|
|
153
|
-
createdAt:
|
|
154
|
-
updatedAt:
|
|
119
|
+
createdAt: nowISO(),
|
|
120
|
+
updatedAt: nowISO(),
|
|
155
121
|
...(options.sourceSessionId ? { sourceSessionId: options.sourceSessionId } : {}),
|
|
156
122
|
};
|
|
157
|
-
|
|
158
|
-
saveMemories(cwd, data);
|
|
123
|
+
getMemoryBackend(cwd).add(memory);
|
|
159
124
|
return memory;
|
|
160
125
|
}
|
|
161
126
|
export function removeMemory(cwd, id) {
|
|
162
|
-
|
|
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;
|
|
127
|
+
return getMemoryBackend(cwd).remove(id);
|
|
169
128
|
}
|
|
170
129
|
export function updateMemory(cwd, id, updates) {
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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;
|
|
130
|
+
const fields = { ...updates };
|
|
131
|
+
if (fields.weight !== undefined) {
|
|
132
|
+
fields.weight = Math.max(1, Math.min(10, fields.weight));
|
|
133
|
+
}
|
|
134
|
+
fields.updatedAt = nowISO();
|
|
135
|
+
return getMemoryBackend(cwd).update(id, fields);
|
|
184
136
|
}
|
|
185
137
|
export function searchMemories(cwd, options = {}) {
|
|
186
|
-
|
|
138
|
+
// searchMemories is read-mostly; load and filter in memory. Pushing the
|
|
139
|
+
// filter into SQL is a future optimization once we have realistic dataset
|
|
140
|
+
// sizes — current footprint is small (typical project has <50 memories).
|
|
141
|
+
const data = getMemoryBackend(cwd).load();
|
|
187
142
|
let results = data.memories;
|
|
188
|
-
if (options.category)
|
|
143
|
+
if (options.category)
|
|
189
144
|
results = results.filter(m => m.category === options.category);
|
|
190
|
-
|
|
191
|
-
if (options.source) {
|
|
145
|
+
if (options.source)
|
|
192
146
|
results = results.filter(m => m.source === options.source);
|
|
193
|
-
}
|
|
194
147
|
if (options.minWeight !== undefined) {
|
|
195
148
|
const min = options.minWeight;
|
|
196
149
|
results = results.filter(m => m.weight >= min);
|
|
@@ -199,19 +152,16 @@ export function searchMemories(cwd, options = {}) {
|
|
|
199
152
|
const q = options.query.toLowerCase();
|
|
200
153
|
results = results.filter(m => m.text.toLowerCase().includes(q));
|
|
201
154
|
}
|
|
202
|
-
// Sort by weight desc, then recency desc
|
|
203
155
|
results.sort((a, b) => {
|
|
204
156
|
if (b.weight !== a.weight)
|
|
205
157
|
return b.weight - a.weight;
|
|
206
158
|
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
|
207
159
|
});
|
|
208
|
-
if (options.limit)
|
|
160
|
+
if (options.limit)
|
|
209
161
|
results = results.slice(0, options.limit);
|
|
210
|
-
}
|
|
211
162
|
return results;
|
|
212
163
|
}
|
|
213
164
|
export function getMemoryById(cwd, id) {
|
|
214
|
-
|
|
215
|
-
return data.memories.find(m => m.id === id);
|
|
165
|
+
return getMemoryBackend(cwd).getById(id);
|
|
216
166
|
}
|
|
217
167
|
//# sourceMappingURL=memory.js.map
|
package/dist/core/memory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/core/memory.ts"],"names":[],"mappings":"AAAA
|
|
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;
|
|
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;AAkDD,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"}
|
package/dist/core/pi-settings.js
CHANGED
|
@@ -37,6 +37,14 @@ const DEFAULT_SETTINGS = {
|
|
|
37
37
|
enabled: true,
|
|
38
38
|
description: 'Cross-session memory: inject relevant memories into briefing, /slope-memory command',
|
|
39
39
|
},
|
|
40
|
+
'model-router': {
|
|
41
|
+
enabled: false,
|
|
42
|
+
description: 'Auto-switch between local/cloud models based on task complexity. Requires both local + cloud providers configured.',
|
|
43
|
+
},
|
|
44
|
+
'plan-gate': {
|
|
45
|
+
enabled: false,
|
|
46
|
+
description: 'Require a written plan or active sprint phase before destructive tool calls (write/edit/bash). Pairs with model-router local-planner tier.',
|
|
47
|
+
},
|
|
40
48
|
},
|
|
41
49
|
};
|
|
42
50
|
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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"}
|
package/dist/core/roadmap.d.ts
CHANGED
|
@@ -48,11 +48,13 @@ export interface RoadmapValidationResult {
|
|
|
48
48
|
warnings: RoadmapValidationWarning[];
|
|
49
49
|
}
|
|
50
50
|
/** Validate a roadmap definition for structural correctness.
|
|
51
|
-
* Optionally cross-check sprint status against scorecards
|
|
51
|
+
* Optionally cross-check sprint status against scorecards and/or shipped
|
|
52
|
+
* sprint commits on main when provided. Caller is responsible for collecting
|
|
53
|
+
* scorecards (via loadScorecards) and shipped IDs (via findShippedSprintsOnMain).
|
|
52
54
|
*/
|
|
53
55
|
export declare function validateRoadmap(roadmap: RoadmapDefinition, scorecards?: {
|
|
54
56
|
sprint_number: number;
|
|
55
|
-
}[]): RoadmapValidationResult;
|
|
57
|
+
}[], shippedSprintIds?: Set<number>): RoadmapValidationResult;
|
|
56
58
|
export interface CriticalPathResult {
|
|
57
59
|
path: number[];
|
|
58
60
|
length: number;
|
|
@@ -66,6 +68,12 @@ export interface ParallelGroup {
|
|
|
66
68
|
}
|
|
67
69
|
/** Find sprints that can run in parallel (no mutual dependencies) */
|
|
68
70
|
export declare function findParallelOpportunities(roadmap: RoadmapDefinition): ParallelGroup[];
|
|
71
|
+
/** Cast a raw JSON object to RoadmapDefinition if minimally structurally valid.
|
|
72
|
+
* Unlike parseRoadmap, this does not run full validation — useful when callers
|
|
73
|
+
* want to flag validation issues against a structurally-cast roadmap (e.g.
|
|
74
|
+
* drift detection should still run when ticket counts or numbering are off).
|
|
75
|
+
*/
|
|
76
|
+
export declare function castRoadmapStructure(json: unknown): RoadmapDefinition | null;
|
|
69
77
|
/** Parse and validate a roadmap from a JSON object */
|
|
70
78
|
export declare function parseRoadmap(json: unknown): {
|
|
71
79
|
roadmap: RoadmapDefinition | null;
|
|
@@ -75,4 +83,10 @@ export declare function parseRoadmap(json: unknown): {
|
|
|
75
83
|
export declare function formatRoadmapSummary(roadmap: RoadmapDefinition): string;
|
|
76
84
|
/** Format strategic context for briefings — concise 3-5 line summary */
|
|
77
85
|
export declare function formatStrategicContext(roadmap: RoadmapDefinition, currentSprint: number): string | null;
|
|
86
|
+
/** Find the next planned sprint after currentSprint.
|
|
87
|
+
* Prefers a sprint with all dependencies satisfied (status:complete);
|
|
88
|
+
* falls back to the lowest-id non-complete sprint when nothing is unblocked.
|
|
89
|
+
* Returns null if no candidate found.
|
|
90
|
+
*/
|
|
91
|
+
export declare function findNextPlannedSprint(roadmap: RoadmapDefinition, currentSprint: number): RoadmapSprint | null;
|
|
78
92
|
//# sourceMappingURL=roadmap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roadmap.d.ts","sourceRoot":"","sources":["../../src/core/roadmap.ts"],"names":[],"mappings":"AAKA,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErF,sCAAsC;AACtC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,mCAAmC;AACnC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAID,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACjC,QAAQ,EAAE,wBAAwB,EAAE,CAAC;CACtC;AAED
|
|
1
|
+
{"version":3,"file":"roadmap.d.ts","sourceRoot":"","sources":["../../src/core/roadmap.ts"],"names":[],"mappings":"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"}
|
package/dist/core/roadmap.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// SLOPE — Roadmap: Strategic planning types and compute functions
|
|
2
2
|
// Course-level methodology — vision → roadmap → review → iteration
|
|
3
3
|
/** Validate a roadmap definition for structural correctness.
|
|
4
|
-
* Optionally cross-check sprint status against scorecards
|
|
4
|
+
* Optionally cross-check sprint status against scorecards and/or shipped
|
|
5
|
+
* sprint commits on main when provided. Caller is responsible for collecting
|
|
6
|
+
* scorecards (via loadScorecards) and shipped IDs (via findShippedSprintsOnMain).
|
|
5
7
|
*/
|
|
6
|
-
export function validateRoadmap(roadmap, scorecards) {
|
|
8
|
+
export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
|
|
7
9
|
const errors = [];
|
|
8
10
|
const warnings = [];
|
|
9
11
|
const sprintIds = new Set(roadmap.sprints.map(s => s.id));
|
|
@@ -129,6 +131,27 @@ export function validateRoadmap(roadmap, scorecards) {
|
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
}
|
|
134
|
+
// Cross-validate sprint status against shipped commits on main when provided
|
|
135
|
+
if (shippedSprintIds) {
|
|
136
|
+
for (const sprint of roadmap.sprints) {
|
|
137
|
+
const status = sprint.status;
|
|
138
|
+
const isShipped = shippedSprintIds.has(sprint.id);
|
|
139
|
+
if (isShipped && status !== 'complete') {
|
|
140
|
+
errors.push({
|
|
141
|
+
type: 'error',
|
|
142
|
+
sprint: sprint.id,
|
|
143
|
+
message: `S${sprint.id} has shipped commits on main but status is "${status ?? 'planned'}" — expected "complete"`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (!isShipped && status === 'complete') {
|
|
147
|
+
warnings.push({
|
|
148
|
+
type: 'warning',
|
|
149
|
+
sprint: sprint.id,
|
|
150
|
+
message: `S${sprint.id} is marked "complete" but no shipped commits found on main`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
132
155
|
return { valid: errors.length === 0, errors, warnings };
|
|
133
156
|
}
|
|
134
157
|
// --- Dependency Graph ---
|
|
@@ -285,51 +308,51 @@ function computeDepthMap(sprints) {
|
|
|
285
308
|
return depthMap;
|
|
286
309
|
}
|
|
287
310
|
// --- Parse ---
|
|
311
|
+
/** Cast a raw JSON object to RoadmapDefinition if minimally structurally valid.
|
|
312
|
+
* Unlike parseRoadmap, this does not run full validation — useful when callers
|
|
313
|
+
* want to flag validation issues against a structurally-cast roadmap (e.g.
|
|
314
|
+
* drift detection should still run when ticket counts or numbering are off).
|
|
315
|
+
*/
|
|
316
|
+
export function castRoadmapStructure(json) {
|
|
317
|
+
if (!json || typeof json !== 'object')
|
|
318
|
+
return null;
|
|
319
|
+
const obj = json;
|
|
320
|
+
if (typeof obj.name !== 'string')
|
|
321
|
+
return null;
|
|
322
|
+
if (!Array.isArray(obj.sprints))
|
|
323
|
+
return null;
|
|
324
|
+
if (!Array.isArray(obj.phases))
|
|
325
|
+
return null;
|
|
326
|
+
return obj;
|
|
327
|
+
}
|
|
288
328
|
/** Parse and validate a roadmap from a JSON object */
|
|
289
329
|
export function parseRoadmap(json) {
|
|
290
|
-
// Type guard: check minimal structure
|
|
330
|
+
// Type guard: check minimal structure with explicit per-field error messages
|
|
291
331
|
if (!json || typeof json !== 'object') {
|
|
292
332
|
return {
|
|
293
333
|
roadmap: null,
|
|
294
|
-
validation: {
|
|
295
|
-
valid: false,
|
|
296
|
-
errors: [{ type: 'error', message: 'Input is not an object' }],
|
|
297
|
-
warnings: [],
|
|
298
|
-
},
|
|
334
|
+
validation: { valid: false, errors: [{ type: 'error', message: 'Input is not an object' }], warnings: [] },
|
|
299
335
|
};
|
|
300
336
|
}
|
|
301
337
|
const obj = json;
|
|
302
338
|
if (typeof obj.name !== 'string') {
|
|
303
339
|
return {
|
|
304
340
|
roadmap: null,
|
|
305
|
-
validation: {
|
|
306
|
-
valid: false,
|
|
307
|
-
errors: [{ type: 'error', message: 'Missing required field: name' }],
|
|
308
|
-
warnings: [],
|
|
309
|
-
},
|
|
341
|
+
validation: { valid: false, errors: [{ type: 'error', message: 'Missing required field: name' }], warnings: [] },
|
|
310
342
|
};
|
|
311
343
|
}
|
|
312
344
|
if (!Array.isArray(obj.sprints)) {
|
|
313
345
|
return {
|
|
314
346
|
roadmap: null,
|
|
315
|
-
validation: {
|
|
316
|
-
valid: false,
|
|
317
|
-
errors: [{ type: 'error', message: 'Missing required field: sprints (must be an array)' }],
|
|
318
|
-
warnings: [],
|
|
319
|
-
},
|
|
347
|
+
validation: { valid: false, errors: [{ type: 'error', message: 'Missing required field: sprints (must be an array)' }], warnings: [] },
|
|
320
348
|
};
|
|
321
349
|
}
|
|
322
350
|
if (!Array.isArray(obj.phases)) {
|
|
323
351
|
return {
|
|
324
352
|
roadmap: null,
|
|
325
|
-
validation: {
|
|
326
|
-
valid: false,
|
|
327
|
-
errors: [{ type: 'error', message: 'Missing required field: phases (must be an array)' }],
|
|
328
|
-
warnings: [],
|
|
329
|
-
},
|
|
353
|
+
validation: { valid: false, errors: [{ type: 'error', message: 'Missing required field: phases (must be an array)' }], warnings: [] },
|
|
330
354
|
};
|
|
331
355
|
}
|
|
332
|
-
// Cast — validateRoadmap will catch structural issues in sprint/ticket fields
|
|
333
356
|
const roadmap = obj;
|
|
334
357
|
const validation = validateRoadmap(roadmap);
|
|
335
358
|
return { roadmap: validation.valid ? roadmap : null, validation };
|
|
@@ -409,6 +432,40 @@ export function formatStrategicContext(roadmap, currentSprint) {
|
|
|
409
432
|
if (dependents.length > 0) {
|
|
410
433
|
lines.push(`Feeds into: ${dependents.join(', ')}`);
|
|
411
434
|
}
|
|
435
|
+
// Next planned sprint (dependency-resolved) — see GH #290
|
|
436
|
+
const next = findNextPlannedSprint(roadmap, currentSprint);
|
|
437
|
+
if (next) {
|
|
438
|
+
const blockers = (next.depends_on ?? [])
|
|
439
|
+
.filter(d => {
|
|
440
|
+
const dep = roadmap.sprints.find(s => s.id === d);
|
|
441
|
+
return !dep || dep.status !== 'complete';
|
|
442
|
+
});
|
|
443
|
+
const status = blockers.length === 0
|
|
444
|
+
? 'ready'
|
|
445
|
+
: `blocked by ${blockers.map(b => `S${b}`).join(', ')}`;
|
|
446
|
+
lines.push(`Next: S${next.id}: ${next.theme} (${status})`);
|
|
447
|
+
}
|
|
412
448
|
return lines.join('\n');
|
|
413
449
|
}
|
|
450
|
+
/** Find the next planned sprint after currentSprint.
|
|
451
|
+
* Prefers a sprint with all dependencies satisfied (status:complete);
|
|
452
|
+
* falls back to the lowest-id non-complete sprint when nothing is unblocked.
|
|
453
|
+
* Returns null if no candidate found.
|
|
454
|
+
*/
|
|
455
|
+
export function findNextPlannedSprint(roadmap, currentSprint) {
|
|
456
|
+
const candidates = roadmap.sprints
|
|
457
|
+
.filter(s => {
|
|
458
|
+
const status = s.status;
|
|
459
|
+
return status !== 'complete' && s.id > currentSprint;
|
|
460
|
+
})
|
|
461
|
+
.sort((a, b) => a.id - b.id);
|
|
462
|
+
if (candidates.length === 0)
|
|
463
|
+
return null;
|
|
464
|
+
const completedIds = new Set(roadmap.sprints
|
|
465
|
+
.filter(s => s.status === 'complete')
|
|
466
|
+
.map(s => s.id));
|
|
467
|
+
// Prefer the lowest-id candidate whose dependencies are all complete
|
|
468
|
+
const ready = candidates.find(s => (s.depends_on ?? []).every(d => completedIds.has(d)));
|
|
469
|
+
return ready ?? candidates[0];
|
|
470
|
+
}
|
|
414
471
|
//# sourceMappingURL=roadmap.js.map
|