@aipper/aiws 0.0.44 → 0.0.46
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.js +162 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/goal-advance.d.ts +20 -0
- package/dist/commands/goal-advance.js +112 -0
- package/dist/commands/goal-advance.js.map +1 -0
- package/dist/commands/goal-help.d.ts +1 -0
- package/dist/commands/goal-help.js +28 -0
- package/dist/commands/goal-help.js.map +1 -0
- package/dist/commands/goal-validate-state.d.ts +92 -0
- package/dist/commands/goal-validate-state.js +371 -0
- package/dist/commands/goal-validate-state.js.map +1 -0
- package/dist/commands/goal-validate.d.ts +16 -0
- package/dist/commands/goal-validate.js +100 -0
- package/dist/commands/goal-validate.js.map +1 -0
- package/dist/commands/memory.d.ts +35 -0
- package/dist/commands/memory.js +239 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/memory-bank/disclosure.d.ts +24 -0
- package/dist/memory-bank/disclosure.js +143 -0
- package/dist/memory-bank/disclosure.js.map +1 -0
- package/dist/memory-bank/index.d.ts +24 -0
- package/dist/memory-bank/index.js +137 -0
- package/dist/memory-bank/index.js.map +1 -0
- package/dist/memory-bank/link.d.ts +21 -0
- package/dist/memory-bank/link.js +113 -0
- package/dist/memory-bank/link.js.map +1 -0
- package/dist/memory-bank/search.d.ts +6 -0
- package/dist/memory-bank/search.js +88 -0
- package/dist/memory-bank/search.js.map +1 -0
- package/dist/memory-bank/seed.d.ts +23 -0
- package/dist/memory-bank/seed.js +164 -0
- package/dist/memory-bank/seed.js.map +1 -0
- package/dist/memory-bank/store.d.ts +24 -0
- package/dist/memory-bank/store.js +193 -0
- package/dist/memory-bank/store.js.map +1 -0
- package/dist/memory-bank/types.d.ts +45 -0
- package/dist/memory-bank/types.js +2 -0
- package/dist/memory-bank/types.js.map +1 -0
- package/dist/memory-bank/uri.d.ts +16 -0
- package/dist/memory-bank/uri.js +52 -0
- package/dist/memory-bank/uri.js.map +1 -0
- package/dist/workspace.d.ts +1 -0
- package/dist/workspace.js +13 -0
- package/dist/workspace.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
import { pathExists } from "../fs.js";
|
|
5
|
+
/**
|
|
6
|
+
* Valid phase sequence for goal state machine.
|
|
7
|
+
* Phases must be completed in order; no gaps allowed.
|
|
8
|
+
*/
|
|
9
|
+
export const VALID_PHASES = [
|
|
10
|
+
"intake",
|
|
11
|
+
"goal_def",
|
|
12
|
+
"dep_check",
|
|
13
|
+
"ws_analysis",
|
|
14
|
+
"plan",
|
|
15
|
+
"dev",
|
|
16
|
+
"review",
|
|
17
|
+
"finish",
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Validate a goal state's structural integrity.
|
|
21
|
+
*
|
|
22
|
+
* Checks performed:
|
|
23
|
+
* a) All required phase checkpoints exist
|
|
24
|
+
* b) Phase sequence: no completed phase with a prior pending phase (no gaps)
|
|
25
|
+
* c) Completed phases must have completed_at set
|
|
26
|
+
* d) Group DAG has no cycles and all dependencies resolve to known groups
|
|
27
|
+
* e) Group statuses are valid (pending/in_progress/complete)
|
|
28
|
+
* f) Groups with a `phase` set must have that parent phase complete
|
|
29
|
+
*/
|
|
30
|
+
export function validateGoalState(state) {
|
|
31
|
+
const errors = [];
|
|
32
|
+
const warnings = [];
|
|
33
|
+
// a) All required phase checkpoints exist
|
|
34
|
+
for (const phase of VALID_PHASES) {
|
|
35
|
+
const cp = state.checkpoints[phase];
|
|
36
|
+
if (!cp) {
|
|
37
|
+
errors.push(`Missing required phase checkpoint: ${phase}`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const validStatuses = new Set(["pending", "in_progress", "complete"]);
|
|
41
|
+
if (!validStatuses.has(cp.status)) {
|
|
42
|
+
errors.push(`Phase ${phase} has invalid status: ${cp.status}`);
|
|
43
|
+
}
|
|
44
|
+
if (typeof cp.attempts !== "number") {
|
|
45
|
+
errors.push(`Phase ${phase} is missing numeric attempts field`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// b) Phase sequence: no completed phase if a prior phase is still pending
|
|
49
|
+
let foundPending = false;
|
|
50
|
+
for (const phase of VALID_PHASES) {
|
|
51
|
+
const cp = state.checkpoints[phase];
|
|
52
|
+
if (!cp)
|
|
53
|
+
continue;
|
|
54
|
+
if (foundPending && cp.status === "complete") {
|
|
55
|
+
errors.push(`Phase ${phase} is complete but prior phase(s) are not yet complete (gap in sequence)`);
|
|
56
|
+
}
|
|
57
|
+
if (cp.status === "pending") {
|
|
58
|
+
foundPending = true;
|
|
59
|
+
}
|
|
60
|
+
// in_progress also counts as "not done" for gap detection
|
|
61
|
+
if (cp.status === "in_progress") {
|
|
62
|
+
foundPending = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// c) Completed phases must have completed_at
|
|
66
|
+
for (const phase of VALID_PHASES) {
|
|
67
|
+
const cp = state.checkpoints[phase];
|
|
68
|
+
if (!cp)
|
|
69
|
+
continue;
|
|
70
|
+
if (cp.status === "complete" && !cp.completed_at) {
|
|
71
|
+
errors.push(`Phase ${phase} is complete but missing completed_at`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// d) Group DAG validation
|
|
75
|
+
const groups = state.groups;
|
|
76
|
+
if (groups && Object.keys(groups).length > 0) {
|
|
77
|
+
const groupIds = new Set(Object.keys(groups));
|
|
78
|
+
// All dependencies must resolve to known groups
|
|
79
|
+
for (const [gid, group] of Object.entries(groups)) {
|
|
80
|
+
const deps = group.dependencies;
|
|
81
|
+
if (deps && Array.isArray(deps)) {
|
|
82
|
+
for (const dep of deps) {
|
|
83
|
+
if (!groupIds.has(dep)) {
|
|
84
|
+
errors.push(`Group ${gid} depends on unknown group: ${dep}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Cycle detection via DFS
|
|
90
|
+
const visited = new Set();
|
|
91
|
+
const inStack = new Set();
|
|
92
|
+
function hasCycle(node) {
|
|
93
|
+
if (inStack.has(node))
|
|
94
|
+
return true;
|
|
95
|
+
if (visited.has(node))
|
|
96
|
+
return false;
|
|
97
|
+
visited.add(node);
|
|
98
|
+
inStack.add(node);
|
|
99
|
+
const g = groups[node];
|
|
100
|
+
if (g) {
|
|
101
|
+
const deps = g.dependencies;
|
|
102
|
+
if (deps && Array.isArray(deps)) {
|
|
103
|
+
for (const dep of deps) {
|
|
104
|
+
if (hasCycle(dep))
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
inStack.delete(node);
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
for (const gid of groupIds) {
|
|
113
|
+
if (hasCycle(gid)) {
|
|
114
|
+
errors.push(`Group dependency cycle detected involving group: ${gid}`);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// e) Group statuses must be valid
|
|
119
|
+
const validGroupStatuses = new Set(["pending", "in_progress", "complete"]);
|
|
120
|
+
for (const [gid, group] of Object.entries(groups)) {
|
|
121
|
+
if (!validGroupStatuses.has(group.status)) {
|
|
122
|
+
errors.push(`Group ${gid} has invalid status: ${group.status}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// f) Groups with a phase set must have that parent phase complete
|
|
126
|
+
for (const [gid, group] of Object.entries(groups)) {
|
|
127
|
+
const groupPhase = group.phase;
|
|
128
|
+
if (groupPhase) {
|
|
129
|
+
const parentCp = state.checkpoints[groupPhase];
|
|
130
|
+
if (!parentCp) {
|
|
131
|
+
errors.push(`Group ${gid} references unknown phase: ${groupPhase}`);
|
|
132
|
+
}
|
|
133
|
+
else if (parentCp.status !== "complete") {
|
|
134
|
+
errors.push(`Group ${gid} has phase ${groupPhase} but that phase is not yet complete`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Validate current_phase if set
|
|
140
|
+
if (state.current_phase &&
|
|
141
|
+
state.current_phase !== "complete" &&
|
|
142
|
+
!VALID_PHASES.includes(state.current_phase)) {
|
|
143
|
+
warnings.push(`current_phase "${state.current_phase}" is not in the standard phase sequence`);
|
|
144
|
+
}
|
|
145
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Read and parse a goal state JSON file.
|
|
149
|
+
* @param statePath - Full path to the state file (e.g., `.aiws/goals/G-014.state.json`)
|
|
150
|
+
*/
|
|
151
|
+
export async function readGoalState(statePath) {
|
|
152
|
+
const content = await fs.readFile(statePath, "utf8");
|
|
153
|
+
return JSON.parse(content);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Atomically write a goal state to disk using tmp-file-then-rename.
|
|
157
|
+
* @param statePath - Full path to the state file to write
|
|
158
|
+
* @param state - The goal state to persist
|
|
159
|
+
*/
|
|
160
|
+
export async function writeGoalState(statePath, state) {
|
|
161
|
+
const dir = path.dirname(statePath);
|
|
162
|
+
const tmpId = crypto.randomBytes(4).toString("hex");
|
|
163
|
+
const tmpPath = path.join(dir, `.tmp-${tmpId}.json`);
|
|
164
|
+
const updated = {
|
|
165
|
+
...state,
|
|
166
|
+
updated_at: new Date().toISOString(),
|
|
167
|
+
};
|
|
168
|
+
await fs.writeFile(tmpPath, JSON.stringify(updated, null, 2), "utf8");
|
|
169
|
+
await fs.rename(tmpPath, statePath);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Determine the next phase in the goal state machine.
|
|
173
|
+
*
|
|
174
|
+
* Logic:
|
|
175
|
+
* 1. If current phase checkpoint is not `complete` → stay on that phase
|
|
176
|
+
* 2. If groups exist: walk groups in topological order; find first pending group
|
|
177
|
+
* and its first pending phase
|
|
178
|
+
* 3. If no groups: advance through the flat VALID_PHASES sequence
|
|
179
|
+
* 4. If all phases (and groups) are complete → signal done
|
|
180
|
+
*/
|
|
181
|
+
export function computeNextPhase(state) {
|
|
182
|
+
const currentPhase = state.current_phase ?? VALID_PHASES[0];
|
|
183
|
+
// Special case: "complete" current_phase means everything is done,
|
|
184
|
+
// or we treat it as all phases completed
|
|
185
|
+
if (currentPhase === "complete") {
|
|
186
|
+
// Check if there are still pending phases
|
|
187
|
+
for (const phase of VALID_PHASES) {
|
|
188
|
+
const cp = state.checkpoints[phase];
|
|
189
|
+
if (cp && cp.status !== "complete") {
|
|
190
|
+
return {
|
|
191
|
+
phase,
|
|
192
|
+
groupId: null,
|
|
193
|
+
done: false,
|
|
194
|
+
reason: `Current phase marked complete but phase ${phase} is still ${cp.status}`,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return { phase: "finish", groupId: null, done: true, reason: "All phases complete" };
|
|
199
|
+
}
|
|
200
|
+
// If current phase checkpoint is not complete, stay on it
|
|
201
|
+
const currentCp = state.checkpoints[currentPhase];
|
|
202
|
+
if (currentCp && currentCp.status !== "complete") {
|
|
203
|
+
return {
|
|
204
|
+
phase: currentPhase,
|
|
205
|
+
groupId: null,
|
|
206
|
+
done: false,
|
|
207
|
+
reason: "Current phase not yet complete",
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
// If current phase is at index < last and we have no groups,
|
|
211
|
+
// return the next sequential phase
|
|
212
|
+
const groups = state.groups;
|
|
213
|
+
if (!groups || Object.keys(groups).length === 0) {
|
|
214
|
+
const currentIdx = VALID_PHASES.indexOf(currentPhase);
|
|
215
|
+
if (currentIdx < VALID_PHASES.length - 1) {
|
|
216
|
+
const nextPhase = VALID_PHASES[currentIdx + 1];
|
|
217
|
+
return {
|
|
218
|
+
phase: nextPhase,
|
|
219
|
+
groupId: null,
|
|
220
|
+
done: false,
|
|
221
|
+
reason: `Advancing to next phase: ${nextPhase}`,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
// All flat phases complete
|
|
225
|
+
return { phase: currentPhase, groupId: null, done: true, reason: "All phases complete" };
|
|
226
|
+
}
|
|
227
|
+
// Groups exist: walk in topological order, find first pending group
|
|
228
|
+
const sorted = topologicalSort(groups);
|
|
229
|
+
for (const gid of sorted) {
|
|
230
|
+
const group = groups[gid];
|
|
231
|
+
if (!group)
|
|
232
|
+
continue;
|
|
233
|
+
if (group.status !== "complete") {
|
|
234
|
+
// Group is not complete — find its first pending phase
|
|
235
|
+
// Groups use the plan/dev/review/finish sub-sequence
|
|
236
|
+
const groupPhases = ["plan", "dev", "review", "finish"];
|
|
237
|
+
for (const phase of groupPhases) {
|
|
238
|
+
const cp = state.checkpoints[phase];
|
|
239
|
+
if (!cp || cp.status !== "complete") {
|
|
240
|
+
return {
|
|
241
|
+
phase,
|
|
242
|
+
groupId: gid,
|
|
243
|
+
done: false,
|
|
244
|
+
reason: `Group ${gid} needs phase ${phase}`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// All group phases done but group not marked complete
|
|
249
|
+
return {
|
|
250
|
+
phase: "finish",
|
|
251
|
+
groupId: gid,
|
|
252
|
+
done: false,
|
|
253
|
+
reason: `Group ${gid} phases done but group not marked complete`,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// All groups complete
|
|
258
|
+
return { phase: currentPhase, groupId: null, done: true, reason: "All groups complete" };
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Topological sort of groups by dependency DAG.
|
|
262
|
+
* Returns group IDs in dependency order (dependencies first).
|
|
263
|
+
*/
|
|
264
|
+
function topologicalSort(groups) {
|
|
265
|
+
const sorted = [];
|
|
266
|
+
const visited = new Set();
|
|
267
|
+
const visiting = new Set();
|
|
268
|
+
function visit(node) {
|
|
269
|
+
if (visited.has(node))
|
|
270
|
+
return;
|
|
271
|
+
if (visiting.has(node))
|
|
272
|
+
return; // cycle protection
|
|
273
|
+
visiting.add(node);
|
|
274
|
+
const g = groups[node];
|
|
275
|
+
if (g) {
|
|
276
|
+
const deps = g.dependencies;
|
|
277
|
+
if (deps && Array.isArray(deps)) {
|
|
278
|
+
for (const dep of deps) {
|
|
279
|
+
visit(dep);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
visiting.delete(node);
|
|
284
|
+
visited.add(node);
|
|
285
|
+
sorted.push(node);
|
|
286
|
+
}
|
|
287
|
+
for (const id of Object.keys(groups)) {
|
|
288
|
+
visit(id);
|
|
289
|
+
}
|
|
290
|
+
return sorted;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Collect pending (non-complete) phases from checkpoints.
|
|
294
|
+
*/
|
|
295
|
+
export function listPendingPhases(state) {
|
|
296
|
+
const pending = [];
|
|
297
|
+
for (const phase of VALID_PHASES) {
|
|
298
|
+
const cp = state.checkpoints[phase];
|
|
299
|
+
if (!cp || cp.status !== "complete") {
|
|
300
|
+
pending.push(phase);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return pending;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Find all goal state files in a directory.
|
|
307
|
+
* Scans for `*.state.json` files.
|
|
308
|
+
*/
|
|
309
|
+
export async function scanGoalStateFiles(goalDir) {
|
|
310
|
+
let entries;
|
|
311
|
+
try {
|
|
312
|
+
entries = await fs.readdir(goalDir);
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
const files = [];
|
|
318
|
+
for (const entry of entries) {
|
|
319
|
+
if (entry.endsWith(".state.json") && !entry.startsWith(".tmp-")) {
|
|
320
|
+
files.push(path.join(goalDir, entry));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return files.sort();
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Resolve a goal state file path from a directory and optional goal ID.
|
|
327
|
+
* If goalId is provided, returns the path to `<goalId>.state.json`.
|
|
328
|
+
* If not provided and exactly one `.state.json` exists, returns that path.
|
|
329
|
+
*/
|
|
330
|
+
export async function resolveGoalStatePath(goalDir, goalId) {
|
|
331
|
+
if (goalId) {
|
|
332
|
+
const p = path.join(goalDir, `${goalId}.state.json`);
|
|
333
|
+
if (await pathExists(p)) {
|
|
334
|
+
return p;
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
// No goalId: find active goal (status=active) or the newest state file
|
|
339
|
+
const files = await scanGoalStateFiles(goalDir);
|
|
340
|
+
if (files.length === 0)
|
|
341
|
+
return null;
|
|
342
|
+
// Prefer a goal with active status
|
|
343
|
+
for (const f of files) {
|
|
344
|
+
try {
|
|
345
|
+
const state = await readGoalState(f);
|
|
346
|
+
if (state.status === "active") {
|
|
347
|
+
return f;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
// skip unreadable files
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Fall back to the most recently modified file
|
|
355
|
+
let best = files[0];
|
|
356
|
+
let bestMtime = 0;
|
|
357
|
+
for (const f of files) {
|
|
358
|
+
try {
|
|
359
|
+
const st = await fs.stat(f);
|
|
360
|
+
if (st.mtimeMs > bestMtime) {
|
|
361
|
+
bestMtime = st.mtimeMs;
|
|
362
|
+
best = f;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// skip
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return best;
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=goal-validate-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-validate-state.js","sourceRoot":"","sources":["../../src/commands/goal-validate-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GoalValidateStateOptions {
|
|
2
|
+
/** Directory containing goal state files (e.g., `.aiws/goals/`) */
|
|
3
|
+
goalDir: string;
|
|
4
|
+
/** Optional goal ID. If omitted, validate all goals */
|
|
5
|
+
goalId?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* `aiws goal validate-state` command handler.
|
|
9
|
+
*
|
|
10
|
+
* Validates one or all goal state files and reports errors/warnings.
|
|
11
|
+
* Exit code 0 if all valid, 1 if any errors found.
|
|
12
|
+
*/
|
|
13
|
+
export declare function goalValidateStateCommand(options: GoalValidateStateOptions): Promise<{
|
|
14
|
+
ok: boolean;
|
|
15
|
+
output: string;
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { readGoalState, validateGoalState, scanGoalStateFiles, resolveGoalStatePath, } from "./goal-validate-state.js";
|
|
2
|
+
/**
|
|
3
|
+
* `aiws goal validate-state` command handler.
|
|
4
|
+
*
|
|
5
|
+
* Validates one or all goal state files and reports errors/warnings.
|
|
6
|
+
* Exit code 0 if all valid, 1 if any errors found.
|
|
7
|
+
*/
|
|
8
|
+
export async function goalValidateStateCommand(options) {
|
|
9
|
+
if (options.goalId) {
|
|
10
|
+
return validateSingleGoal(options.goalDir, options.goalId);
|
|
11
|
+
}
|
|
12
|
+
return validateAllGoals(options.goalDir);
|
|
13
|
+
}
|
|
14
|
+
async function validateSingleGoal(goalDir, goalId) {
|
|
15
|
+
const statePath = await resolveGoalStatePath(goalDir, goalId);
|
|
16
|
+
if (!statePath) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
output: `Goal state file not found for "${goalId}" in ${goalDir}`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
let state;
|
|
23
|
+
try {
|
|
24
|
+
state = await readGoalState(statePath);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
output: `Failed to read ${statePath}: ${String(err)}`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const result = validateGoalState(state);
|
|
33
|
+
const lines = [];
|
|
34
|
+
lines.push(`Goal: ${state.goal_id || goalId}`);
|
|
35
|
+
lines.push(` File: ${statePath}`);
|
|
36
|
+
lines.push(` Status: ${result.valid ? "PASS" : "FAIL"}`);
|
|
37
|
+
if (result.errors.length > 0) {
|
|
38
|
+
lines.push(` Errors (${result.errors.length}):`);
|
|
39
|
+
for (const err of result.errors) {
|
|
40
|
+
lines.push(` - ${err}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (result.warnings.length > 0) {
|
|
44
|
+
lines.push(` Warnings (${result.warnings.length}):`);
|
|
45
|
+
for (const warn of result.warnings) {
|
|
46
|
+
lines.push(` - ${warn}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
ok: result.valid,
|
|
51
|
+
output: lines.join("\n"),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function validateAllGoals(goalDir) {
|
|
55
|
+
const files = await scanGoalStateFiles(goalDir);
|
|
56
|
+
if (files.length === 0) {
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
output: `No goal state files found in ${goalDir}`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const lines = [];
|
|
63
|
+
let hasErrors = false;
|
|
64
|
+
let totalGoals = 0;
|
|
65
|
+
let passed = 0;
|
|
66
|
+
let failed = 0;
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
totalGoals++;
|
|
69
|
+
let state;
|
|
70
|
+
try {
|
|
71
|
+
state = await readGoalState(file);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
lines.push(`[FAIL] ${file}: Failed to read: ${String(err)}`);
|
|
75
|
+
failed++;
|
|
76
|
+
hasErrors = true;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const result = validateGoalState(state);
|
|
80
|
+
const goalLabel = state.goal_id || file;
|
|
81
|
+
if (result.valid) {
|
|
82
|
+
lines.push(`[PASS] ${goalLabel}${result.warnings.length > 0 ? ` (${result.warnings.length} warnings)` : ""}`);
|
|
83
|
+
passed++;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
lines.push(`[FAIL] ${goalLabel}: ${result.errors.length} error(s)`);
|
|
87
|
+
for (const err of result.errors) {
|
|
88
|
+
lines.push(` - ${err}`);
|
|
89
|
+
}
|
|
90
|
+
failed++;
|
|
91
|
+
hasErrors = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
lines.push(`\nSummary: ${totalGoals} goal(s) — ${passed} passed, ${failed} failed`);
|
|
95
|
+
return {
|
|
96
|
+
ok: !hasErrors,
|
|
97
|
+
output: lines.join("\n"),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=goal-validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-validate.js","sourceRoot":"","sources":["../../src/commands/goal-validate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AASlC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAiC;IAEjC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,OAAe,EACf,MAAc;IAEd,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,kCAAkC,MAAM,QAAQ,OAAO,EAAE;SAClE,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,kBAAkB,SAAS,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE;SACtD,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAE1D,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QAClD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;QACtD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,KAAK;QAChB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;KACzB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,OAAe;IAEf,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,gCAAgC,OAAO,EAAE;SAClD,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,UAAU,EAAE,CAAC;QACb,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,qBAAqB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,EAAE,CAAC;YACT,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC;QAExC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CACR,UAAU,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAClG,CAAC;YACF,MAAM,EAAE,CAAC;QACX,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CACR,UAAU,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,WAAW,CACxD,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;YAChC,CAAC;YACD,MAAM,EAAE,CAAC;YACT,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CACR,cAAc,UAAU,cAAc,MAAM,YAAY,MAAM,SAAS,CACxE,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,CAAC,SAAS;QACd,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;KACzB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* aiws memory read <uri>
|
|
3
|
+
*/
|
|
4
|
+
export declare function memoryReadCommand(args: Record<string, unknown>): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* aiws memory write <uri> <text> [--title <title>] [--tags <tags>] [--disclosure <level>]
|
|
7
|
+
*/
|
|
8
|
+
export declare function memoryWriteCommand(args: Record<string, unknown>): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* aiws memory search <query>
|
|
11
|
+
*/
|
|
12
|
+
export declare function memorySearchCommand(args: Record<string, unknown>): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* aiws memory list [domain]
|
|
15
|
+
*/
|
|
16
|
+
export declare function memoryListCommand(args: Record<string, unknown>): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* aiws memory link add|list|rm
|
|
19
|
+
*/
|
|
20
|
+
export declare function memoryLinkCommand(args: Record<string, unknown>): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* aiws memory boot
|
|
23
|
+
* Lists memories marked with disclosure: boot (or always).
|
|
24
|
+
* Scans index only — reads files only for snippet.
|
|
25
|
+
*/
|
|
26
|
+
export declare function memoryBootCommand(_args: Record<string, unknown>): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* aiws memory seed [--dry-run] [--force]
|
|
29
|
+
* Seeds memory entries from project truth files and artifacts.
|
|
30
|
+
*/
|
|
31
|
+
export declare function memorySeedCommand(args: Record<string, unknown>): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* aiws memory rebuild-index
|
|
34
|
+
*/
|
|
35
|
+
export declare function memoryRebuildIndexCommand(_args: Record<string, unknown>): Promise<void>;
|