@veewo/claw-core 0.1.67 → 0.1.69

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 (52) hide show
  1. package/dist/src/context.d.ts +3 -3
  2. package/dist/src/context.js +25 -67
  3. package/dist/src/context.js.map +1 -1
  4. package/dist/src/embedding-daemon-protocol.d.ts +48 -0
  5. package/dist/src/embedding-daemon-protocol.js +198 -0
  6. package/dist/src/embedding-daemon-protocol.js.map +1 -0
  7. package/dist/src/embedding-daemon.d.ts +1 -0
  8. package/dist/src/embedding-daemon.js +256 -0
  9. package/dist/src/embedding-daemon.js.map +1 -0
  10. package/dist/src/embedding-local-runtime.d.ts +8 -0
  11. package/dist/src/embedding-local-runtime.js +134 -0
  12. package/dist/src/embedding-local-runtime.js.map +1 -0
  13. package/dist/src/embedding-local.d.ts +8 -0
  14. package/dist/src/embedding-local.js +75 -38
  15. package/dist/src/embedding-local.js.map +1 -1
  16. package/dist/src/embedding-worker.js +29 -75
  17. package/dist/src/embedding-worker.js.map +1 -1
  18. package/dist/src/errors.d.ts +1 -1
  19. package/dist/src/errors.js.map +1 -1
  20. package/dist/src/index.d.ts +2 -0
  21. package/dist/src/index.js +2 -0
  22. package/dist/src/index.js.map +1 -1
  23. package/dist/src/init.js +3 -0
  24. package/dist/src/init.js.map +1 -1
  25. package/dist/src/memory.js +181 -22
  26. package/dist/src/memory.js.map +1 -1
  27. package/dist/src/plan-events.d.ts +7 -2
  28. package/dist/src/plan-events.js +3 -0
  29. package/dist/src/plan-events.js.map +1 -1
  30. package/dist/src/plan-templates.js +4 -1
  31. package/dist/src/plan-templates.js.map +1 -1
  32. package/dist/src/plan.js +94 -38
  33. package/dist/src/plan.js.map +1 -1
  34. package/dist/src/project-check.js +5 -2
  35. package/dist/src/project-check.js.map +1 -1
  36. package/dist/src/session-bindings.d.ts +5 -0
  37. package/dist/src/session-bindings.js +85 -0
  38. package/dist/src/session-bindings.js.map +1 -0
  39. package/dist/src/switch-task.js +11 -34
  40. package/dist/src/switch-task.js.map +1 -1
  41. package/dist/src/task-layout-migration.d.ts +8 -0
  42. package/dist/src/task-layout-migration.js +210 -0
  43. package/dist/src/task-layout-migration.js.map +1 -0
  44. package/dist/src/task-retention.d.ts +2 -1
  45. package/dist/src/task-retention.js +60 -27
  46. package/dist/src/task-retention.js.map +1 -1
  47. package/dist/src/types.d.ts +16 -6
  48. package/dist/src/workflow-guidance.config.json +8 -4
  49. package/dist/src/workflow-guidance.d.ts +1 -1
  50. package/dist/src/workflow-guidance.js +36 -18
  51. package/dist/src/workflow-guidance.js.map +1 -1
  52. package/package.json +1 -1
