@veewo/claw-core 0.2.2 → 0.2.3

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 (33) hide show
  1. package/README.md +16 -16
  2. package/dist/src/daily-maintenance.d.ts +2 -0
  3. package/dist/src/daily-maintenance.js +66 -110
  4. package/dist/src/daily-maintenance.js.map +1 -1
  5. package/dist/src/knowledge-assignments.d.ts +0 -6
  6. package/dist/src/knowledge-assignments.js +1 -8
  7. package/dist/src/knowledge-assignments.js.map +1 -1
  8. package/dist/src/knowledge-sidecar.js +2 -1
  9. package/dist/src/knowledge-sidecar.js.map +1 -1
  10. package/dist/src/resources/delegate-writer/TEMPLATE.json +5 -5
  11. package/dist/src/resources/knowledge-writer/CONTENT-COVERAGE.md +30 -30
  12. package/dist/src/resources/knowledge-writer/SKILL.md +9 -9
  13. package/dist/src/resources/knowledge-writer/TEMPLATE.json +1 -1
  14. package/dist/src/resources/knowledge-writer/agents/openai.yaml +4 -4
  15. package/dist/src/resources/knowledge-writer/knowledge-format.md +47 -47
  16. package/dist/src/resources/knowledge-writer/non-claw-fallback.md +53 -53
  17. package/dist/src/session-bindings.d.ts +2 -1
  18. package/dist/src/session-bindings.js +22 -1
  19. package/dist/src/session-bindings.js.map +1 -1
  20. package/dist/src/task-lifecycle.d.ts +13 -0
  21. package/dist/src/task-lifecycle.js +142 -0
  22. package/dist/src/task-lifecycle.js.map +1 -0
  23. package/dist/src/templates/plans/default.js +1 -1
  24. package/dist/src/workflow-guidance.codex.config.json +363 -0
  25. package/dist/src/workflow-guidance.config.json +363 -363
  26. package/dist/src/workflow-guidance.qoder.config.json +362 -0
  27. package/package.json +48 -48
  28. package/dist/src/embedding-config.d.ts +0 -9
  29. package/dist/src/embedding-config.js +0 -21
  30. package/dist/src/embedding-config.js.map +0 -1
  31. package/dist/src/project-config-defaults.d.ts +0 -6
  32. package/dist/src/project-config-defaults.js +0 -5
  33. package/dist/src/project-config-defaults.js.map +0 -1
