@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,238 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ClawError } from "./errors.js";
4
+ import { findProjectRoot, normalizeTaskName } from "./paths.js";
5
+ const DEFAULT_MAX_TASKS_TO_KEEP = 99;
6
+ export function checkProjectProtocol(cwd) {
7
+ const projectRoot = findRequiredProjectRoot(cwd);
8
+ const projectJsonPath = path.join(projectRoot, ".claw", "project.json");
9
+ const { raw, issues } = readRawProjectConfig(projectJsonPath);
10
+ if (raw !== undefined) {
11
+ validateProjectConfig(raw, issues);
12
+ }
13
+ return {
14
+ ok: issues.length === 0,
15
+ projectRoot,
16
+ projectJsonPath,
17
+ issues,
18
+ };
19
+ }
20
+ export function ensureProjectProtocol(cwd) {
21
+ const projectRoot = findRequiredProjectRoot(cwd);
22
+ const projectJsonPath = path.join(projectRoot, ".claw", "project.json");
23
+ const { raw, issues } = readRawProjectConfig(projectJsonPath);
24
+ if (raw !== undefined) {
25
+ validateProjectConfig(raw, issues);
26
+ }
27
+ const normalized = normalizeProjectConfig(raw, projectRoot);
28
+ const normalizedText = `${JSON.stringify(normalized, null, 2)}\n`;
29
+ const previousText = fs.existsSync(projectJsonPath) ? fs.readFileSync(projectJsonPath, "utf-8") : null;
30
+ const changed = previousText !== normalizedText;
31
+ if (changed) {
32
+ fs.mkdirSync(path.dirname(projectJsonPath), { recursive: true });
33
+ fs.writeFileSync(projectJsonPath, normalizedText, "utf-8");
34
+ }
35
+ return {
36
+ ok: true,
37
+ changed,
38
+ projectRoot,
39
+ projectJsonPath,
40
+ issueCountBefore: issues.length,
41
+ issueCountAfter: 0,
42
+ fixedPaths: collectFixedPaths(issues, changed),
43
+ issuesBefore: issues,
44
+ issuesAfter: [],
45
+ projectConfig: normalized,
46
+ };
47
+ }
48
+ function findRequiredProjectRoot(cwd) {
49
+ const projectRoot = findProjectRoot(cwd);
50
+ if (!projectRoot) {
51
+ throw new ClawError("CLAW_DIR_NOT_FOUND", `No .claw directory was found from ${cwd}.`, { cwd });
52
+ }
53
+ return projectRoot;
54
+ }
55
+ function readRawProjectConfig(projectJsonPath) {
56
+ if (!fs.existsSync(projectJsonPath)) {
57
+ return {
58
+ raw: undefined,
59
+ issues: [{ path: "project.json", message: "Missing .claw/project.json." }],
60
+ };
61
+ }
62
+ try {
63
+ return {
64
+ raw: JSON.parse(fs.readFileSync(projectJsonPath, "utf-8")),
65
+ issues: [],
66
+ };
67
+ }
68
+ catch (error) {
69
+ return {
70
+ raw: undefined,
71
+ issues: [
72
+ {
73
+ path: "project.json",
74
+ message: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,
75
+ },
76
+ ],
77
+ };
78
+ }
79
+ }
80
+ function normalizeProjectConfig(raw, projectRoot) {
81
+ const source = asObject(raw);
82
+ const { autoAchieveTask: _autoAchieveTask, ...sourceWithoutLegacyAutoAchieve } = source ?? {};
83
+ const sourceMemory = asObject(source?.memory);
84
+ const sourceGitnexus = asObject(source?.gitnexus);
85
+ const maxTasksToKeep = source?.maxTasksToKeep;
86
+ return {
87
+ ...sourceWithoutLegacyAutoAchieve,
88
+ id: deriveProjectId(source, projectRoot),
89
+ name: deriveProjectName(source, projectRoot),
90
+ maxTasksToKeep: Number.isInteger(maxTasksToKeep) && maxTasksToKeep >= 1
91
+ ? maxTasksToKeep
92
+ : DEFAULT_MAX_TASKS_TO_KEEP,
93
+ externalTruthSkill: normalizeOptionalSkill(source?.externalTruthSkill),
94
+ externalAdrSkill: normalizeOptionalSkill(source?.externalAdrSkill),
95
+ contextPaths: normalizeStringArray(source?.contextPaths),
96
+ memory: {
97
+ ...sourceMemory,
98
+ externalDocPaths: normalizeStringArray(sourceMemory?.externalDocPaths),
99
+ },
100
+ gitnexus: {
101
+ ...sourceGitnexus,
102
+ enabled: typeof sourceGitnexus?.enabled === "boolean" ? sourceGitnexus.enabled : false,
103
+ },
104
+ };
105
+ }
106
+ function deriveProjectId(source, projectRoot) {
107
+ const id = source ? readNonEmptyString(source.id) : undefined;
108
+ const name = source ? readNonEmptyString(source.name) : undefined;
109
+ const candidates = [id, name, path.basename(projectRoot)];
110
+ for (const candidate of candidates) {
111
+ if (!candidate) {
112
+ continue;
113
+ }
114
+ const normalized = normalizeTaskName(candidate).toLowerCase();
115
+ if (normalized) {
116
+ return normalized;
117
+ }
118
+ }
119
+ throw new ClawError("PROJECT_ROOT_NOT_FOUND", "Unable to derive a project id.", { projectRoot });
120
+ }
121
+ function deriveProjectName(source, projectRoot) {
122
+ return (source ? readNonEmptyString(source.name) : undefined) ?? path.basename(projectRoot);
123
+ }
124
+ function collectFixedPaths(issues, changed) {
125
+ const paths = new Set(issues.map((issue) => issue.path));
126
+ if (changed && paths.size === 0) {
127
+ paths.add("project.json");
128
+ }
129
+ return [...paths];
130
+ }
131
+ function validateProjectConfig(raw, issues) {
132
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
133
+ issues.push({ path: "project.json", message: "project.json must contain a JSON object." });
134
+ return;
135
+ }
136
+ const config = raw;
137
+ requireString(config, "id", issues);
138
+ requireString(config, "name", issues);
139
+ requireIntegerAtLeast(config, "maxTasksToKeep", 1, issues);
140
+ requireNullableString(config, "externalTruthSkill", issues);
141
+ requireNullableString(config, "externalAdrSkill", issues);
142
+ requireStringArray(config, "contextPaths", issues);
143
+ const memory = requireObject(config, "memory", issues);
144
+ if (memory) {
145
+ requireStringArray(memory, "externalDocPaths", issues, "memory.externalDocPaths");
146
+ }
147
+ const gitnexus = requireObject(config, "gitnexus", issues);
148
+ if (gitnexus) {
149
+ requireBoolean(gitnexus, "enabled", issues, "gitnexus.enabled");
150
+ }
151
+ }
152
+ function requireString(source, key, issues, label = key) {
153
+ if (!(key in source)) {
154
+ issues.push({ path: label, message: "Field is required and must be explicitly present." });
155
+ return;
156
+ }
157
+ if (typeof source[key] !== "string" || !String(source[key]).trim()) {
158
+ issues.push({ path: label, message: "Field must be a non-empty string." });
159
+ }
160
+ }
161
+ function requireNullableString(source, key, issues, label = key) {
162
+ if (!(key in source)) {
163
+ issues.push({ path: label, message: "Field is required and must be explicitly present." });
164
+ return;
165
+ }
166
+ const value = source[key];
167
+ if (value !== null && typeof value !== "string") {
168
+ issues.push({ path: label, message: "Field must be a string or null." });
169
+ }
170
+ }
171
+ function requireBoolean(source, key, issues, label = key) {
172
+ if (!(key in source)) {
173
+ issues.push({ path: label, message: "Field is required and must be explicitly present." });
174
+ return;
175
+ }
176
+ if (typeof source[key] !== "boolean") {
177
+ issues.push({ path: label, message: "Field must be a boolean." });
178
+ }
179
+ }
180
+ function requireIntegerAtLeast(source, key, minimum, issues, label = key) {
181
+ if (!(key in source)) {
182
+ issues.push({ path: label, message: "Field is required and must be explicitly present." });
183
+ return;
184
+ }
185
+ const value = source[key];
186
+ if (!Number.isInteger(value) || value < minimum) {
187
+ issues.push({ path: label, message: `Field must be an integer greater than or equal to ${minimum}.` });
188
+ }
189
+ }
190
+ function requireStringArray(source, key, issues, label = key) {
191
+ if (!(key in source)) {
192
+ issues.push({ path: label, message: "Field is required and must be explicitly present." });
193
+ return;
194
+ }
195
+ const value = source[key];
196
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
197
+ issues.push({ path: label, message: "Field must be an array of strings." });
198
+ }
199
+ }
200
+ function requireObject(source, key, issues, label = key) {
201
+ if (!(key in source)) {
202
+ issues.push({ path: label, message: "Field is required and must be explicitly present." });
203
+ return null;
204
+ }
205
+ const value = source[key];
206
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
207
+ issues.push({ path: label, message: "Field must be an object." });
208
+ return null;
209
+ }
210
+ return value;
211
+ }
212
+ function asObject(value) {
213
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
214
+ return null;
215
+ }
216
+ return value;
217
+ }
218
+ function normalizeStringArray(value) {
219
+ if (!Array.isArray(value)) {
220
+ return [];
221
+ }
222
+ return value.filter((item) => typeof item === "string");
223
+ }
224
+ function readNonEmptyString(value) {
225
+ if (typeof value !== "string") {
226
+ return undefined;
227
+ }
228
+ const trimmed = value.trim();
229
+ return trimmed ? trimmed : undefined;
230
+ }
231
+ function normalizeOptionalSkill(value) {
232
+ if (typeof value !== "string") {
233
+ return null;
234
+ }
235
+ const trimmed = value.trim();
236
+ return trimmed ? trimmed : null;
237
+ }
238
+ //# sourceMappingURL=project-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-check.js","sourceRoot":"","sources":["../../src/project-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { PlanDocument, PlanReviewResult, PlanReviewer, PlanStatus } from "./types.js";
2
+ export declare const REQUIREMENTS_NEXT_ACTION: "collect_requirements";
3
+ export declare const REQUIREMENTS_INSTRUCTION = "Collect requirements first. Clarify scope if needed, then update goal, rules, references, and tasks before moving to process.active/process.wait/process.discussing.";
4
+ export declare const REVIEW_NEXT_ACTION: "revise_plan_from_review";
5
+ export declare const REVIEW_INSTRUCTION = "Plan review found actionable feedback. Revise goal, rules, references, and tasks using planReview, then move to process.active/process.wait/process.discussing.";
6
+ export declare const REVIEW_ADDRESSED_INSTRUCTION = "Review feedback is considered addressed. Continue with the selected process status.";
7
+ export declare function runPlanReview(params: {
8
+ reviewer?: PlanReviewer;
9
+ planContent: PlanDocument;
10
+ previousStatus?: PlanStatus;
11
+ targetStatus: PlanStatus;
12
+ workflowDefinitions?: string;
13
+ projectId?: string;
14
+ taskName?: string;
15
+ }): Promise<{
16
+ nextStatus: PlanStatus;
17
+ planReview?: PlanReviewResult;
18
+ nextAction?: "revise_plan_from_review" | "proceed";
19
+ instruction?: string;
20
+ }>;
21
+ export declare function shouldRunRequirementsExitReview(previousStatus: PlanStatus | undefined, targetStatus: PlanStatus): boolean;
22
+ export declare function hasActionableReviewFeedback(review: PlanReviewResult): boolean;
23
+ export declare function isProcessStatus(status: PlanStatus): boolean;
@@ -0,0 +1,49 @@
1
+ export const REQUIREMENTS_NEXT_ACTION = "collect_requirements";
2
+ export const REQUIREMENTS_INSTRUCTION = "Collect requirements first. Clarify scope if needed, then update goal, rules, references, and tasks before moving to process.active/process.wait/process.discussing.";
3
+ export const REVIEW_NEXT_ACTION = "revise_plan_from_review";
4
+ export const REVIEW_INSTRUCTION = "Plan review found actionable feedback. Revise goal, rules, references, and tasks using planReview, then move to process.active/process.wait/process.discussing.";
5
+ export const REVIEW_ADDRESSED_INSTRUCTION = "Review feedback is considered addressed. Continue with the selected process status.";
6
+ export async function runPlanReview(params) {
7
+ if (!params.reviewer) {
8
+ return { nextStatus: params.targetStatus };
9
+ }
10
+ if (!shouldRunRequirementsExitReview(params.previousStatus, params.targetStatus)) {
11
+ return { nextStatus: params.targetStatus };
12
+ }
13
+ const review = await params.reviewer({
14
+ planContent: params.planContent,
15
+ isSubPlan: Boolean(params.planContent.parentPlan || params.planContent.parentTaskId),
16
+ workflowDefinitions: params.workflowDefinitions,
17
+ projectId: params.projectId,
18
+ taskName: params.taskName,
19
+ });
20
+ if (!review || !hasActionableReviewFeedback(review)) {
21
+ return {
22
+ nextStatus: params.targetStatus,
23
+ ...(review ? { planReview: review, nextAction: "proceed" } : {}),
24
+ ...(review ? { instruction: REVIEW_ADDRESSED_INSTRUCTION } : {}),
25
+ };
26
+ }
27
+ return {
28
+ nextStatus: "prepare.review",
29
+ planReview: review,
30
+ nextAction: "revise_plan_from_review",
31
+ instruction: REVIEW_INSTRUCTION,
32
+ };
33
+ }
34
+ export function shouldRunRequirementsExitReview(previousStatus, targetStatus) {
35
+ if (!isProcessStatus(targetStatus)) {
36
+ return false;
37
+ }
38
+ if (!previousStatus) {
39
+ return true;
40
+ }
41
+ return previousStatus === "prepare.requirements";
42
+ }
43
+ export function hasActionableReviewFeedback(review) {
44
+ return review.issues.length > 0 || review.suggestions.length > 0;
45
+ }
46
+ export function isProcessStatus(status) {
47
+ return status.startsWith("process.");
48
+ }
49
+ //# sourceMappingURL=requirements-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirements-gate.js","sourceRoot":"","sources":["../../src/requirements-gate.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAA+B,CAAC;AACxE,MAAM,CAAC,MAAM,wBAAwB,GACnC,sKAAsK,CAAC;AACzK,MAAM,CAAC,MAAM,kBAAkB,GAAG,yBAAkC,CAAC;AACrE,MAAM,CAAC,MAAM,kBAAkB,GAC7B,iKAAiK,CAAC;AACpK,MAAM,CAAC,MAAM,4BAA4B,GACvC,qFAAqF,CAAC;AAExF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAQnC;IAMC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC,+BAA+B,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QACjF,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;QACnC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,IAAI,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC;QACpF,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;KACA,CAAC,CAAC;IAE7B,IAAI,CAAC,MAAM,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,YAAY;YAC/B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,UAAU,EAAE,gBAAgB;QAC5B,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE,yBAAyB;QACrC,WAAW,EAAE,kBAAkB;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,cAAsC,EACtC,YAAwB;IAExB,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,cAAc,KAAK,sBAAsB,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,MAAwB;IAClE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAkB;IAChD,OAAO,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { SwitchTaskInput, SwitchTaskResult } from "./types.js";
2
+ export declare function switchTask(input: SwitchTaskInput): SwitchTaskResult;
@@ -0,0 +1,60 @@
1
+ import { ensureTaskMeta, resolveProjectContext, resolveTaskContext, saveTaskMeta } from "./context.js";
2
+ export function switchTask(input) {
3
+ const project = resolveProjectContext(input.cwd);
4
+ const source = resolveTaskContext(project, input.fromTask);
5
+ const target = ensureTaskMeta(project, input.toTask);
6
+ const now = new Date().toISOString();
7
+ const sourceSnapshot = {
8
+ projectId: project.projectId,
9
+ task: source.taskName,
10
+ status: source.meta.status,
11
+ updatedAt: source.meta.updatedAt,
12
+ activePlan: source.meta.activePlan,
13
+ planPath: source.activePlanPath,
14
+ };
15
+ const leaveState = {
16
+ leftAt: now,
17
+ updatedAt: now,
18
+ reason: input.reason ?? "user_switch",
19
+ fromTask: source.taskName,
20
+ toTask: target.taskName,
21
+ nextTask: target.taskName,
22
+ continueNeeded: input.reason !== "completed" && input.reason !== "abandoned",
23
+ sourceSnapshot,
24
+ };
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
+ return {
53
+ fromTask: source.taskName,
54
+ toTask: target.taskName,
55
+ sourceMetaPath: source.metaPath,
56
+ targetMetaPath: target.metaPath,
57
+ leaveState,
58
+ };
59
+ }
60
+ //# sourceMappingURL=switch-task.js.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ import type { ProjectContext, TaskRetentionResult } from "./types.js";
2
+ export declare function enforceTaskRetention(project: ProjectContext, currentTaskName?: string): TaskRetentionResult;
@@ -0,0 +1,126 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { readJsonFile } from "./io.js";
4
+ export function enforceTaskRetention(project, currentTaskName) {
5
+ const maxTasksToKeep = project.projectConfig?.maxTasksToKeep ?? 99;
6
+ const archiveTasksRoot = path.join(project.clawDir, "archive", "tasks");
7
+ const prunedArchivedTasks = [];
8
+ let archivedCurrentTask;
9
+ for (const taskName of listActiveTaskNames(project)) {
10
+ const archivedTask = archiveTaskDirectory(project, taskName, archiveTasksRoot);
11
+ if (archivedTask && taskName === currentTaskName) {
12
+ archivedCurrentTask = archivedTask;
13
+ }
14
+ }
15
+ const archivedTasks = listArchivedTasks(archiveTasksRoot);
16
+ if (archivedTasks.length > maxTasksToKeep) {
17
+ const overflow = archivedTasks.length - maxTasksToKeep;
18
+ const toPrune = archivedTasks
19
+ .sort(compareArchivedTasksByUpdatedAt)
20
+ .slice(0, overflow);
21
+ for (const archivedTask of toPrune) {
22
+ fs.rmSync(archivedTask.archivedTaskDir, { recursive: true, force: true });
23
+ prunedArchivedTasks.push(archivedTask);
24
+ }
25
+ }
26
+ return {
27
+ enabled: true,
28
+ maxTasksToKeep,
29
+ ...(archivedCurrentTask ? { archivedCurrentTask } : {}),
30
+ prunedArchivedTasks,
31
+ };
32
+ }
33
+ function archiveTaskDirectory(project, taskName, archiveTasksRoot) {
34
+ const sourceTaskDir = path.join(project.tasksDir, taskName);
35
+ if (!fs.existsSync(sourceTaskDir) || !fs.statSync(sourceTaskDir).isDirectory()) {
36
+ return undefined;
37
+ }
38
+ const metaPath = path.join(sourceTaskDir, "meta.json");
39
+ if (!fs.existsSync(metaPath)) {
40
+ return undefined;
41
+ }
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") {
48
+ return undefined;
49
+ }
50
+ fs.mkdirSync(archiveTasksRoot, { recursive: true });
51
+ const archivedTaskDir = uniqueArchiveTaskDir(archiveTasksRoot, taskName);
52
+ fs.renameSync(sourceTaskDir, archivedTaskDir);
53
+ const archivedPlanPath = typeof meta.activePlan === "string" ? path.join(archivedTaskDir, meta.activePlan) : undefined;
54
+ return {
55
+ taskName,
56
+ sourceTaskDir,
57
+ archivedTaskDir,
58
+ ...(archivedPlanPath ? { archivedPlanPath } : {}),
59
+ ...(meta.updatedAt ? { updatedAt: meta.updatedAt } : {}),
60
+ };
61
+ }
62
+ function listActiveTaskNames(project) {
63
+ if (!fs.existsSync(project.tasksDir)) {
64
+ return [];
65
+ }
66
+ return fs
67
+ .readdirSync(project.tasksDir, { withFileTypes: true })
68
+ .filter((entry) => entry.isDirectory())
69
+ .map((entry) => entry.name);
70
+ }
71
+ function listArchivedTasks(archiveTasksRoot) {
72
+ if (!fs.existsSync(archiveTasksRoot)) {
73
+ return [];
74
+ }
75
+ const entries = [];
76
+ for (const child of fs.readdirSync(archiveTasksRoot, { withFileTypes: true })) {
77
+ if (!child.isDirectory()) {
78
+ continue;
79
+ }
80
+ const archivedTaskDir = path.join(archiveTasksRoot, child.name);
81
+ const metaPath = path.join(archivedTaskDir, "meta.json");
82
+ let updatedAt;
83
+ let taskName = child.name;
84
+ 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);
91
+ }
92
+ }
93
+ entries.push({
94
+ taskName,
95
+ sourceTaskDir: "",
96
+ archivedTaskDir,
97
+ ...(archivedPlanPath ? { archivedPlanPath } : {}),
98
+ ...(updatedAt ? { updatedAt } : {}),
99
+ });
100
+ }
101
+ return entries;
102
+ }
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;
106
+ if (leftTime !== rightTime) {
107
+ return leftTime - rightTime;
108
+ }
109
+ return left.taskName.localeCompare(right.taskName);
110
+ }
111
+ function uniqueArchiveTaskDir(archiveTasksRoot, taskName) {
112
+ const candidate = path.join(archiveTasksRoot, taskName);
113
+ if (!fs.existsSync(candidate)) {
114
+ return candidate;
115
+ }
116
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
117
+ let attempt = 1;
118
+ while (true) {
119
+ const suffixed = path.join(archiveTasksRoot, `${taskName}--${stamp}-${attempt}`);
120
+ if (!fs.existsSync(suffixed)) {
121
+ return suffixed;
122
+ }
123
+ attempt += 1;
124
+ }
125
+ }
126
+ //# sourceMappingURL=task-retention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-retention.js","sourceRoot":"","sources":["../../src/task-retention.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { TruthIngestInput, TruthIngestResult } from "./types.js";
2
+ export declare function ingestTruth(input: TruthIngestInput): TruthIngestResult;
@@ -0,0 +1,33 @@
1
+ import { resolveProjectContext } from "./context.js";
2
+ import { ClawError } from "./errors.js";
3
+ import { readTextFile, writeTextFile } from "./io.js";
4
+ import { ensureInsideDir } from "./paths.js";
5
+ export function ingestTruth(input) {
6
+ const project = resolveProjectContext(input.cwd);
7
+ const targetPath = ensureInsideDir(project.truthDir, input.target.replace(/\\/g, "/"));
8
+ if (!targetPath) {
9
+ throw new ClawError("TRUTH_TARGET_INVALID", `Truth target "${input.target}" escapes .claw/truth/.`, {
10
+ target: input.target,
11
+ });
12
+ }
13
+ const nextContent = input.append && exists(targetPath)
14
+ ? `${readTextFile(targetPath)}${input.content}`
15
+ : input.content;
16
+ writeTextFile(targetPath, nextContent);
17
+ return {
18
+ truthRoot: project.truthDir,
19
+ targetPath,
20
+ bytesWritten: Buffer.byteLength(nextContent, "utf-8"),
21
+ mode: input.append ? "append" : "replace",
22
+ };
23
+ }
24
+ function exists(filePath) {
25
+ try {
26
+ readTextFile(filePath);
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ //# sourceMappingURL=truth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truth.js","sourceRoot":"","sources":["../../src/truth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,SAAS,CAAC,sBAAsB,EAAE,iBAAiB,KAAK,CAAC,MAAM,yBAAyB,EAAE;YAClG,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC;QACpD,CAAC,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE;QAC/C,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IAClB,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEvC,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,QAAQ;QAC3B,UAAU;QACV,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC;QACrD,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,QAAgB;IAC9B,IAAI,CAAC;QACH,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}