@@ -1,15 +1,19 @@
1
- import { ensureTaskMeta, resolveProjectContext, resolveTaskContext, saveTaskMeta } from "./context.js";
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ensureTaskContext, resolveProjectContext, resolveTaskContext } from "./context.js";
4
+ import { readJsonFile } from "./io.js";
2
5
  export function switchTask(input) {
3
6
  const project = resolveProjectContext(input.cwd);
4
7
  const source = resolveTaskContext(project, input.fromTask);
5
- const target = ensureTaskMeta(project, input.toTask);
8
+ const target = ensureTaskContext(project, input.toTask);
6
9
  const now = new Date().toISOString();
10
+ const sourcePlan = readJsonFile(source.activePlanPath);
7
11
  const sourceSnapshot = {
8
12
  projectId: project.projectId,
9
13
  task: source.taskName,
10
- status: source.meta.status,
11
- updatedAt: source.meta.updatedAt,
12
- activePlan: source.meta.activePlan,
14
+ status: sourcePlan.status === "end.completed" ? "completed" : sourcePlan.status.startsWith("end.") ? "paused" : "active",
15
+ updatedAt: sourcePlan.completedAt,
16
+ activePlan: source.activePlan,
13
17
  planPath: source.activePlanPath,
14
18
  };
15
19
  const leaveState = {
@@ -22,38 +26,11 @@ export function switchTask(input) {
22
26
  continueNeeded: input.reason !== "completed" && input.reason !== "abandoned",
23
27
  sourceSnapshot,
24
28
  };
25
- const inheritedFrom = {
26
- projectId: project.projectId,
27
- task: source.taskName,
28
- mode: input.mode ?? "prev_task",
29
- linkedAt: now,
30
- historyLimit: input.historyLimit ?? 5,
31
- sourceSnapshot,
32
- reason: leaveState.reason,
33
- sourceStatus: source.meta.status ?? "active",
34
- sourceUpdatedAt: source.meta.updatedAt,
35
- sourceLeaveStateUpdatedAt: leaveState.updatedAt ?? leaveState.leftAt,
36
- sourceLeaveState: leaveState,
37
- };
38
- source.meta.leaveState = leaveState;
39
- source.meta.updatedAt = now;
40
- target.meta.prevTask = source.taskName;
41
- target.meta.previousTask = {
42
- projectId: project.projectId,
43
- task: source.taskName,
44
- linkedAt: now,
45
- reason: leaveState.reason,
46
- leaveStateAt: leaveState.leftAt,
47
- };
48
- target.meta.inheritedFrom = inheritedFrom;
49
- target.meta.updatedAt = now;
50
- saveTaskMeta(source);
51
- saveTaskMeta(target);
52
29
  return {
53
30
  fromTask: source.taskName,
54
31
  toTask: target.taskName,
55
- sourceMetaPath: source.metaPath,
56
- targetMetaPath: target.metaPath,
32
+ sourcePlanPath: source.activePlanPath,
33
+ ...(fs.existsSync(path.join(target.taskDir, "plan.json")) ? { targetPlanPath: path.join(target.taskDir, "plan.json") } : {}),
57
34
  leaveState,
58
35
  };
59
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"switch-task.js","sourceRoot":"","sources":["../../src/switch-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGvG,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,cAAc,GAAuB;QACzC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,MAAM,CAAC,QAAQ;QACrB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;QAC1B,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS;QAChC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU;QAClC,QAAQ,EAAE,MAAM,CAAC,cAAc;KAChC,CAAC;IAEF,MAAM,UAAU,GAAe;QAC7B,MAAM,EAAE,GAAG;QACX,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,aAAa;QACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,QAAQ;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,cAAc,EAAE,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAC5E,cAAc;KACf,CAAC;IAEF,MAAM,aAAa,GAAkB;QACnC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,MAAM,CAAC,QAAQ;QACrB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,WAAW;QAC/B,QAAQ,EAAE,GAAG;QACb,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,CAAC;QACrC,cAAc;QACd,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ;QAC5C,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS;QACtC,yBAAyB,EAAE,UAAU,CAAC,SAAS,IAAI,UAAU,CAAC,MAAM;QACpE,gBAAgB,EAAE,UAAU;KAC7B,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACpC,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACvC,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG;QACzB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,MAAM,CAAC,QAAQ;QACrB,QAAQ,EAAE,GAAG;QACb,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,YAAY,EAAE,UAAU,CAAC,MAAM;KAChC,CAAC;IACF,MAAM,CAAC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IAC1C,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;IAE5B,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,CAAC,MAAM,CAAC,CAAC;IAErB,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,QAAQ;QACvB,cAAc,EAAE,MAAM,CAAC,QAAQ;QAC/B,cAAc,EAAE,MAAM,CAAC,QAAQ;QAC/B,UAAU;KACX,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"switch-task.js","sourceRoot":"","sources":["../../src/switch-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,YAAY,CAAe,MAAM,CAAC,cAAc,CAAC,CAAC;IAErE,MAAM,cAAc,GAAuB;QACzC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,MAAM,CAAC,QAAQ;QACrB,MAAM,EAAE,UAAU,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;QACxH,SAAS,EAAE,UAAU,CAAC,WAAW;QACjC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,MAAM,CAAC,cAAc;KAChC,CAAC;IAEF,MAAM,UAAU,GAAe;QAC7B,MAAM,EAAE,GAAG;QACX,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,aAAa;QACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,QAAQ;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,cAAc,EAAE,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAC5E,cAAc;KACf,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,QAAQ;QACvB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5H,UAAU;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ProjectContext } from "./types.js";
2
+ export type TaskLayoutMigrationResult = {
3
+ changed: boolean;
4
+ fixedPaths: string[];
5
+ };
6
+ export declare function migrateLegacyTaskLayout(project: ProjectContext): TaskLayoutMigrationResult;
7
+ export declare function taskLayoutMigrationMarkerPath(clawDir: string): string;
8
+ export declare function markTaskLayoutMigrationComplete(clawDir: string): string;
@@ -0,0 +1,210 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ClawError } from "./errors.js";
4
+ import { readJsonFile, writeJsonFile } from "./io.js";
5
+ import { ensureInsideDir, normalizePlanFile } from "./paths.js";
6
+ import { bindSessionToPlan, resolveSessionBoundPlan, unbindSession } from "./session-bindings.js";
7
+ export function migrateLegacyTaskLayout(project) {
8
+ const markerPath = taskLayoutMigrationMarkerPath(project.clawDir);
9
+ if (fs.existsSync(markerPath)) {
10
+ return { changed: false, fixedPaths: [] };
11
+ }
12
+ const taskDirs = fs.existsSync(project.tasksDir)
13
+ ? fs.readdirSync(project.tasksDir, { withFileTypes: true })
14
+ .filter((entry) => entry.isDirectory())
15
+ .map((entry) => path.join(project.tasksDir, entry.name))
16
+ : [];
17
+ const moves = taskDirs.flatMap((taskDir) => collectLegacyPlanMoves(taskDir));
18
+ validateMoves(moves);
19
+ const fixedPaths = new Set();
20
+ const bindingCandidates = new Map();
21
+ for (const taskDir of taskDirs) {
22
+ const metaPath = path.join(taskDir, "meta.json");
23
+ const legacyMeta = readLegacyMeta(metaPath);
24
+ const taskMoves = moves.filter((move) => path.dirname(move.targetPath) === taskDir);
25
+ const planFileMap = new Map(taskMoves.map((move) => [move.sourcePlanFile, move.targetPlanFile]));
26
+ rewriteTaskPlanReferences(taskDir, taskMoves, planFileMap, fixedPaths, project);
27
+ for (const move of taskMoves) {
28
+ fs.renameSync(move.sourcePath, move.targetPath);
29
+ fixedPaths.add(toProjectRelativePath(project, move.sourcePath));
30
+ fixedPaths.add(toProjectRelativePath(project, move.targetPath));
31
+ }
32
+ removeEmptyLegacyPlanDirectories(path.join(taskDir, "plans"));
33
+ if (legacyMeta) {
34
+ collectBindingCandidate(taskDir, legacyMeta, planFileMap, bindingCandidates);
35
+ fs.unlinkSync(metaPath);
36
+ fixedPaths.add(toProjectRelativePath(project, metaPath));
37
+ }
38
+ }
39
+ applyBindingCandidates(project, bindingCandidates, fixedPaths);
40
+ markTaskLayoutMigrationComplete(project.clawDir);
41
+ fixedPaths.add(toProjectRelativePath(project, markerPath));
42
+ return { changed: fixedPaths.size > 0, fixedPaths: [...fixedPaths] };
43
+ }
44
+ export function taskLayoutMigrationMarkerPath(clawDir) {
45
+ return path.join(clawDir, "runtime", "task-layout-v2.complete");
46
+ }
47
+ export function markTaskLayoutMigrationComplete(clawDir) {
48
+ const markerPath = taskLayoutMigrationMarkerPath(clawDir);
49
+ fs.mkdirSync(path.dirname(markerPath), { recursive: true });
50
+ fs.writeFileSync(markerPath, "", "utf-8");
51
+ return markerPath;
52
+ }
53
+ function collectLegacyPlanMoves(taskDir) {
54
+ const plansDir = path.join(taskDir, "plans");
55
+ if (!fs.existsSync(plansDir)) {
56
+ return [];
57
+ }
58
+ return fs.readdirSync(plansDir, { recursive: true, withFileTypes: true })
59
+ .filter((entry) => entry.isFile())
60
+ .map((entry) => {
61
+ const sourcePath = path.join(entry.parentPath, entry.name);
62
+ if (path.extname(entry.name).toLowerCase() !== ".json") {
63
+ throw new ClawError("PROJECT_CONFIG_INVALID", `Legacy plans directory contains a non-JSON file: ${sourcePath}`, {
64
+ path: sourcePath,
65
+ });
66
+ }
67
+ const sourcePlanFile = path.relative(taskDir, sourcePath).replace(/\\/g, "/");
68
+ const targetPlanFile = normalizePlanFile(path.basename(sourcePath));
69
+ return {
70
+ sourcePath,
71
+ targetPath: path.join(taskDir, targetPlanFile),
72
+ sourcePlanFile,
73
+ targetPlanFile,
74
+ };
75
+ });
76
+ }
77
+ function validateMoves(moves) {
78
+ const targets = new Set();
79
+ for (const move of moves) {
80
+ const normalizedTarget = path.resolve(move.targetPath).toLowerCase();
81
+ if (targets.has(normalizedTarget) || fs.existsSync(move.targetPath)) {
82
+ throw new ClawError("PLAN_ALREADY_EXISTS", `Cannot flatten legacy subplan because "${move.targetPlanFile}" already exists.`, {
83
+ sourcePath: move.sourcePath,
84
+ targetPath: move.targetPath,
85
+ });
86
+ }
87
+ targets.add(normalizedTarget);
88
+ }
89
+ }
90
+ function rewriteTaskPlanReferences(taskDir, moves, planFileMap, fixedPaths, project) {
91
+ const planPaths = [
92
+ ...fs.readdirSync(taskDir, { withFileTypes: true })
93
+ .filter((entry) => entry.isFile() && path.extname(entry.name).toLowerCase() === ".json" && entry.name !== "meta.json")
94
+ .map((entry) => path.join(taskDir, entry.name)),
95
+ ...moves.map((move) => move.sourcePath),
96
+ ];
97
+ for (const planPath of planPaths) {
98
+ let plan;
99
+ try {
100
+ plan = readJsonFile(planPath);
101
+ }
102
+ catch {
103
+ continue;
104
+ }
105
+ let changed = false;
106
+ const mappedParent = mapLegacyPlanFile(plan.parentPlan, planFileMap);
107
+ if (mappedParent && mappedParent !== plan.parentPlan) {
108
+ plan.parentPlan = mappedParent;
109
+ changed = true;
110
+ }
111
+ for (const task of Array.isArray(plan.tasks) ? plan.tasks : []) {
112
+ if (!task.execution) {
113
+ continue;
114
+ }
115
+ const mappedSubplan = mapLegacyPlanFile(task.execution.subplan, planFileMap);
116
+ const mappedPlanPath = mapLegacyPlanFile(task.execution.planPath, planFileMap);
117
+ if (mappedSubplan && mappedSubplan !== task.execution.subplan) {
118
+ task.execution.subplan = mappedSubplan;
119
+ changed = true;
120
+ }
121
+ if (mappedPlanPath && mappedPlanPath !== task.execution.planPath) {
122
+ task.execution.planPath = mappedPlanPath;
123
+ changed = true;
124
+ }
125
+ }
126
+ if (changed) {
127
+ writeJsonFile(planPath, plan);
128
+ fixedPaths.add(toProjectRelativePath(project, planPath));
129
+ }
130
+ }
131
+ }
132
+ function mapLegacyPlanFile(value, planFileMap) {
133
+ if (!value) {
134
+ return value;
135
+ }
136
+ return planFileMap.get(value.replace(/\\/g, "/")) ?? value;
137
+ }
138
+ function collectBindingCandidate(taskDir, meta, planFileMap, candidates) {
139
+ const sessionKey = typeof meta.ownerSessionKey === "string" ? meta.ownerSessionKey.trim() : "";
140
+ if (!sessionKey) {
141
+ return;
142
+ }
143
+ const legacyActivePlan = typeof meta.activePlan === "string" ? meta.activePlan.replace(/\\/g, "/") : "plan.json";
144
+ const planFile = planFileMap.get(legacyActivePlan) ?? normalizePlanFile(legacyActivePlan);
145
+ const planPath = ensureInsideDir(taskDir, planFile);
146
+ if (!planPath || !isOpenPlan(planPath)) {
147
+ return;
148
+ }
149
+ const updatedAt = typeof meta.updatedAt === "string" ? meta.updatedAt : "";
150
+ const current = candidates.get(sessionKey);
151
+ if (!current || updatedAt > current.updatedAt) {
152
+ candidates.set(sessionKey, { sessionKey, planPath, updatedAt });
153
+ }
154
+ }
155
+ function applyBindingCandidates(project, candidates, fixedPaths) {
156
+ for (const candidate of candidates.values()) {
157
+ const existingPlanPath = resolveSessionBoundPlan(project, candidate.sessionKey);
158
+ if (existingPlanPath && isOpenPlan(existingPlanPath)) {
159
+ continue;
160
+ }
161
+ if (existingPlanPath) {
162
+ unbindSession(project, candidate.sessionKey);
163
+ }
164
+ bindSessionToPlan(project, candidate.sessionKey, candidate.planPath);
165
+ fixedPaths.add(".claw/runtime/session-bindings.json");
166
+ }
167
+ }
168
+ function isOpenPlan(planPath) {
169
+ if (!fs.existsSync(planPath)) {
170
+ return false;
171
+ }
172
+ try {
173
+ const plan = readJsonFile(planPath);
174
+ return typeof plan.status === "string" && !plan.status.startsWith("end.");
175
+ }
176
+ catch {
177
+ return false;
178
+ }
179
+ }
180
+ function readLegacyMeta(metaPath) {
181
+ if (!fs.existsSync(metaPath)) {
182
+ return undefined;
183
+ }
184
+ try {
185
+ return readJsonFile(metaPath);
186
+ }
187
+ catch (error) {
188
+ throw new ClawError("PROJECT_CONFIG_INVALID", `Failed to parse legacy task metadata: ${metaPath}`, {
189
+ path: metaPath,
190
+ cause: error instanceof Error ? error.message : String(error),
191
+ });
192
+ }
193
+ }
194
+ function removeEmptyLegacyPlanDirectories(plansDir) {
195
+ if (!fs.existsSync(plansDir)) {
196
+ return;
197
+ }
198
+ for (const entry of fs.readdirSync(plansDir, { withFileTypes: true })) {
199
+ if (entry.isDirectory()) {
200
+ removeEmptyLegacyPlanDirectories(path.join(plansDir, entry.name));
201
+ }
202
+ }
203
+ if (fs.readdirSync(plansDir).length === 0) {
204
+ fs.rmdirSync(plansDir);
205
+ }
206
+ }
207
+ function toProjectRelativePath(project, absolutePath) {
208
+ return path.relative(project.projectRoot, absolutePath).replace(/\\/g, "/");
209
+ }
210
+ //# sourceMappingURL=task-layout-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-layout-migration.js","sourceRoot":"","sources":["../../src/task-layout-migration.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  import type { ProjectContext, TaskRetentionResult } from "./types.js";
2
- export declare function enforceTaskRetention(project: ProjectContext, currentTaskName?: string): TaskRetentionResult;
2
+ export declare const COMPLETED_TASK_ARCHIVE_DELAY_MS: number;
3
+ export declare function enforceTaskRetention(project: ProjectContext, currentTaskName?: string, nowMs?: number): TaskRetentionResult;
@@ -1,13 +1,14 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { readJsonFile } from "./io.js";
4
- export function enforceTaskRetention(project, currentTaskName) {
4
+ export const COMPLETED_TASK_ARCHIVE_DELAY_MS = 60 * 60 * 1000;
5
+ export function enforceTaskRetention(project, currentTaskName, nowMs = Date.now()) {
5
6
  const maxTasksToKeep = project.projectConfig?.maxTasksToKeep ?? 99;
6
7
  const archiveTasksRoot = path.join(project.clawDir, "archive", "tasks");
7
8
  const prunedArchivedTasks = [];
8
9
  let archivedCurrentTask;
9
10
  for (const taskName of listActiveTaskNames(project)) {
10
- const archivedTask = archiveTaskDirectory(project, taskName, archiveTasksRoot);
11
+ const archivedTask = archiveTaskDirectory(project, taskName, archiveTasksRoot, nowMs);
11
12
  if (archivedTask && taskName === currentTaskName) {
12
13
  archivedCurrentTask = archivedTask;
13
14
  }
@@ -16,7 +17,7 @@ export function enforceTaskRetention(project, currentTaskName) {
16
17
  if (archivedTasks.length > maxTasksToKeep) {
17
18
  const overflow = archivedTasks.length - maxTasksToKeep;
18
19
  const toPrune = archivedTasks
19
- .sort(compareArchivedTasksByUpdatedAt)
20
+ .sort(compareArchivedTasksByCompletedAt)
20
21
  .slice(0, overflow);
21
22
  for (const archivedTask of toPrune) {
22
23
  removeDirectoryTreeSync(archivedTask.archivedTaskDir);
@@ -30,35 +31,59 @@ export function enforceTaskRetention(project, currentTaskName) {
30
31
  prunedArchivedTasks,
31
32
  };
32
33
  }
33
- function archiveTaskDirectory(project, taskName, archiveTasksRoot) {
34
+ function archiveTaskDirectory(project, taskName, archiveTasksRoot, nowMs) {
34
35
  const sourceTaskDir = path.join(project.tasksDir, taskName);
35
36
  if (!fs.existsSync(sourceTaskDir) || !fs.statSync(sourceTaskDir).isDirectory()) {
36
37
  return undefined;
37
38
  }
38
- const metaPath = path.join(sourceTaskDir, "meta.json");
39
- if (!fs.existsSync(metaPath)) {
39
+ const rootPlanPath = path.join(sourceTaskDir, "plan.json");
40
+ const legacyMetaPath = path.join(sourceTaskDir, "meta.json");
41
+ const legacyMeta = fs.existsSync(legacyMetaPath) ? readJsonFile(legacyMetaPath) : undefined;
42
+ const activePlanPath = fs.existsSync(rootPlanPath)
43
+ ? rootPlanPath
44
+ : typeof legacyMeta?.activePlan === "string"
45
+ ? path.join(sourceTaskDir, legacyMeta.activePlan)
46
+ : undefined;
47
+ if (!activePlanPath || !fs.existsSync(activePlanPath)) {
40
48
  return undefined;
41
49
  }
42
- const meta = readJsonFile(metaPath);
43
- const activePlanPath = typeof meta.activePlan === "string" ? path.join(sourceTaskDir, meta.activePlan) : undefined;
44
- const planStatus = activePlanPath && fs.existsSync(activePlanPath)
45
- ? readJsonFile(activePlanPath).status
46
- : undefined;
47
- if (meta.status !== "completed" && planStatus !== "end.completed") {
50
+ const completedAt = readJsonFile(activePlanPath).completedAt;
51
+ const completedAtMs = typeof completedAt === "string" ? Date.parse(completedAt) : Number.NaN;
52
+ if (!Number.isFinite(completedAtMs) || nowMs - completedAtMs < COMPLETED_TASK_ARCHIVE_DELAY_MS) {
48
53
  return undefined;
49
54
  }
50
55
  fs.mkdirSync(archiveTasksRoot, { recursive: true });
51
56
  const archivedTaskDir = uniqueArchiveTaskDir(archiveTasksRoot, taskName);
52
- fs.renameSync(sourceTaskDir, archivedTaskDir);
53
- const archivedPlanPath = typeof meta.activePlan === "string" ? path.join(archivedTaskDir, meta.activePlan) : undefined;
57
+ renameDirectoryWithRetry(sourceTaskDir, archivedTaskDir);
58
+ const archivedPlanPath = activePlanPath
59
+ ? path.join(archivedTaskDir, path.relative(sourceTaskDir, activePlanPath))
60
+ : undefined;
54
61
  return {
55
62
  taskName,
56
63
  sourceTaskDir,
57
64
  archivedTaskDir,
58
65
  ...(archivedPlanPath ? { archivedPlanPath } : {}),
59
- ...(meta.updatedAt ? { updatedAt: meta.updatedAt } : {}),
66
+ ...(completedAt ? { completedAt } : {}),
60
67
  };
61
68
  }
69
+ function renameDirectoryWithRetry(sourceDir, targetDir) {
70
+ const retryDelaysMs = [0, 50, 150, 300];
71
+ for (let attempt = 0; attempt < retryDelaysMs.length; attempt += 1) {
72
+ try {
73
+ fs.renameSync(sourceDir, targetDir);
74
+ return;
75
+ }
76
+ catch (error) {
77
+ const code = error.code;
78
+ const retryable = code === "EPERM" || code === "EBUSY" || code === "EACCES";
79
+ if (!retryable || attempt === retryDelaysMs.length - 1) {
80
+ throw error;
81
+ }
82
+ const delayMs = retryDelaysMs[attempt + 1];
83
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delayMs);
84
+ }
85
+ }
86
+ }
62
87
  function listActiveTaskNames(project) {
63
88
  if (!fs.existsSync(project.tasksDir)) {
64
89
  return [];
@@ -78,16 +103,24 @@ function listArchivedTasks(archiveTasksRoot) {
78
103
  continue;
79
104
  }
80
105
  const archivedTaskDir = path.join(archiveTasksRoot, child.name);
81
- const metaPath = path.join(archivedTaskDir, "meta.json");
82
- let updatedAt;
106
+ const rootPlanPath = path.join(archivedTaskDir, "plan.json");
107
+ let completedAt;
83
108
  let taskName = child.name;
84
109
  let archivedPlanPath;
85
- if (fs.existsSync(metaPath)) {
86
- const meta = readJsonFile(metaPath);
87
- updatedAt = meta.updatedAt;
88
- taskName = typeof meta.name === "string" && meta.name.trim() ? meta.name : child.name;
89
- if (typeof meta.activePlan === "string" && meta.activePlan.trim()) {
90
- archivedPlanPath = path.join(archivedTaskDir, meta.activePlan);
110
+ if (fs.existsSync(rootPlanPath)) {
111
+ const plan = readJsonFile(rootPlanPath);
112
+ completedAt = plan.completedAt;
113
+ archivedPlanPath = rootPlanPath;
114
+ }
115
+ else {
116
+ const metaPath = path.join(archivedTaskDir, "meta.json");
117
+ if (fs.existsSync(metaPath)) {
118
+ const meta = readJsonFile(metaPath);
119
+ completedAt = meta.updatedAt;
120
+ taskName = typeof meta.name === "string" && meta.name.trim() ? meta.name : child.name;
121
+ if (typeof meta.activePlan === "string" && meta.activePlan.trim()) {
122
+ archivedPlanPath = path.join(archivedTaskDir, meta.activePlan);
123
+ }
91
124
  }
92
125
  }
93
126
  entries.push({
@@ -95,14 +128,14 @@ function listArchivedTasks(archiveTasksRoot) {
95
128
  sourceTaskDir: "",
96
129
  archivedTaskDir,
97
130
  ...(archivedPlanPath ? { archivedPlanPath } : {}),
98
- ...(updatedAt ? { updatedAt } : {}),
131
+ ...(completedAt ? { completedAt } : {}),
99
132
  });
100
133
  }
101
134
  return entries;
102
135
  }
103
- function compareArchivedTasksByUpdatedAt(left, right) {
104
- const leftTime = left.updatedAt ? Date.parse(left.updatedAt) : Number.NEGATIVE_INFINITY;
105
- const rightTime = right.updatedAt ? Date.parse(right.updatedAt) : Number.NEGATIVE_INFINITY;
136
+ function compareArchivedTasksByCompletedAt(left, right) {
137
+ const leftTime = left.completedAt ? Date.parse(left.completedAt) : Number.NEGATIVE_INFINITY;
138
+ const rightTime = right.completedAt ? Date.parse(right.completedAt) : Number.NEGATIVE_INFINITY;
106
139
  if (leftTime !== rightTime) {
107
140
  return leftTime - rightTime;
108
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"task-retention.js","sourceRoot":"","sources":["../../src/task-retention.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"task-retention.js","sourceRoot":"","sources":["../../src/task-retention.ts"],"names":[],"mappings":"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"}
@@ -87,6 +87,7 @@ export type PlanDocument = {
87
87
  templateId?: string;
88
88
  configOverride?: TemplateConfigOverride;
89
89
  status: PlanStatus;
90
+ completedAt?: string;
90
91
  goal: {
91
92
  text: string;
92
93
  };
@@ -371,10 +372,10 @@ export type TaskContext = {
371
372
  project: ProjectContext;
372
373
  taskName: string;
373
374
  taskDir: string;
374
- metaPath: string;
375
- meta: TaskMeta;
376
375
  activePlan: string;
377
376
  activePlanPath: string;
377
+ legacyMetaPath?: string;
378
+ legacyMeta?: TaskMeta;
378
379
  };
379
380
  export type ResolvedContext = {
380
381
  project: ProjectContext;
@@ -401,7 +402,6 @@ export type PlanWriteInput = {
401
402
  export type PlanWriteResult = {
402
403
  taskName: string;
403
404
  taskDir: string;
404
- metaPath: string;
405
405
  planPath: string;
406
406
  planFile: string;
407
407
  planStatus: PlanStatus;
@@ -433,9 +433,12 @@ export type PlanEditInput = {
433
433
  taskStatus?: PlanTaskStatus;
434
434
  taskChoiceId?: string;
435
435
  appendTasks?: PlanTask[];
436
+ completeLifecycleBridge?: boolean;
437
+ commandSource?: "plan.edit" | "plan.start" | "plan.done";
436
438
  reviewer?: PlanReviewer;
437
439
  workflowDefinitions?: string;
438
440
  host?: string;
441
+ ownerSessionKey?: string;
439
442
  };
440
443
  export type PlanEditResult = {
441
444
  taskName: string;
@@ -449,6 +452,7 @@ export type PlanEditResult = {
449
452
  planReview?: PlanReviewResult;
450
453
  completionHooks?: PlanCompletionHooks;
451
454
  workflowGuidance: WorkflowGuidance;
455
+ plan: PlanDocument;
452
456
  planView: PlanViewModel;
453
457
  };
454
458
  export type PlanShowInput = {
@@ -475,8 +479,8 @@ export type SwitchTaskInput = {
475
479
  export type SwitchTaskResult = {
476
480
  fromTask: string;
477
481
  toTask: string;
478
- sourceMetaPath: string;
479
- targetMetaPath: string;
482
+ sourcePlanPath: string;
483
+ targetPlanPath?: string;
480
484
  leaveState: LeaveState;
481
485
  };
482
486
  export type MemoryScope = "project" | "task";
@@ -524,6 +528,12 @@ export type MemorySearchResult = {
524
528
  scope: MemoryScope;
525
529
  storePath: string;
526
530
  results: MemorySearchResultEntry[];
531
+ telemetry: {
532
+ route: "task_fts" | "lexical_fast_path" | "hybrid";
533
+ queryEmbedding: "skipped" | "cache_hit" | "generated";
534
+ embeddingRuntime?: "mock" | "persistent_daemon" | "one_shot" | "remote";
535
+ durationMs: number;
536
+ };
527
537
  };
528
538
  export type MemoryGetInput = {
529
539
  cwd: string;
@@ -574,7 +584,7 @@ export type ArchivedTaskRecord = {
574
584
  sourceTaskDir: string;
575
585
  archivedTaskDir: string;
576
586
  archivedPlanPath?: string;
577
- updatedAt?: string;
587
+ completedAt?: string;
578
588
  };
579
589
  export type TaskRetentionResult = {
580
590
  enabled: boolean;
@@ -3,6 +3,10 @@
3
3
  "withGoal": "Using claw-kit, update plan, follow returned workflowGuidance,finish your goal:{{planGoal}}",
4
4
  "withoutGoal": "Using claw-kit, update plan, follow returned workflowGuidance,finish your goal."
5
5
  },
6
+ "planCreateRecall": {
7
+ "nextstep": "Run one project recall query.",
8
+ "recommendedCommand": "claw search --query \"<topic>\""
9
+ },
6
10
  "delegates": {
7
11
  "truthWriter": {
8
12
  "name": "truth-writer",
@@ -24,7 +28,7 @@
24
28
  "fork_context": false,
25
29
  "waitForCompletion": false,
26
30
  "preferReuseSameTypeInThread": true,
27
- "inputContract": "updated completed plan.json containing retrospective and durable keyDecisions; decision extraction and canonical target routing belong to the ADR writer",
31
+ "inputContract": "updated active root plan.json path after retrospective and durable keyDecisions are persisted; plan done retains this path for at least one hour so the ADR writer can continue asynchronously; decision extraction and canonical target routing belong to the ADR writer",
28
32
  "outputContract": "optional telemetry only",
29
33
  "closePolicy": "keep_open_for_reuse"
30
34
  }
@@ -131,9 +135,9 @@
131
135
  "nextsteps": [
132
136
  "1. Clear thread progress with `update_plan`.",
133
137
  "2. Read the returned `truth-writer` entry's `dispatch`. For `when_reusable_truth_confirmed`, the main agent must evaluate reusable truth and dispatch only after confirmation.",
134
- "3. First write both `retrospective` and `keyDecisions` back into the plan, then execute the `adr-writer` contract with `dispatch: required` using that updated completed `plan.json`."
138
+ "3. First write both `retrospective` and `keyDecisions` back into the plan, then execute the `adr-writer` contract with `dispatch: required` using that updated active root `plan.json` path. Do not wait for the writer before running `claw plan done`; delayed archive keeps the path readable for at least one hour."
135
139
  ],
136
- "notes": "Truth dispatch requires the main agent's reusable-value confirmation; ADR dispatch is required for root-plan closeout. Honor every field in a dispatched delegate contract.",
140
+ "notes": "Truth dispatch requires the main agent's reusable-value confirmation; ADR dispatch is required but remains asynchronous for root-plan closeout. Root `claw plan done` records completedAt and keeps the plan path readable for at least one hour. Honor every field in a dispatched delegate contract.",
137
141
  "recommendedCommands": [
138
142
  "{{editBase}} --patch <completed-plan.json>",
139
143
  "{{doneBase}} --summary \"<retrospective summary>\""
@@ -297,7 +301,7 @@
297
301
  ],
298
302
  "notes": "Use the seeded planning task to refine the request and append executable tasks before execution begins.",
299
303
  "recommendedCommands": [
300
- "{{editBase}} --plan-status process.active"
304
+ "{{startBase}} --patch <plan-patch.json> --append-tasks <tasks.json>"
301
305
  ]
302
306
  },
303
307
  "process.discussing.noGoalMode": {
@@ -8,7 +8,7 @@ export declare function buildPlanWorkflowGuidance(params: {
8
8
  taskName: string;
9
9
  planFile: string;
10
10
  plan: PlanDocument;
11
- commandSource?: "plan.create" | "subplan.create" | "plan.edit" | "plan.done";
11
+ commandSource?: "plan.create" | "subplan.create" | "plan.edit" | "plan.start" | "plan.done";
12
12
  projectRoot?: string;
13
13
  projectConfig?: ProjectConfig | null;
14
14
  previousStatus?: PlanStatus;