@@ -1,30 +1,30 @@
1
- # knowledge-writer content coverage
2
-
3
- ## Source to converted-home mapping
4
-
5
- - Trigger and template entry: `SKILL.md`; input and quality contract: `TEMPLATE.json` requirements, tasks, guidance, and rules.
6
- - Template compatibility: `TEMPLATE.json` declares the current claw CLI version.
7
- - Conclusion evidence from every supplied material, with task-status interpretation when present: `non-claw-fallback.md`, template tasks 1 and 2, acceptance criteria, and template rules.
8
- - Evidence freshness and unresolved-conflict handling: `non-claw-fallback.md`, template task 2, acceptance criteria, and template rules.
9
- - Runtime scope: `TEMPLATE.json` top-level `scope` only; it is not repeated in writer prompts.
10
- - Fixed Truth-then-ADR sequence without routing choices: template tasks 4 and 5 and `non-claw-fallback.md`.
11
- - Machine-stable current/history/superseded metadata and dated evolution grammar: `knowledge-format.md`, template tasks 4 and 5, and `non-claw-fallback.md`.
12
- - On-write format inspection and repair without corpus-wide migration: `knowledge-format.md`, template tasks 3 through 6, acceptance criteria, and template rules.
13
- - Canonical-owner discovery and exhaustive search: template tasks 3 through 6 plus template rules.
14
- - One-owner stewardship and cross-document consistency: template task 6, template rules, and `non-claw-fallback.md`.
15
- - Writing constraints, encoding, exact identifiers, and return behavior: `non-claw-fallback.md`, template task 6, and template rules.
16
- - Supplied-material immutability: template task 1, acceptance criteria, template rules, and `non-claw-fallback.md`.
17
- - Verification gate: template task 6 requires focused and exhaustive post-write review before completion.
18
-
19
- ## Coverage result
20
-
21
- - [x] Important source triggers and inputs are represented.
22
- - [x] Conclusion-bearing content from every supplied material drives deposition; task status informs interpretation without turning task metadata into an execution record.
23
- - [x] The ordered workflow always performs the Truth pass before the ADR pass and has no route-choice task.
24
- - [x] Search tools, ownership constraints, and safety boundaries are represented.
25
- - [x] Time-bounded authority, current-anchor checks, and unresolved-freshness no-edit behavior are represented.
26
- - [x] Writing and consistency verification requirements are represented.
27
- - [x] Canonical state and dated evolution semantics are represented.
28
- - [x] Every written owner is repaired to canonical format while untouched documents remain unmigrated.
29
- - [x] Full direct behavior remains available in the adjacent fallback.
30
- - [x] No source companion scripts or external links require migration.
1
+ # knowledge-writer content coverage
2
+
3
+ ## Source to converted-home mapping
4
+
5
+ - Trigger and template entry: `SKILL.md`; input and quality contract: `TEMPLATE.json` requirements, tasks, guidance, and rules.
6
+ - Template compatibility: `TEMPLATE.json` declares the current claw CLI version.
7
+ - Conclusion evidence from every supplied material, with task-status interpretation when present: `non-claw-fallback.md`, template tasks 1 and 2, acceptance criteria, and template rules.
8
+ - Evidence freshness and unresolved-conflict handling: `non-claw-fallback.md`, template task 2, acceptance criteria, and template rules.
9
+ - Runtime scope: `TEMPLATE.json` top-level `scope` only; it is not repeated in writer prompts.
10
+ - Fixed Truth-then-ADR sequence without routing choices: template tasks 4 and 5 and `non-claw-fallback.md`.
11
+ - Machine-stable current/history/superseded metadata and dated evolution grammar: `knowledge-format.md`, template tasks 4 and 5, and `non-claw-fallback.md`.
12
+ - On-write format inspection and repair without corpus-wide migration: `knowledge-format.md`, template tasks 3 through 6, acceptance criteria, and template rules.
13
+ - Canonical-owner discovery and exhaustive search: template tasks 3 through 6 plus template rules.
14
+ - One-owner stewardship and cross-document consistency: template task 6, template rules, and `non-claw-fallback.md`.
15
+ - Writing constraints, encoding, exact identifiers, and return behavior: `non-claw-fallback.md`, template task 6, and template rules.
16
+ - Supplied-material immutability: template task 1, acceptance criteria, template rules, and `non-claw-fallback.md`.
17
+ - Verification gate: template task 6 requires focused and exhaustive post-write review before completion.
18
+
19
+ ## Coverage result
20
+
21
+ - [x] Important source triggers and inputs are represented.
22
+ - [x] Conclusion-bearing content from every supplied material drives deposition; task status informs interpretation without turning task metadata into an execution record.
23
+ - [x] The ordered workflow always performs the Truth pass before the ADR pass and has no route-choice task.
24
+ - [x] Search tools, ownership constraints, and safety boundaries are represented.
25
+ - [x] Time-bounded authority, current-anchor checks, and unresolved-freshness no-edit behavior are represented.
26
+ - [x] Writing and consistency verification requirements are represented.
27
+ - [x] Canonical state and dated evolution semantics are represented.
28
+ - [x] Every written owner is repaired to canonical format while untouched documents remain unmigrated.
29
+ - [x] Full direct behavior remains available in the adjacent fallback.
30
+ - [x] No source companion scripts or external links require migration.
@@ -1,9 +1,9 @@
1
- ---
2
- name: knowledge-writer
3
- description: Evaluate supplied materials by their content, then maintain canonical Truth followed by ADR knowledge in one consistency-aware pass. Use only when explicitly invoked with supplied materials; do not trigger this skill implicitly.
4
- ---
5
- # Knowledge writer
6
-
7
- Resolve `<skill-dir>` as the directory containing this file. Run `claw plan create --template-file "<skill-dir>/TEMPLATE.json" --title "knowledge-writer"`, then follow the returned `workflowGuidance`.
8
-
9
- If the template or claw CLI is unavailable, follow `non-claw-fallback.md` directly.
1
+ ---
2
+ name: knowledge-writer
3
+ description: Evaluate supplied materials by their content, then maintain canonical Truth followed by ADR knowledge in one consistency-aware pass. Use only when explicitly invoked with supplied materials; do not trigger this skill implicitly.
4
+ ---
5
+ # Knowledge writer
6
+
7
+ Resolve `<skill-dir>` as the directory containing this file. Run `claw plan create --template-file "<skill-dir>/TEMPLATE.json" --title "knowledge-writer"`, then follow the returned `workflowGuidance`.
8
+
9
+ If the template or claw CLI is unavailable, follow `non-claw-fallback.md` directly.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "knowledge-writer",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "scope": "session",
5
5
  "title": "knowledge-writer",
