@veewo/claw-core 0.1.12

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 (56) hide show
  1. package/README.md +7 -0
  2. package/dist/src/completion-hooks.d.ts +6 -0
  3. package/dist/src/completion-hooks.js +64 -0
  4. package/dist/src/completion-hooks.js.map +1 -0
  5. package/dist/src/context.d.ts +7 -0
  6. package/dist/src/context.js +171 -0
  7. package/dist/src/context.js.map +1 -0
  8. package/dist/src/errors.d.ts +6 -0
  9. package/dist/src/errors.js +11 -0
  10. package/dist/src/errors.js.map +1 -0
  11. package/dist/src/index.d.ts +15 -0
  12. package/dist/src/index.js +16 -0
  13. package/dist/src/index.js.map +1 -0
  14. package/dist/src/init.d.ts +22 -0
  15. package/dist/src/init.js +91 -0
  16. package/dist/src/init.js.map +1 -0
  17. package/dist/src/io.d.ts +6 -0
  18. package/dist/src/io.js +47 -0
  19. package/dist/src/io.js.map +1 -0
  20. package/dist/src/memory.d.ts +4 -0
  21. package/dist/src/memory.js +240 -0
  22. package/dist/src/memory.js.map +1 -0
  23. package/dist/src/paths.d.ts +6 -0
  24. package/dist/src/paths.js +73 -0
  25. package/dist/src/paths.js.map +1 -0
  26. package/dist/src/plan-events.d.ts +12 -0
  27. package/dist/src/plan-events.js +8 -0
  28. package/dist/src/plan-events.js.map +1 -0
  29. package/dist/src/plan-view.d.ts +6 -0
  30. package/dist/src/plan-view.js +69 -0
  31. package/dist/src/plan-view.js.map +1 -0
  32. package/dist/src/plan.d.ts +10 -0
  33. package/dist/src/plan.js +510 -0
  34. package/dist/src/plan.js.map +1 -0
  35. package/dist/src/project-check.d.ts +3 -0
  36. package/dist/src/project-check.js +238 -0
  37. package/dist/src/project-check.js.map +1 -0
  38. package/dist/src/requirements-gate.d.ts +23 -0
  39. package/dist/src/requirements-gate.js +49 -0
  40. package/dist/src/requirements-gate.js.map +1 -0
  41. package/dist/src/switch-task.d.ts +2 -0
  42. package/dist/src/switch-task.js +60 -0
  43. package/dist/src/switch-task.js.map +1 -0
  44. package/dist/src/task-retention.d.ts +2 -0
  45. package/dist/src/task-retention.js +126 -0
  46. package/dist/src/task-retention.js.map +1 -0
  47. package/dist/src/truth.d.ts +2 -0
  48. package/dist/src/truth.js +33 -0
  49. package/dist/src/truth.js.map +1 -0
  50. package/dist/src/types.d.ts +476 -0
  51. package/dist/src/types.js +2 -0
  52. package/dist/src/types.js.map +1 -0
  53. package/dist/src/workflow-guidance.d.ts +10 -0
  54. package/dist/src/workflow-guidance.js +233 -0
  55. package/dist/src/workflow-guidance.js.map +1 -0
  56. package/package.json +32 -0