6
6
  "status": "process.active",
@@ -1,4 +1,4 @@
1
- interface:
2
- display_name: "Knowledge Writer"
3
- short_description: "Maintain consistent canonical Truth and ADR knowledge."
4
- default_prompt: "Use $knowledge-writer with the explicitly supplied materials to maintain canonical Truth followed by ADR in one consistency-aware pass."
1
+ interface:
2
+ display_name: "Knowledge Writer"
3
+ short_description: "Maintain consistent canonical Truth and ADR knowledge."
4
+ default_prompt: "Use $knowledge-writer with the explicitly supplied materials to maintain canonical Truth followed by ADR in one consistency-aware pass."
@@ -1,47 +1,47 @@
1
- # Canonical knowledge evolution format
2
-
3
- Use this format for every new Truth or ADR document and every existing owner written by the current writer pass. Inspect the selected owner before writing and repair nonconforming structure in the same edit. Do not mass-rewrite untouched documents.
4
-
5
- ## Document metadata
6
-
7
- Document kind is inferred from its canonical path: documents under `adr/` are ADRs; other documents under the Truth root are Truth documents. Do not add a document-kind field.
8
-
9
- Truth documents default to `current`. ADR documents default to `accepted`. When a different document state must be explicit, place a renderer-hidden generic comment immediately after the title:
10
-
11
- ```markdown
12
- # ADR: Replaced decision
13
-
14
- <!-- document-state: superseded -->
15
- ```
16
-
17
- Allowed document states are:
18
-
19
- - Truth: `current` or `historical`
20
- - ADR: `accepted`, `superseded`, or `historical`
21
-
22
- An ordinary leading `## Status` or `## 状态` section may also supply the document state. Do not emit tool-specific metadata names.
23
-
24
- ## Current and evolution sections
25
-
26
- Use renderer-hidden, machine-stable ASCII comments before natural-language headings:
27
-
28
- ```markdown
29
- <!-- state: current -->
30
- ## Current behavior
31
-
32
- Current canonical content.
33
-
34
- <!-- state: history -->
35
- ## Evolution history
36
-
37
- <!-- dated: 2026-07-20 -->
38
- ### Replaced the earlier route
39
-
40
- The prior behavior and why it matters for rollback or repeated work.
41
- ```
42
-
43
- For ADRs, the ordinary Context, Decision, Alternatives, and Consequences sections inherit the document state. Mark only retained decision evolution with `<!-- state: history -->`.
44
-
45
- Each `<!-- dated: YYYY-MM-DD -->` comment starts one complete evolution unit at the level-three heading that follows it. The unit extends to the next dated comment or the next level-two heading. The date is a stable checkpoint label and search signal, not a time-to-live value. Multiple checkpoints may use the same date. Their canonical evolution order is document order.
46
-
47
- Do not append an evolution unit for routine progress or every successful turn. Add one only when the former fact or decision remains useful for rollback, compatibility, feature repetition, incident reasoning, or understanding a meaningful transition.
1
+ # Canonical knowledge evolution format
2
+
3
+ Use this format for every new Truth or ADR document and every existing owner written by the current writer pass. Inspect the selected owner before writing and repair nonconforming structure in the same edit. Do not mass-rewrite untouched documents.
4
+
5
+ ## Document metadata
6
+
7
+ Document kind is inferred from its canonical path: documents under `adr/` are ADRs; other documents under the Truth root are Truth documents. Do not add a document-kind field.
8
+
9
+ Truth documents default to `current`. ADR documents default to `accepted`. When a different document state must be explicit, place a renderer-hidden generic comment immediately after the title:
10
+
11
+ ```markdown
12
+ # ADR: Replaced decision
13
+
14
+ <!-- document-state: superseded -->
15
+ ```
16
+
17
+ Allowed document states are:
18
+
19
+ - Truth: `current` or `historical`
20
+ - ADR: `accepted`, `superseded`, or `historical`
21
+
22
+ An ordinary leading `## Status` or `## 状态` section may also supply the document state. Do not emit tool-specific metadata names.
23
+
24
+ ## Current and evolution sections
25
+
26
+ Use renderer-hidden, machine-stable ASCII comments before natural-language headings:
27
+
28
+ ```markdown
29
+ <!-- state: current -->
30
+ ## Current behavior
31
+
32
+ Current canonical content.
33
+
34
+ <!-- state: history -->
35
+ ## Evolution history
36
+
37
+ <!-- dated: 2026-07-20 -->
38
+ ### Replaced the earlier route
39
+
40
+ The prior behavior and why it matters for rollback or repeated work.
41
+ ```
42
+
43
+ For ADRs, the ordinary Context, Decision, Alternatives, and Consequences sections inherit the document state. Mark only retained decision evolution with `<!-- state: history -->`.
44
+
45
+ Each `<!-- dated: YYYY-MM-DD -->` comment starts one complete evolution unit at the level-three heading that follows it. The unit extends to the next dated comment or the next level-two heading. The date is a stable checkpoint label and search signal, not a time-to-live value. Multiple checkpoints may use the same date. Their canonical evolution order is document order.
46
+
47
+ Do not append an evolution unit for routine progress or every successful turn. Add one only when the former fact or decision remains useful for rollback, compatibility, feature repetition, incident reasoning, or understanding a meaningful transition.
@@ -1,53 +1,53 @@
1
- # Knowledge writer fallback
2
-
3
- Act as the knowledge-base steward for the project. Leave the relevant Truth and ADR corpus accurate, coherent, and easy for future agents to trust.
4
-
5
- ## Input and evidence boundary
6
-
7
- Read every supplied material completely. Interpret evidence from its content and semantics rather than requiring a particular filename, field, record shape, or serialization format. Extract executed conclusions, verified findings, retrospective lessons, key decisions, and other explicit outcomes wherever they appear. Do not repeat implementation or test verification or modify supplied materials.
8
-
9
- When task status is present, it helps interpret completed, pending, and blocked scope, but a task list is not an execution log. Infer execution results, verified findings, planning outcomes, and durable decisions from conclusion-bearing content; never turn task titles, descriptions, requirements, or intentions into completed results merely because they appear in an input.
10
-
11
- ## Evidence freshness
12
-
13
- Trusted means the evidence was verified at the revision or worktree state it describes; it does not make an older report permanently authoritative for current behavior.
14
-
15
- - Before writing current behavior from a supplied conclusion, read the relevant implementation anchors and inspect later or overlapping working-tree changes. This is a freshness check, not repeated implementation verification; do not rerun tests merely to reconfirm the report.
16
- - When current implementation supersedes the report, current implementation owns current-state Truth and the report may only support historical or version-bound evidence.
17
- - If chronology or authority cannot be resolved safely, omit the affected canonical write and retain the freshness conflict as the reason.
18
-
19
- ## Fixed deposition sequence
20
-
21
- Process the eligible evidence without a route choice:
22
-
23
- 1. Maintain Truth for stable behavior, architecture facts, constraints, pitfalls, code anchors, and verification rules.
24
- 2. Then maintain ADRs for durable decisions, context, rationale, alternatives, tradeoffs, ownership, and consequences, using the same evidence and resulting Truth state.
25
- 3. Finally review Truth and ADR together for ownership and consistency.
26
-
27
- Use `knowledge-format.md` for every new document and every existing owner written by this pass. Inspect each selected owner before writing and repair nonconforming structure in the same edit; leave untouched documents unmigrated. Dated identifies an evolution checkpoint, not age or time-to-live.
28
-
29
- It is valid for either pass to make no edit when the eligible evidence contains no new or changed durable knowledge. Temporary progress, speculation, conversational narration, unchanged facts, and unfinished-task claims do not belong in canonical knowledge.
30
-
31
- ## Stewardship and ownership
32
-
33
- Use `claw search` to discover existing owners, then open every plausible candidate before judging it. Use exhaustive text search for distinguishing identifiers when top-k recall could hide another current claim. Update the document that already owns the topic; create a new document only for a genuinely new durable topic after filename and title collision checks.
34
-
35
- Maintain one current owner for each material fact or decision. A broad or neighboring document is still a competing owner when it restates an unqualified current rule. Reconcile overlaps by extending the canonical owner and narrowing other current claims to references, historical evidence, or non-overlapping scope. Preserve unrelated user edits and repository conventions.
36
-
37
- Truth and ADR are one knowledge system: after both ordered passes, review the related documents together and resolve contradictions between current-state Truth, decision ownership, and consequences. Do not report completion while a material current claim remains inconsistent or ownerless.
38
-
39
- ## Writing and verification
40
-
41
- - Follow the repository's language and document shape.
42
- - Preserve exact identifiers, config keys, commands, and error text.
43
- - Use project-relative paths in canonical documents.
44
- - Ground every fact, path, owner, and alternative in supplied or inspected evidence.
45
- - Label historical and superseded evidence explicitly; never silently promote it to current behavior.
46
- - Add dated evolution only for former facts or decisions that remain useful for rollback, compatibility, feature repetition, incident reasoning, or understanding a meaningful transition.
47
- - Repair every written Truth or ADR owner to the canonical format in `knowledge-format.md`; do not defer a discovered format mismatch.
48
- - Repair mojibake and preserve valid Markdown encoding.
49
- - Re-run focused and exhaustive searches after writing; every plausible hit must be the selected owner, an explicit reference, historical or version-bound evidence, or a narrowed non-overlapping claim.
50
-
51
- ## Return
52
-
53
- Return a brief completion note with changed paths or the evidence-backed no-edit reasons. Response format is not part of the contract.
1
+ # Knowledge writer fallback
2
+
3
+ Act as the knowledge-base steward for the project. Leave the relevant Truth and ADR corpus accurate, coherent, and easy for future agents to trust.
4
+
5
+ ## Input and evidence boundary
6
+
7
+ Read every supplied material completely. Interpret evidence from its content and semantics rather than requiring a particular filename, field, record shape, or serialization format. Extract executed conclusions, verified findings, retrospective lessons, key decisions, and other explicit outcomes wherever they appear. Do not repeat implementation or test verification or modify supplied materials.
8
+
9
+ When task status is present, it helps interpret completed, pending, and blocked scope, but a task list is not an execution log. Infer execution results, verified findings, planning outcomes, and durable decisions from conclusion-bearing content; never turn task titles, descriptions, requirements, or intentions into completed results merely because they appear in an input.
10
+
11
+ ## Evidence freshness
12
+
13
+ Trusted means the evidence was verified at the revision or worktree state it describes; it does not make an older report permanently authoritative for current behavior.
14
+
15
+ - Before writing current behavior from a supplied conclusion, read the relevant implementation anchors and inspect later or overlapping working-tree changes. This is a freshness check, not repeated implementation verification; do not rerun tests merely to reconfirm the report.
16
+ - When current implementation supersedes the report, current implementation owns current-state Truth and the report may only support historical or version-bound evidence.
17
+ - If chronology or authority cannot be resolved safely, omit the affected canonical write and retain the freshness conflict as the reason.
18
+
19
+ ## Fixed deposition sequence
20
+
21
+ Process the eligible evidence without a route choice:
22
+
23
+ 1. Maintain Truth for stable behavior, architecture facts, constraints, pitfalls, code anchors, and verification rules.
24
+ 2. Then maintain ADRs for durable decisions, context, rationale, alternatives, tradeoffs, ownership, and consequences, using the same evidence and resulting Truth state.
25
+ 3. Finally review Truth and ADR together for ownership and consistency.
26
+
27
+ Use `knowledge-format.md` for every new document and every existing owner written by this pass. Inspect each selected owner before writing and repair nonconforming structure in the same edit; leave untouched documents unmigrated. Dated identifies an evolution checkpoint, not age or time-to-live.
28
+
29
+ It is valid for either pass to make no edit when the eligible evidence contains no new or changed durable knowledge. Temporary progress, speculation, conversational narration, unchanged facts, and unfinished-task claims do not belong in canonical knowledge.
30
+
31
+ ## Stewardship and ownership
32
+
33
+ Use `claw search` to discover existing owners, then open every plausible candidate before judging it. Use exhaustive text search for distinguishing identifiers when top-k recall could hide another current claim. Update the document that already owns the topic; create a new document only for a genuinely new durable topic after filename and title collision checks.
34
+
35
+ Maintain one current owner for each material fact or decision. A broad or neighboring document is still a competing owner when it restates an unqualified current rule. Reconcile overlaps by extending the canonical owner and narrowing other current claims to references, historical evidence, or non-overlapping scope. Preserve unrelated user edits and repository conventions.
36
+
37
+ Truth and ADR are one knowledge system: after both ordered passes, review the related documents together and resolve contradictions between current-state Truth, decision ownership, and consequences. Do not report completion while a material current claim remains inconsistent or ownerless.
38
+
39
+ ## Writing and verification
40
+
41
+ - Follow the repository's language and document shape.
42
+ - Preserve exact identifiers, config keys, commands, and error text.
43
+ - Use project-relative paths in canonical documents.
44
+ - Ground every fact, path, owner, and alternative in supplied or inspected evidence.
45
+ - Label historical and superseded evidence explicitly; never silently promote it to current behavior.
46
+ - Add dated evolution only for former facts or decisions that remain useful for rollback, compatibility, feature repetition, incident reasoning, or understanding a meaningful transition.
47
+ - Repair every written Truth or ADR owner to the canonical format in `knowledge-format.md`; do not defer a discovered format mismatch.
48
+ - Repair mojibake and preserve valid Markdown encoding.
49
+ - Re-run focused and exhaustive searches after writing; every plausible hit must be the selected owner, an explicit reference, historical or version-bound evidence, or a narrowed non-overlapping claim.
50
+
51
+ ## Return
52
+
53
+ Return a brief completion note with changed paths or the evidence-backed no-edit reasons. Response format is not part of the contract.
@@ -1,7 +1,8 @@
1
1
  import type { ProjectContext } from "./types.js";
2
+ export declare const SESSION_BINDING_TTL_MS: number;
2
3
  export declare function sessionBindingRegistryPath(project: ProjectContext): string;
3
4
  export declare function bindSessionToPlan(project: ProjectContext, sessionKey: string | undefined, planPath: string): void;
4
5
  export declare function unbindSession(project: ProjectContext, sessionKey: string | undefined): void;
5
6
  /** Remove registry entries whose bound plan is no longer present under active tasks. */
6
- export declare function pruneStaleSessionBindings(project: ProjectContext): string[];
7
+ export declare function pruneStaleSessionBindings(project: ProjectContext, nowMs?: number): string[];
7
8
  export declare function resolveSessionBoundPlan(project: ProjectContext, sessionKey: string | undefined): string | null;
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { readJsonFile, withFileLock, writeJsonFile } from "./io.js";
4
4
  import { ensureInsideDir } from "./paths.js";
5
5
  const SESSION_SCOPE_BINDING_KEY = "$session";
6
+ export const SESSION_BINDING_TTL_MS = 7 * 24 * 60 * 60 * 1000;
6
7
  export function sessionBindingRegistryPath(project) {
7
8
  return path.join(project.clawDir, "runtime", "session-bindings.json");
8
9
  }
@@ -26,8 +27,22 @@ export function unbindSession(project, sessionKey) {
26
27
  });