@@ -0,0 +1,240 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { resolveProjectContext, resolveTaskContext } from "./context.js";
5
+ import { ClawError } from "./errors.js";
6
+ import { readJsonFile, readTextFile } from "./io.js";
7
+ export function buildMemoryIndex(input) {
8
+ const { scope, project, task } = resolveMemoryScope(input);
9
+ const storePath = getMemoryStorePath(project, scope, task);
10
+ const sources = collectMemorySources(project, scope, task);
11
+ fs.mkdirSync(path.dirname(storePath), { recursive: true });
12
+ const db = new DatabaseSync(storePath);
13
+ try {
14
+ prepareSchema(db);
15
+ db.exec("DELETE FROM docs;");
16
+ db.exec("DELETE FROM docs_fts;");
17
+ const insertDoc = db.prepare("INSERT INTO docs (source_path, kind, content) VALUES (?, ?, ?)");
18
+ const insertFts = db.prepare("INSERT INTO docs_fts (rowid, source_path, kind, content) VALUES (?, ?, ?, ?)");
19
+ for (const source of sources) {
20
+ const result = insertDoc.run(source.sourcePath, source.kind, source.content);
21
+ insertFts.run(result.lastInsertRowid, source.sourcePath, source.kind, source.content);
22
+ }
23
+ }
24
+ finally {
25
+ db.close();
26
+ }
27
+ return {
28
+ scope,
29
+ storePath,
30
+ indexedCount: sources.length,
31
+ sources: sources.map((entry) => entry.sourcePath),
32
+ };
33
+ }
34
+ export function searchMemory(input) {
35
+ if (!input.query.trim()) {
36
+ throw new ClawError("MEMORY_QUERY_REQUIRED", "memory search requires a non-empty query.");
37
+ }
38
+ const { scope, project, task } = resolveMemoryScope(input);
39
+ const storePath = getMemoryStorePath(project, scope, task);
40
+ if (!fs.existsSync(storePath)) {
41
+ buildMemoryIndex({
42
+ cwd: input.cwd,
43
+ scope,
44
+ ...(task ? { taskName: task.taskName } : {}),
45
+ });
46
+ }
47
+ const db = new DatabaseSync(storePath);
48
+ try {
49
+ prepareSchema(db);
50
+ const limit = input.limit ?? 10;
51
+ const rows = db
52
+ .prepare([
53
+ "SELECT source_path, kind, snippet(docs_fts, 2, '[', ']', ' ... ', 18) AS snippet, bm25(docs_fts) AS score",
54
+ "FROM docs_fts",
55
+ "WHERE docs_fts MATCH ?",
56
+ "ORDER BY score ASC",
57
+ "LIMIT ?",
58
+ ].join(" "))
59
+ .all(input.query, limit);
60
+ const results = rows.map((row) => ({
61
+ sourcePath: row.source_path,
62
+ kind: row.kind,
63
+ snippet: row.snippet,
64
+ score: row.score,
65
+ }));
66
+ return {
67
+ scope,
68
+ storePath,
69
+ results,
70
+ };
71
+ }
72
+ finally {
73
+ db.close();
74
+ }
75
+ }
76
+ export function getMemory(input) {
77
+ const { scope, project, task } = resolveMemoryScope(input);
78
+ const storePath = getMemoryStorePath(project, scope, task);
79
+ const sources = collectMemorySources(project, scope, task);
80
+ return {
81
+ scope,
82
+ storePath,
83
+ sources,
84
+ };
85
+ }
86
+ function resolveMemoryScope(input) {
87
+ const project = resolveProjectContext(input.cwd);
88
+ const scope = input.scope ?? "project";
89
+ if (scope === "task") {
90
+ if (!input.taskName) {
91
+ throw new ClawError("TASK_NOT_FOUND", "Task scope memory commands require --task.", { scope });
92
+ }
93
+ return {
94
+ scope,
95
+ project,
96
+ task: resolveTaskContext(project, input.taskName),
97
+ };
98
+ }
99
+ return { scope, project };
100
+ }
101
+ function getMemoryStorePath(project, scope, task) {
102
+ if (scope === "task" && task) {
103
+ return path.join(task.taskDir, "memory.sqlite");
104
+ }
105
+ return path.join(project.clawDir, "memory.sqlite");
106
+ }
107
+ function collectMemorySources(project, scope, task) {
108
+ if (scope === "task" && task) {
109
+ return collectTaskMemorySources(task);
110
+ }
111
+ return collectProjectMemorySources(project);
112
+ }
113
+ function collectProjectMemorySources(project) {
114
+ const sources = [];
115
+ addTextSourceIfExists(sources, path.join(project.clawDir, "memory.md"), "project_memory");
116
+ for (const truthPath of listFiles(project.truthDir, (entry) => entry.endsWith(".md"))) {
117
+ addTextSourceIfExists(sources, truthPath, "truth_doc");
118
+ }
119
+ for (const knowledgePath of listFiles(path.join(project.clawDir, ".knowledge"), (entry) => /\.(md|txt|json)$/i.test(entry))) {
120
+ addTextSourceIfExists(sources, knowledgePath, "knowledge");
121
+ }
122
+ for (const externalPath of project.projectConfig?.memory?.externalDocPaths ?? []) {
123
+ addExternalDocSources(sources, project.projectRoot, externalPath);
124
+ }
125
+ return sources;
126
+ }
127
+ function collectTaskMemorySources(task) {
128
+ const sources = [];
129
+ const plan = readJsonFile(task.activePlanPath);
130
+ sources.push({
131
+ sourcePath: task.activePlanPath,
132
+ kind: "active_plan",
133
+ content: renderStructuredPlanMemory(plan),
134
+ });
135
+ addTextSourceIfExists(sources, path.join(task.taskDir, "memory.md"), "task_memory");
136
+ return sources;
137
+ }
138
+ function addTextSourceIfExists(sources, sourcePath, kind) {
139
+ if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {
140
+ return;
141
+ }
142
+ sources.push({
143
+ sourcePath,
144
+ kind,
145
+ content: readTextFile(sourcePath),
146
+ });
147
+ }
148
+ function addExternalDocSources(sources, projectRoot, externalPath) {
149
+ const resolved = path.isAbsolute(externalPath)
150
+ ? externalPath
151
+ : path.resolve(projectRoot, externalPath);
152
+ if (!fs.existsSync(resolved)) {
153
+ return;
154
+ }
155
+ const stat = fs.statSync(resolved);
156
+ if (stat.isFile()) {
157
+ addTextSourceIfExists(sources, resolved, "external_doc");
158
+ return;
159
+ }
160
+ if (!stat.isDirectory()) {
161
+ return;
162
+ }
163
+ for (const filePath of listFiles(resolved, isExternalDocFile)) {
164
+ addTextSourceIfExists(sources, filePath, "external_doc");
165
+ }
166
+ }
167
+ function renderStructuredPlanMemory(plan) {
168
+ const parts = [
169
+ `# ${plan.title}`,
170
+ `Status: ${plan.status}`,
171
+ `Goal: ${plan.goal.text}`,
172
+ ];
173
+ if (plan.rules?.length) {
174
+ parts.push("Rules:");
175
+ parts.push(...plan.rules.map((rule) => `- ${rule}`));
176
+ }
177
+ if (plan.references?.length) {
178
+ parts.push("References:");
179
+ parts.push(...plan.references.map((reference) => `- ${reference.why}: ${reference.path}`));
180
+ }
181
+ if (plan.keyDecisions?.length) {
182
+ parts.push("Key Decisions:");
183
+ parts.push(...plan.keyDecisions.map((decision) => `- ${decision}`));
184
+ }
185
+ if (plan.retrospective) {
186
+ parts.push("Retrospective:");
187
+ parts.push(`- Summary: ${plan.retrospective.summary}`);
188
+ for (const item of plan.retrospective.whatWorked ?? []) {
189
+ parts.push(`- Worked: ${item}`);
190
+ }
191
+ for (const item of plan.retrospective.issues ?? []) {
192
+ parts.push(`- Issue: ${item}`);
193
+ }
194
+ }
195
+ if (plan.tasks.length) {
196
+ parts.push("Tasks:");
197
+ parts.push(...plan.tasks.map((task) => `- [${task.status}] ${task.id}: ${task.title}`));
198
+ }
199
+ return `${parts.join("\n")}\n`;
200
+ }
201
+ function prepareSchema(db) {
202
+ db.exec([
203
+ "CREATE TABLE IF NOT EXISTS docs (",
204
+ " id INTEGER PRIMARY KEY,",
205
+ " source_path TEXT NOT NULL,",
206
+ " kind TEXT NOT NULL,",
207
+ " content TEXT NOT NULL",
208
+ ");",
209
+ "CREATE VIRTUAL TABLE IF NOT EXISTS docs_fts USING fts5(",
210
+ " source_path,",
211
+ " kind,",
212
+ " content",
213
+ ");",
214
+ ].join("\n"));
215
+ }
216
+ function listFiles(rootDir, matcher) {
217
+ if (!fs.existsSync(rootDir)) {
218
+ return [];
219
+ }
220
+ const entries = [];
221
+ const queue = [rootDir];
222
+ while (queue.length > 0) {
223
+ const current = queue.shift();
224
+ for (const child of fs.readdirSync(current, { withFileTypes: true })) {
225
+ const fullPath = path.join(current, child.name);
226
+ if (child.isDirectory()) {
227
+ queue.push(fullPath);
228
+ continue;
229
+ }
230
+ if (matcher(fullPath)) {
231
+ entries.push(fullPath);
232
+ }
233
+ }
234
+ }
235
+ return entries;
236
+ }
237
+ function isExternalDocFile(filePath) {
238
+ return /\.(md|mdx|txt|json)$/i.test(filePath);
239
+ }
240
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAgBrD,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IACtD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE3D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,aAAa,CAAC,EAAE,CAAC,CAAC;QAClB,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC7B,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAC1B,gEAAgE,CACjE,CAAC;QACF,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAC1B,8EAA8E,CAC/E,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7E,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IAED,OAAO;QACL,KAAK;QACL,SAAS;QACT,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,SAAS,CAAC,uBAAuB,EAAE,2CAA2C,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,gBAAgB,CAAC;YACf,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,KAAK;YACL,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,aAAa,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CACN;YACE,2GAA2G;YAC3G,eAAe;YACf,wBAAwB;YACxB,oBAAoB;YACpB,SAAS;SACV,CAAC,IAAI,CAAC,GAAG,CAAC,CACZ;aACA,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAiF,CAAC;QAE3G,MAAM,OAAO,GAA8B,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC5D,UAAU,EAAE,GAAG,CAAC,WAAW;YAC3B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE,GAAG,CAAC,KAAK;SACjB,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,KAAK;YACL,SAAS;YACT,OAAO;SACR,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3D,OAAO;QACL,KAAK;QACL,SAAS;QACT,OAAO;KACR,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAA2C;IAKrE,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC;IACvC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,IAAI,SAAS,CAAC,gBAAgB,EAAE,4CAA4C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACjG,CAAC;QACD,OAAO;YACL,KAAK;YACL,OAAO;YACP,IAAI,EAAE,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC;SAClD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAuB,EAAE,KAAkB,EAAE,IAAkB;IACzF,IAAI,KAAK,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAuB,EAAE,KAAkB,EAAE,IAAkB;IAC3F,IAAI,KAAK,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;QAC7B,OAAO,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,2BAA2B,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,2BAA2B,CAAC,OAAuB;IAC1D,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC1F,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACtF,qBAAqB,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,MAAM,aAAa,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC5H,qBAAqB,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,MAAM,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,gBAAgB,IAAI,EAAE,EAAE,CAAC;QACjF,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAiB;IACjD,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,YAAY,CAAe,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC;QACX,UAAU,EAAE,IAAI,CAAC,cAAc;QAC/B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,0BAA0B,CAAC,IAAI,CAAC;KAC1C,CAAC,CAAC;IACH,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,aAAa,CAAC,CAAC;IACpF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAA4B,EAAE,UAAkB,EAAE,IAAY;IAC3F,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QACpE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,IAAI,CAAC;QACX,UAAU;QACV,IAAI;QACJ,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC;KAClC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAC5B,OAA4B,EAC5B,WAAmB,EACnB,YAAoB;IAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAC5C,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAkB;IACpD,MAAM,KAAK,GAAa;QACtB,KAAK,IAAI,CAAC,KAAK,EAAE;QACjB,WAAW,IAAI,CAAC,MAAM,EAAE;QACxB,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;KAC1B,CAAC;IACF,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,GAAG,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,aAAa,CAAC,EAAgB;IACrC,EAAE,CAAC,IAAI,CACL;QACE,mCAAmC;QACnC,2BAA2B;QAC3B,8BAA8B;QAC9B,uBAAuB;QACvB,yBAAyB;QACzB,IAAI;QACJ,yDAAyD;QACzD,gBAAgB;QAChB,SAAS;QACT,WAAW;QACX,IAAI;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,OAAe,EAAE,OAAsC;IACxE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACrB,SAAS;YACX,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,OAAO,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function findProjectRoot(startDir: string): string | null;
2
+ export declare function normalizeTaskName(input: string): string;
3
+ export declare function isValidTaskName(input: string): boolean;
4
+ export declare function ensureInsideDir(rootDir: string, relativePath: string): string | null;
5
+ export declare function normalizePlanFile(relativePath?: string): string;
6
+ export declare function slugFromFilePath(filePath: string): string;
@@ -0,0 +1,73 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const WINDOWS_RESERVED_NAMES = new Set([
4
+ "con",
5
+ "prn",
6
+ "aux",
7
+ "nul",
8
+ "com1",
9
+ "com2",
10
+ "com3",
11
+ "com4",
12
+ "com5",
13
+ "com6",
14
+ "com7",
15
+ "com8",
16
+ "com9",
17
+ "lpt1",
18
+ "lpt2",
19
+ "lpt3",
20
+ "lpt4",
21
+ "lpt5",
22
+ "lpt6",
23
+ "lpt7",
24
+ "lpt8",
25
+ "lpt9"
26
+ ]);
27
+ export function findProjectRoot(startDir) {
28
+ let current = path.resolve(startDir);
29
+ while (true) {
30
+ if (fs.existsSync(path.join(current, ".claw"))) {
31
+ return current;
32
+ }
33
+ const parent = path.dirname(current);
34
+ if (parent === current) {
35
+ return null;
36
+ }
37
+ current = parent;
38
+ }
39
+ }
40
+ export function normalizeTaskName(input) {
41
+ const compact = input
42
+ .trim()
43
+ .replace(/[<>:"/\\|?*\u0000-\u001f]/g, "-")
44
+ .replace(/\s+/g, "-")
45
+ .replace(/-+/g, "-")
46
+ .replace(/^[.-]+|[.-]+$/g, "");
47
+ const lower = compact.toLowerCase();
48
+ return WINDOWS_RESERVED_NAMES.has(lower) ? `${compact}-task` : compact;
49
+ }
50
+ export function isValidTaskName(input) {
51
+ return input.length > 0 && normalizeTaskName(input) === input;
52
+ }
53
+ export function ensureInsideDir(rootDir, relativePath) {
54
+ const resolved = path.resolve(rootDir, relativePath);
55
+ const absoluteRoot = path.resolve(rootDir);
56
+ if (resolved === absoluteRoot || resolved.startsWith(`${absoluteRoot}${path.sep}`)) {
57
+ return resolved;
58
+ }
59
+ return null;
60
+ }
61
+ export function normalizePlanFile(relativePath) {
62
+ if (!relativePath?.trim()) {
63
+ return "plan.json";
64
+ }
65
+ const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
66
+ return normalized.endsWith(".json") ? normalized : `${normalized}.json`;
67
+ }
68
+ export function slugFromFilePath(filePath) {
69
+ const normalized = filePath.replace(/\\/g, "/").replace(/\/+$/, "");
70
+ const baseName = path.posix.basename(normalized, path.posix.extname(normalized));
71
+ return normalizeTaskName(baseName);
72
+ }
73
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACrC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,OAAO,GAAG,KAAK;SAClB,IAAI,EAAE;SACN,OAAO,CAAC,4BAA4B,EAAE,GAAG,CAAC;SAC1C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,YAAoB;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QACnF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,YAAqB;IACrD,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxE,OAAO,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,OAAO,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACjF,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export type PlanEventType = "plan_created" | "plan_changed" | "plan_task_completed" | "plan_completed";
2
+ export type PlanEvent = {
3
+ type: PlanEventType;
4
+ planPath: string;
5
+ planTitle: string;
6
+ planStatus: string;
7
+ taskId?: number;
8
+ affectedPlanTaskIds?: number[];
9
+ previousStatus?: string;
10
+ timestamp: number;
11
+ };
12
+ export declare function buildPlanEvent(type: PlanEventType, params: Omit<PlanEvent, "type" | "timestamp">): PlanEvent;
@@ -0,0 +1,8 @@
1
+ export function buildPlanEvent(type, params) {
2
+ return {
3
+ type,
4
+ timestamp: Date.now(),
5
+ ...params,
6
+ };
7
+ }
8
+ //# sourceMappingURL=plan-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-events.js","sourceRoot":"","sources":["../../src/plan-events.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,cAAc,CAC5B,IAAmB,EACnB,MAA6C;IAE7C,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,GAAG,MAAM;KACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { PlanDocument, PlanViewModel } from "./types.js";
2
+ export declare function buildPlanViewModel(input: {
3
+ taskName: string;
4
+ planFile: string;
5
+ plan: PlanDocument;
6
+ }): PlanViewModel;
@@ -0,0 +1,69 @@
1
+ export function buildPlanViewModel(input) {
2
+ const { taskName, planFile, plan } = input;
3
+ const total = plan.tasks.length;
4
+ const completed = plan.tasks.filter((task) => task.status === "done").length;
5
+ const orderedTasks = orderPlanViewTasks(plan.tasks);
6
+ return {
7
+ taskName,
8
+ planFile,
9
+ title: plan.title,
10
+ status: plan.status,
11
+ collapsedSummary: `${completed}/${total} ${plan.title}`,
12
+ counts: {
13
+ completed,
14
+ total,
15
+ },
16
+ goal: {
17
+ text: plan.goal.text,
18
+ defaultCollapsed: true,
19
+ },
20
+ tasks: {
21
+ ordering: "unfinished_first_stable",
22
+ items: orderedTasks,
23
+ },
24
+ expanded: {
25
+ sections: [
26
+ {
27
+ id: "goal",
28
+ label: "Goal",
29
+ type: "disclosure",
30
+ defaultExpanded: false,
31
+ content: {
32
+ text: plan.goal.text,
33
+ },
34
+ },
35
+ {
36
+ id: "tasks",
37
+ label: "Tasks",
38
+ type: "list",
39
+ defaultExpanded: true,
40
+ ordering: "unfinished_first_stable",
41
+ items: orderedTasks,
42
+ },
43
+ ],
44
+ },
45
+ renderHints: {
46
+ defaultCollapsed: true,
47
+ supportsGoalDisclosure: true,
48
+ refreshOn: ["plan.write", "plan.edit", "plan.done"],
49
+ },
50
+ };
51
+ }
52
+ function orderPlanViewTasks(tasks) {
53
+ const indexed = tasks.map((task, index) => ({ task, index }));
54
+ indexed.sort((left, right) => {
55
+ const leftDone = left.task.status === "done";
56
+ const rightDone = right.task.status === "done";
57
+ if (leftDone !== rightDone) {
58
+ return leftDone ? 1 : -1;
59
+ }
60
+ return left.index - right.index;
61
+ });
62
+ return indexed.map(({ task }) => ({
63
+ id: task.id,
64
+ title: task.title,
65
+ status: task.status,
66
+ ...(task.detail ? { detail: task.detail } : {}),
67
+ }));
68
+ }
69
+ //# sourceMappingURL=plan-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-view.js","sourceRoot":"","sources":["../../src/plan-view.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,KAIlC;IACC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC7E,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEpD,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,gBAAgB,EAAE,GAAG,SAAS,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;QACvD,MAAM,EAAE;YACN,SAAS;YACT,KAAK;SACN;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YACpB,gBAAgB,EAAE,IAAI;SACvB;QACD,KAAK,EAAE;YACL,QAAQ,EAAE,yBAAyB;YACnC,KAAK,EAAE,YAAY;SACpB;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE;gBACR;oBACE,EAAE,EAAE,MAAM;oBACV,KAAK,EAAE,MAAM;oBACb,IAAI,EAAE,YAAY;oBAClB,eAAe,EAAE,KAAK;oBACtB,OAAO,EAAE;wBACP,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;qBACrB;iBACF;gBACD;oBACE,EAAE,EAAE,OAAO;oBACX,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,MAAM;oBACZ,eAAe,EAAE,IAAI;oBACrB,QAAQ,EAAE,yBAAyB;oBACnC,KAAK,EAAE,YAAY;iBACpB;aACF;SACF;QACD,WAAW,EAAE;YACX,gBAAgB,EAAE,IAAI;YACtB,sBAAsB,EAAE,IAAI;YAC5B,SAAS,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC;SACpD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAiB;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC;QAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAClC,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAChC,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { PlanEditInput, PlanEditResult, PlanShowInput, PlanShowResult, PlanStatus, PlanWriteInput, PlanWriteResult } from "./types.js";
2
+ import type { PlanEvent } from "./plan-events.js";
3
+ export declare function writePlan(input: PlanWriteInput): Promise<PlanWriteResult & {
4
+ events: PlanEvent[];
5
+ }>;
6
+ export declare function editPlan(input: PlanEditInput): Promise<PlanEditResult & {
7
+ events: PlanEvent[];
8
+ }>;
9
+ export declare function showPlan(input: PlanShowInput): PlanShowResult;
10
+ export declare function normalizePlanStatus(status: unknown): PlanStatus | null;