27
28
  }
28
29
  /** Remove registry entries whose bound plan is no longer present under active tasks. */
29
- export function pruneStaleSessionBindings(project) {
30
+ export function pruneStaleSessionBindings(project, nowMs = Date.now()) {
30
31
  const removed = [];
32
+ const registryPath = sessionBindingRegistryPath(project);
33
+ if (fs.existsSync(registryPath)) {
34
+ try {
35
+ if (nowMs - fs.statSync(registryPath).mtimeMs >= SESSION_BINDING_TTL_MS) {
36
+ const registry = readRegistry(project);
37
+ removed.push(...Object.keys(registry.bindings));
38
+ fs.unlinkSync(registryPath);
39
+ return removed;
40
+ }
41
+ }
42
+ catch {
43
+ return removed;
44
+ }
45
+ }
31
46
  updateRegistry(project, (registry) => {
32
47
  for (const [key, relativePath] of Object.entries(registry.bindings)) {
33
48
  const normalizedRelative = typeof relativePath === "string" ? relativePath.replace(/\\/g, "/") : "";
@@ -58,6 +73,12 @@ export function resolveSessionBoundPlan(project, sessionKey) {
58
73
  unbindSession(project, normalizedKey);
59
74
  return null;
60
75
  }
76
+ try {
77
+ fs.utimesSync(sessionBindingRegistryPath(project), new Date(), new Date());
78
+ }
79
+ catch {
80
+ // Binding freshness is advisory; resolution remains valid.
81
+ }
61
82
  return planPath;
62
83
  }
63
84
  function bindingKey(project, sessionKey) {
@@ -1 +1 @@
1
- {"version":3,"file":"session-bindings.js","sourceRoot":"","sources":["../../src/session-bindings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-bindings.js","sourceRoot":"","sources":["../../src/session-bindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQ7C,MAAM,yBAAyB,GAAG,UAAU,CAAC;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9D,MAAM,UAAU,0BAA0B,CAAC,OAAuB;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAuB,EAAE,UAA8B,EAAE,QAAgB;IACzG,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACtD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IACD,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACxD,cAAc,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;QACnC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,YAAY,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAuB,EAAE,UAA8B;IACnF,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACtD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IACD,cAAc,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;QACnC,OAAO,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,yBAAyB,CAAC,OAAuB,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IACnF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,YAAY,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,IAAI,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,OAAO,IAAI,sBAAsB,EAAE,CAAC;gBACxE,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;gBACvC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChD,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;gBAC5B,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,cAAc,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;QACnC,KAAK,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpE,MAAM,kBAAkB,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpG,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClH,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/F,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1C,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAAuB,EAAE,UAA8B;IAC7F,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACtD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACtD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClH,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,0BAA0B,CAAC,OAAO,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,UAAU,CAAC,OAAuB,EAAE,UAA8B;IACzE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,CAAC;IACD,OAAO,UAAU,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AACzC,CAAC;AAED,SAAS,eAAe,CAAC,OAAuB,EAAE,QAAgB;IAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACvE,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,gBAAgB,IAAI,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAC7H,MAAM,IAAI,KAAK,CAAC,8CAA8C,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,cAAc,CAAC,OAAuB,EAAE,MAAkD;IACjG,MAAM,YAAY,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACzD,YAAY,CAAC,YAAY,EAAE,GAAG,EAAE;QAC9B,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjB,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO;QACT,CAAC;QACD,aAAa,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,OAAuB;IAC3C,MAAM,YAAY,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAkC,YAAY,CAAC,CAAC;QAC7E,OAAO;YACL,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;SAC9F,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ProjectContext } from "./types.js";
2
+ export type TaskLifecycleMaintenanceResult = {
3
+ archivedTasks: number;
4
+ prunedArchivedTasks: number;
5
+ expiredTaskDirectoriesRemoved: number;
6
+ emptyDatedDirectoriesRemoved: number;
7
+ };
8
+ /**
9
+ * Coordinates the task lifecycle without merging the policies themselves:
10
+ * archive eligibility, archive retention, and inactivity TTL are evaluated in
11
+ * that order so archived work gets a recovery window before final deletion.
12
+ */
13
+ export declare function runTaskLifecycleMaintenance(project: ProjectContext, now: Date): TaskLifecycleMaintenanceResult;
@@ -0,0 +1,142 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { readJsonFile } from "./io.js";
4
+ import { listTaskDirectories } from "./context.js";
5
+ import { enforceTaskRetention } from "./task-retention.js";
6
+ const WORKFLOW_TASK_TTL_MS = 30 * 24 * 60 * 60 * 1000;
7
+ /**
8
+ * Coordinates the task lifecycle without merging the policies themselves:
9
+ * archive eligibility, archive retention, and inactivity TTL are evaluated in
10
+ * that order so archived work gets a recovery window before final deletion.
11
+ */
12
+ export function runTaskLifecycleMaintenance(project, now) {
13
+ const cutoffDate = previousLocalDate(now);
14
+ const archivedDatedTasks = archiveDatedTaskDirectoriesBefore(project, cutoffDate);
15
+ const archivedLegacyTasks = archiveLegacyTaskDirectoriesBefore(project, cutoffDate);
16
+ const retention = enforceTaskRetention(project, undefined, now.getTime(), {
17
+ includeDatedTasks: false,
18
+ includeLegacyTasks: false,
19
+ });
20
+ const expiredTaskDirectoriesRemoved = pruneExpiredTaskDirectories(project, now.getTime());
21
+ const emptyDatedDirectoriesRemoved = removeEmptyDatedTaskDirectories(project);
22
+ return {
23
+ archivedTasks: archivedDatedTasks + archivedLegacyTasks + retention.archivedTasks.length,
24
+ prunedArchivedTasks: retention.prunedArchivedTasks.length,
25
+ expiredTaskDirectoriesRemoved,
26
+ emptyDatedDirectoriesRemoved,
27
+ };
28
+ }
29
+ function pruneExpiredTaskDirectories(project, nowMs) {
30
+ let removed = 0;
31
+ for (const root of [project.tasksDir, path.join(project.clawDir, "archive", "tasks")]) {
32
+ for (const task of listTaskDirectories({ tasksDir: root })) {
33
+ const updatedAt = readPlanUpdatedAt(path.join(task.taskDir, "plan.json"));
34
+ if (updatedAt === null || nowMs - updatedAt < WORKFLOW_TASK_TTL_MS)
35
+ continue;
36
+ try {
37
+ fs.rmSync(task.taskDir, { recursive: true, force: true });
38
+ removed += 1;
39
+ }
40
+ catch {
41
+ // A locked or concurrently updated task is retried by the next pass.
42
+ }
43
+ }
44
+ }
45
+ return removed;
46
+ }
47
+ function removeEmptyDatedTaskDirectories(project) {
48
+ return [project.tasksDir, path.join(project.clawDir, "archive", "tasks")]
49
+ .reduce((removed, root) => removed + removeEmptyDatedDirectories(root), 0);
50
+ }
51
+ function removeEmptyDatedDirectories(root) {
52
+ if (!fs.existsSync(root))
53
+ return 0;
54
+ let removed = 0;
55
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
56
+ if (!entry.isDirectory() || !/^\d{4}-\d{2}-\d{2}$/.test(entry.name))
57
+ continue;
58
+ const directory = path.join(root, entry.name);
59
+ if (fs.readdirSync(directory).length > 0)
60
+ continue;
61
+ fs.rmdirSync(directory);
62
+ removed += 1;
63
+ }
64
+ return removed;
65
+ }
66
+ function archiveDatedTaskDirectoriesBefore(project, cutoffDate) {
67
+ if (!fs.existsSync(project.tasksDir))
68
+ return 0;
69
+ const archiveRoot = path.join(project.clawDir, "archive", "tasks");
70
+ let archivedTaskCount = 0;
71
+ for (const entry of fs.readdirSync(project.tasksDir, { withFileTypes: true })) {
72
+ if (!entry.isDirectory() || !/^\d{4}-\d{2}-\d{2}$/.test(entry.name) || entry.name >= cutoffDate)
73
+ continue;
74
+ const sourceDateDir = path.join(project.tasksDir, entry.name);
75
+ const taskCount = fs.readdirSync(sourceDateDir, { withFileTypes: true }).filter((child) => child.isDirectory()).length;
76
+ moveDateDirectory(sourceDateDir, path.join(archiveRoot, entry.name));
77
+ archivedTaskCount += taskCount;
78
+ }
79
+ return archivedTaskCount;
80
+ }
81
+ function moveDateDirectory(sourceDateDir, targetDateDir) {
82
+ fs.mkdirSync(path.dirname(targetDateDir), { recursive: true });
83
+ if (!fs.existsSync(targetDateDir)) {
84
+ fs.renameSync(sourceDateDir, targetDateDir);
85
+ return;
86
+ }
87
+ for (const child of fs.readdirSync(sourceDateDir, { withFileTypes: true })) {
88
+ const source = path.join(sourceDateDir, child.name);
89
+ let target = path.join(targetDateDir, child.name);
90
+ let suffix = 1;
91
+ while (fs.existsSync(target)) {
92
+ target = path.join(targetDateDir, `${child.name}--${suffix}`);
93
+ suffix += 1;
94
+ }
95
+ fs.renameSync(source, target);
96
+ }
97
+ fs.rmdirSync(sourceDateDir);
98
+ }
99
+ function archiveLegacyTaskDirectoriesBefore(project, cutoffDate) {
100
+ const archiveRoot = path.join(project.clawDir, "archive", "tasks");
101
+ let archivedTaskCount = 0;
102
+ for (const task of listTaskDirectories(project)) {
103
+ if (/^\d{4}-\d{2}-\d{2}[\\/]/.test(task.relativePath))
104
+ continue;
105
+ const updatedAt = readPlanUpdatedAt(path.join(task.taskDir, "plan.json"));
106
+ if (!updatedAt || localDate(new Date(updatedAt)) >= cutoffDate)
107
+ continue;
108
+ moveDirectoryWithCollision(task.taskDir, path.join(archiveRoot, task.relativePath));
109
+ archivedTaskCount += 1;
110
+ }
111
+ return archivedTaskCount;
112
+ }
113
+ function readPlanUpdatedAt(planPath) {
114
+ if (!fs.existsSync(planPath))
115
+ return null;
116
+ try {
117
+ const plan = readJsonFile(planPath);
118
+ const timestamp = typeof plan.updatedAt === "string" ? Date.parse(plan.updatedAt) : Number.NaN;
119
+ return Number.isFinite(timestamp) ? timestamp : fs.statSync(planPath).mtimeMs;
120
+ }
121
+ catch {
122
+ return fs.statSync(planPath).mtimeMs;
123
+ }
124
+ }
125
+ function moveDirectoryWithCollision(sourceDir, targetDir) {
126
+ fs.mkdirSync(path.dirname(targetDir), { recursive: true });
127
+ let target = targetDir;
128
+ let suffix = 1;
129
+ while (fs.existsSync(target)) {
130
+ target = `${targetDir}--${suffix}`;
131
+ suffix += 1;
132
+ }
133
+ fs.renameSync(sourceDir, target);
134
+ }
135
+ function localDate(now) {
136
+ return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
137
+ }
138
+ function previousLocalDate(now) {
139
+ const previous = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
140
+ return localDate(previous);
141
+ }
142
+ //# sourceMappingURL=task-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-lifecycle.js","sourceRoot":"","sources":["../../src/task-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  export const defaultPlanTemplate = {
2
2
  id: "default",
3
- version: "0.2.2",
3
+ version: "0.2.3",
4
4
  status: "process.discussing",
5
5
  goal: {
6
6
  text: "",