ctxr-cli 0.3.0 → 0.4.1

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 (117) hide show
  1. package/dist/adapters/harness/claude-code.d.ts +0 -6
  2. package/dist/adapters/harness/claude-code.d.ts.map +1 -1
  3. package/dist/adapters/harness/claude-code.js +44 -25
  4. package/dist/adapters/harness/claude-code.js.map +1 -1
  5. package/dist/adapters/types.d.ts +28 -9
  6. package/dist/adapters/types.d.ts.map +1 -1
  7. package/dist/commands/adapters-generate.d.ts.map +1 -1
  8. package/dist/commands/adapters-generate.js +16 -7
  9. package/dist/commands/adapters-generate.js.map +1 -1
  10. package/dist/commands/adapters-write-gate.d.ts +20 -0
  11. package/dist/commands/adapters-write-gate.d.ts.map +1 -0
  12. package/dist/commands/adapters-write-gate.js +77 -0
  13. package/dist/commands/adapters-write-gate.js.map +1 -0
  14. package/dist/commands/init.d.ts.map +1 -1
  15. package/dist/commands/init.js +7 -7
  16. package/dist/commands/init.js.map +1 -1
  17. package/dist/commands/rollup-stale.d.ts.map +1 -1
  18. package/dist/commands/rollup-stale.js +1 -1
  19. package/dist/commands/rollup-stale.js.map +1 -1
  20. package/dist/commands/session-land.d.ts.map +1 -1
  21. package/dist/commands/session-land.js +55 -24
  22. package/dist/commands/session-land.js.map +1 -1
  23. package/dist/commands/session-reap.d.ts.map +1 -1
  24. package/dist/commands/session-reap.js +4 -0
  25. package/dist/commands/session-reap.js.map +1 -1
  26. package/dist/commands/verify.js +17 -17
  27. package/dist/commands/verify.js.map +1 -1
  28. package/dist/config/defaults.d.ts +4 -2
  29. package/dist/config/defaults.d.ts.map +1 -1
  30. package/dist/config/defaults.js +4 -2
  31. package/dist/config/defaults.js.map +1 -1
  32. package/dist/config/schema.d.ts +20 -4
  33. package/dist/config/schema.d.ts.map +1 -1
  34. package/dist/config/schema.js +53 -4
  35. package/dist/config/schema.js.map +1 -1
  36. package/dist/core/agents-doc.d.ts +13 -9
  37. package/dist/core/agents-doc.d.ts.map +1 -1
  38. package/dist/core/agents-doc.js +69 -107
  39. package/dist/core/agents-doc.js.map +1 -1
  40. package/dist/core/checks/integrity-checks.d.ts +14 -0
  41. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  42. package/dist/core/checks/integrity-checks.js +77 -1
  43. package/dist/core/checks/integrity-checks.js.map +1 -1
  44. package/dist/core/conventions.d.ts +1 -1
  45. package/dist/core/errors.d.ts +9 -0
  46. package/dist/core/errors.d.ts.map +1 -1
  47. package/dist/core/errors.js +18 -1
  48. package/dist/core/errors.js.map +1 -1
  49. package/dist/core/git/repo.d.ts +10 -0
  50. package/dist/core/git/repo.d.ts.map +1 -1
  51. package/dist/core/git/repo.js +28 -0
  52. package/dist/core/git/repo.js.map +1 -1
  53. package/dist/core/git/worktree.d.ts +8 -0
  54. package/dist/core/git/worktree.d.ts.map +1 -1
  55. package/dist/core/git/worktree.js +11 -0
  56. package/dist/core/git/worktree.js.map +1 -1
  57. package/dist/core/hooks.d.ts +10 -0
  58. package/dist/core/hooks.d.ts.map +1 -1
  59. package/dist/core/hooks.js +37 -10
  60. package/dist/core/hooks.js.map +1 -1
  61. package/dist/core/json-config-merge.d.ts +26 -2
  62. package/dist/core/json-config-merge.d.ts.map +1 -1
  63. package/dist/core/json-config-merge.js +61 -7
  64. package/dist/core/json-config-merge.js.map +1 -1
  65. package/dist/core/markers.d.ts +7 -0
  66. package/dist/core/markers.d.ts.map +1 -1
  67. package/dist/core/markers.js +9 -0
  68. package/dist/core/markers.js.map +1 -1
  69. package/dist/core/migrations/registry.d.ts.map +1 -1
  70. package/dist/core/migrations/registry.js +2 -1
  71. package/dist/core/migrations/registry.js.map +1 -1
  72. package/dist/core/migrations/rename-procedures-path.d.ts +17 -0
  73. package/dist/core/migrations/rename-procedures-path.d.ts.map +1 -0
  74. package/dist/core/migrations/rename-procedures-path.js +45 -0
  75. package/dist/core/migrations/rename-procedures-path.js.map +1 -0
  76. package/dist/core/notes/list.d.ts.map +1 -1
  77. package/dist/core/notes/list.js +9 -5
  78. package/dist/core/notes/list.js.map +1 -1
  79. package/dist/core/reconcile.js +2 -2
  80. package/dist/core/reconcile.js.map +1 -1
  81. package/dist/core/rollup.d.ts +25 -2
  82. package/dist/core/rollup.d.ts.map +1 -1
  83. package/dist/core/rollup.js +51 -5
  84. package/dist/core/rollup.js.map +1 -1
  85. package/dist/core/{procedures.d.ts → skills.d.ts} +12 -12
  86. package/dist/core/skills.d.ts.map +1 -0
  87. package/dist/core/{procedures.js → skills.js} +55 -41
  88. package/dist/core/skills.js.map +1 -0
  89. package/dist/core/templates.d.ts +20 -0
  90. package/dist/core/templates.d.ts.map +1 -0
  91. package/dist/core/templates.js +68 -0
  92. package/dist/core/templates.js.map +1 -0
  93. package/dist/core/write-lifecycle/path-gate.d.ts +28 -0
  94. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  95. package/dist/core/write-lifecycle/path-gate.js +78 -22
  96. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  97. package/dist/run.d.ts.map +1 -1
  98. package/dist/run.js +12 -1
  99. package/dist/run.js.map +1 -1
  100. package/dist/version.d.ts +1 -1
  101. package/dist/version.js +1 -1
  102. package/package.json +1 -1
  103. package/templates/agents/canonical.md +26 -0
  104. package/templates/agents/capture-and-ingest.md +17 -0
  105. package/templates/agents/placement-no-layers.md +5 -0
  106. package/templates/agents/placement.md +7 -0
  107. package/templates/agents/retrieval-leg-routing.md +14 -0
  108. package/templates/agents/store-conventions-empty.md +7 -0
  109. package/templates/agents/store-conventions.md +7 -0
  110. package/templates/hooks/claude-code-write-gate.sh +15 -0
  111. package/templates/skills/ctxr-connection-finding.md +1 -1
  112. package/templates/skills/ctxr-ingest-orchestration.md +1 -1
  113. package/templates/skills/ctxr-land.md +11 -6
  114. package/templates/skills/ctxr-mission.md +36 -0
  115. package/templates/skills/ctxr-session-lifecycle.md +1 -2
  116. package/dist/core/procedures.d.ts.map +0 -1
  117. package/dist/core/procedures.js.map +0 -1
@@ -6,9 +6,13 @@ import { parseNote } from './parse.js';
6
6
  const ALWAYS_SKIP_DIRS = new Set(['.git', '.githooks', '.queue']);
7
7
  /**
8
8
  * Filenames intrinsic to contexture itself, never user content — same
9
- * status as ALWAYS_SKIP_DIRS. AGENTS.md is a CLI-generated procedure
10
- * document (task 4.5), not a note; without this it would otherwise be
11
- * picked up as one, since it lives at the store root as a plain .md file.
9
+ * status as ALWAYS_SKIP_DIRS. AGENTS.md is a CLI-generated document
10
+ * (task 4.5), not a note, but only the one `agentsMdPath` ever
11
+ * generates: the store root's own `AGENTS.md` (`agents-doc.ts` hardcodes
12
+ * `path.join(root, 'AGENTS.md')`, never a nested path). A same-named file
13
+ * anywhere else is ordinary content an operator happened to name AGENTS.md
14
+ * — the walk below applies this root-only, the same way it treats a
15
+ * harness's own entry filename (`skipRootFiles`, right below).
12
16
  */
13
17
  const ALWAYS_SKIP_FILES = new Set(['AGENTS.md']);
14
18
  /**
@@ -38,7 +42,7 @@ export function excludedPrefixesFor(config) {
38
42
  config.session.worktrees_path,
39
43
  config.catalog.path,
40
44
  // Tool-owned instruction docs (skills, conventions) are never notes, wherever they live.
41
- config.harness.procedures_path,
45
+ config.harness.skills_path,
42
46
  config.harness.conventions_path,
43
47
  ];
44
48
  }
@@ -63,7 +67,7 @@ async function walk(dir, root, excludePrefixes, skipRootFiles, results) {
63
67
  await walk(fullPath, root, excludePrefixes, skipRootFiles, results);
64
68
  }
65
69
  else if (entry.isFile() && entry.name.endsWith('.md')) {
66
- if (ALWAYS_SKIP_FILES.has(entry.name))
70
+ if (relativePath === entry.name && ALWAYS_SKIP_FILES.has(entry.name))
67
71
  continue;
68
72
  if (relativePath === entry.name && skipRootFiles.has(entry.name))
69
73
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { agentsMdPath, buildAgentsCanonicalSection, buildAgentsCaptureSection, b
3
3
  import { removeFencedRegionFromFile, upsertFencedRegionInFile } from './fs/fenced-region.js';
4
4
  import { configureHooksPath, installHooks } from './hooks.js';
5
5
  import { commentFence, DERIVED_GITIGNORE_FENCE, htmlCommentFence } from './markers.js';
6
- import { syncShippedSkills } from './procedures.js';
6
+ import { syncShippedSkills } from './skills.js';
7
7
  export const WORKTREES_GITIGNORE_FENCE = commentFence('worktrees');
8
8
  /**
9
9
  * remove-agent-identity: AGENTS.md's old "Agent identity" section is an
@@ -33,7 +33,7 @@ export async function reconcileStore(env, root, config) {
33
33
  note('.gitignore', (await upsertFencedRegionInFile(gitignorePath, DERIVED_GITIGNORE_FENCE, config.derived.paths)).changed);
34
34
  note('.gitignore', (await upsertFencedRegionInFile(gitignorePath, WORKTREES_GITIGNORE_FENCE, [config.session.worktrees_path])).changed);
35
35
  // Files the generated sections index (skills) must be current BEFORE the
36
- // sections are rendered — the procedure index is a disk scan.
36
+ // sections are rendered — the skill index is a disk scan.
37
37
  changed.push(...(await syncShippedSkills(root, config)));
38
38
  let agentsChanged = false;
39
39
  for (const build of [
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,CAAC,MAAM,yBAAyB,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,gCAAgC,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;AAO5E;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAY,EAAE,MAAmB;IACjF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,YAAoB,EAAE,SAAkB,EAAQ,EAAE;QAC9D,IAAI,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,uBAAuB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3H,IAAI,CACF,YAAY,EACZ,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,yBAAyB,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CACpH,CAAC;IAEF,yEAAyE;IACzE,8DAA8D;IAC9D,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAEzD,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI;QAClB,4BAA4B;QAC5B,yBAAyB;QACzB,2BAA2B;QAC3B,2BAA2B;QAC3B,6BAA6B;KAC9B,EAAE,CAAC;QACF,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO;YAAE,aAAa,GAAG,IAAI,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,MAAM,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,gCAAgC,CAAC,CAAC,CAAC,OAAO;QAAE,aAAa,GAAG,IAAI,CAAC;IAC3H,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAEjC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACnF,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAC3B,MAAM,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAExC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,CAAC,MAAM,yBAAyB,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,gCAAgC,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;AAO5E;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAY,EAAE,MAAmB;IACjF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,YAAoB,EAAE,SAAkB,EAAQ,EAAE;QAC9D,IAAI,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,uBAAuB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3H,IAAI,CACF,YAAY,EACZ,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,yBAAyB,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CACpH,CAAC;IAEF,yEAAyE;IACzE,0DAA0D;IAC1D,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAEzD,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI;QAClB,4BAA4B;QAC5B,yBAAyB;QACzB,2BAA2B;QAC3B,2BAA2B;QAC3B,6BAA6B;KAC9B,EAAE,CAAC;QACF,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO;YAAE,aAAa,GAAG,IAAI,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,MAAM,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,gCAAgC,CAAC,CAAC,CAAC,OAAO;QAAE,aAAa,GAAG,IAAI,CAAC;IAC3H,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAEjC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACnF,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAC3B,MAAM,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAExC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC"}
@@ -22,8 +22,31 @@ export interface StaleRollupEntry {
22
22
  * counts as newer than any timestamp, since it clearly postdates it.
23
23
  */
24
24
  export declare function checkRollupStaleness(git: GitRunner, root: string, entity: Note, allNotes: readonly Note[], staleDays: number): Promise<StaleRollupEntry | null>;
25
- /** Every entity with a rollup section (optionally narrowed to one), reported stale per `checkRollupStaleness`. */
25
+ /**
26
+ * context-organize spec (D3, generalize-identity-migration-residue): a
27
+ * store-wide mission document has no natural backlink set — nothing
28
+ * wikilinks "the mission" — so its staleness is purely time-based: no
29
+ * recorded timestamp, or one older than `staleDays`, is stale. No git call,
30
+ * no backlink computation. `newestBacklink` is always `null`, which never
31
+ * occurs for a *stale* entry under `checkRollupStaleness`'s backlink rule
32
+ * (an entity with no backlinks is never reported stale there), so `null`
33
+ * unambiguously marks a mission-rule entry to any caller that cares.
34
+ */
35
+ export declare function checkMissionStaleness(note: Note, staleDays: number, now: Date): StaleRollupEntry | null;
36
+ /**
37
+ * Every entity with a rollup section (optionally narrowed to one), reported
38
+ * stale per `checkRollupStaleness`, plus — when `missionPath` names a note
39
+ * that exists in `notes` — that one path via `checkMissionStaleness`
40
+ * instead of the backlink-based entity scan, even when it carries no
41
+ * `ROLLUP_FENCE` yet (an unwritten mission document must surface as
42
+ * needing its first write, not be silently excluded by `hasRollupSection`).
43
+ * The two candidate sources are de-duplicated by entity path before
44
+ * returning; a path matching both the entity scan and the configured
45
+ * `missionPath` is reported once, under the mission (time-based) rule,
46
+ * since that is the operator's explicit configuration choice for that path.
47
+ */
26
48
  export declare function findStaleRollups(git: GitRunner, root: string, notes: readonly Note[], options?: {
27
49
  entity?: string;
28
- }, staleDays?: number): Promise<StaleRollupEntry[]>;
50
+ missionPath?: string;
51
+ }, staleDays?: number, now?: Date): Promise<StaleRollupEntry[]>;
29
52
  //# sourceMappingURL=rollup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollup.d.ts","sourceRoot":"","sources":["../../src/core/rollup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,iHAAiH;AACjH,eAAO,MAAM,YAAY,8BAA6B,CAAC;AACvD,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAEpD;AAaD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,IAAI,EACZ,QAAQ,EAAE,SAAS,IAAI,EAAE,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsBlC;AAED,kHAAkH;AAClH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,EACjC,SAAS,SAAI,GACZ,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAQ7B"}
1
+ {"version":3,"file":"rollup.d.ts","sourceRoot":"","sources":["../../src/core/rollup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,iHAAiH;AACjH,eAAO,MAAM,YAAY,8BAA6B,CAAC;AACvD,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAEpD;AAaD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,IAAI,EACZ,QAAQ,EAAE,SAAS,IAAI,EAAE,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsBlC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,gBAAgB,GAAG,IAAI,CAYvG;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,EACvD,SAAS,SAAI,EACb,GAAG,GAAE,IAAiB,GACrB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAsB7B"}
@@ -46,15 +46,61 @@ export async function checkRollupStaleness(git, root, entity, allNotes, staleDay
46
46
  return null;
47
47
  return { entity: entity.path, rolledUp, newestBacklink: newest };
48
48
  }
49
- /** Every entity with a rollup section (optionally narrowed to one), reported stale per `checkRollupStaleness`. */
50
- export async function findStaleRollups(git, root, notes, options = {}, staleDays = 0) {
49
+ /**
50
+ * context-organize spec (D3, generalize-identity-migration-residue): a
51
+ * store-wide mission document has no natural backlink set — nothing
52
+ * wikilinks "the mission" — so its staleness is purely time-based: no
53
+ * recorded timestamp, or one older than `staleDays`, is stale. No git call,
54
+ * no backlink computation. `newestBacklink` is always `null`, which never
55
+ * occurs for a *stale* entry under `checkRollupStaleness`'s backlink rule
56
+ * (an entity with no backlinks is never reported stale there), so `null`
57
+ * unambiguously marks a mission-rule entry to any caller that cares.
58
+ */
59
+ export function checkMissionStaleness(note, staleDays, now) {
60
+ const recorded = note.frontmatter?.[ROLLED_UP_FIELD];
61
+ const rolledUp = typeof recorded === 'string' ? recorded : null;
62
+ if (rolledUp === null) {
63
+ return { entity: note.path, rolledUp: null, newestBacklink: null };
64
+ }
65
+ const elapsedMs = now.getTime() - new Date(rolledUp).getTime();
66
+ if (elapsedMs < staleDays * 24 * 60 * 60 * 1000)
67
+ return null;
68
+ return { entity: note.path, rolledUp, newestBacklink: null };
69
+ }
70
+ /**
71
+ * Every entity with a rollup section (optionally narrowed to one), reported
72
+ * stale per `checkRollupStaleness`, plus — when `missionPath` names a note
73
+ * that exists in `notes` — that one path via `checkMissionStaleness`
74
+ * instead of the backlink-based entity scan, even when it carries no
75
+ * `ROLLUP_FENCE` yet (an unwritten mission document must surface as
76
+ * needing its first write, not be silently excluded by `hasRollupSection`).
77
+ * The two candidate sources are de-duplicated by entity path before
78
+ * returning; a path matching both the entity scan and the configured
79
+ * `missionPath` is reported once, under the mission (time-based) rule,
80
+ * since that is the operator's explicit configuration choice for that path.
81
+ */
82
+ export async function findStaleRollups(git, root, notes, options = {}, staleDays = 0, now = new Date()) {
51
83
  const candidates = notes.filter((n) => hasRollupSection(n) && (!options.entity || n.path === options.entity));
52
- const results = [];
84
+ const byPath = new Map();
53
85
  for (const candidate of candidates) {
54
86
  const entry = await checkRollupStaleness(git, root, candidate, notes, staleDays);
55
87
  if (entry)
56
- results.push(entry);
88
+ byPath.set(entry.entity, entry);
89
+ }
90
+ if (options.missionPath && (!options.entity || options.entity === options.missionPath)) {
91
+ const missionNote = notes.find((n) => n.path === options.missionPath);
92
+ if (missionNote) {
93
+ const entry = checkMissionStaleness(missionNote, staleDays, now);
94
+ // The mission rule OWNS this path once configured: it overrides the
95
+ // entity scan's verdict for the same note either way — sets a stale
96
+ // entry, or clears one the backlink-based scan produced — never a
97
+ // blend of both rules for one path.
98
+ if (entry)
99
+ byPath.set(options.missionPath, entry);
100
+ else
101
+ byPath.delete(options.missionPath);
102
+ }
57
103
  }
58
- return results.sort((a, b) => a.entity.localeCompare(b.entity));
104
+ return [...byPath.values()].sort((a, b) => a.entity.localeCompare(b.entity));
59
105
  }
60
106
  //# sourceMappingURL=rollup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollup.js","sourceRoot":"","sources":["../../src/core/rollup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rollup.js","sourceRoot":"","sources":["../../src/core/rollup.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,10 @@ import type { StoreConfig, TaxonomyLayerConfig } from '../config/schema.js';
2
2
  import { type ScannedDoc } from './conventions.js';
3
3
  /**
4
4
  * harness-portability spec (task 8.6, revised by entry-doc-generation D5,
5
- * expanded by owned-skills-expansion): reusable store procedures ship as
6
- * contexture-OWNED skills. The canonical content is this module (versioned
5
+ * expanded by owned-skills-expansion): reusable store skills ship as
6
+ * contexture-OWNED files. The canonical content is this module (versioned
7
7
  * with the package); a store carries a full copy at
8
- * `<procedures_path>/ctxr-<slug>/SKILL.md` — written by `ctxr init`,
8
+ * `<skills_path>/ctxr-<slug>/SKILL.md` — written by `ctxr init`,
9
9
  * refreshed by `ctxr update`, never hand-edited. The default location is
10
10
  * the directory harnesses with skill auto-discovery read, so there is no
11
11
  * wrapper and no extra hop; any other harness reaches the same file by
@@ -20,8 +20,8 @@ import { type ScannedDoc } from './conventions.js';
20
20
  * that verifies it. The one config-derived skill (placement) is rendered
21
21
  * per store, which is why a seed's body is a function of the config.
22
22
  */
23
- export interface Procedure {
24
- /** Skill directory slug under config.harness.procedures_path (file is `<slug>/SKILL.md`). */
23
+ export interface Skill {
24
+ /** Skill directory slug under config.harness.skills_path (file is `<slug>/SKILL.md`). */
25
25
  file: string;
26
26
  /** The human title (the H1 in the skill body). */
27
27
  name: string;
@@ -29,7 +29,7 @@ export interface Procedure {
29
29
  description: string;
30
30
  content: string;
31
31
  }
32
- interface ProcedureSeed {
32
+ interface SkillSeed {
33
33
  file: string;
34
34
  name: string;
35
35
  description: string;
@@ -39,17 +39,17 @@ interface ProcedureSeed {
39
39
  export declare const MANAGED_SKILL_HEADER = "<!-- Owned by contexture \u2014 written by `ctxr init`, refreshed by `ctxr update`. Do not edit; add your own skills alongside. -->";
40
40
  export declare function terminatingLayers(config: StoreConfig): TaxonomyLayerConfig[];
41
41
  export declare function retiredLayers(config: StoreConfig): TaxonomyLayerConfig[];
42
- export declare const PROCEDURES: readonly ProcedureSeed[];
42
+ export declare const SKILLS: readonly SkillSeed[];
43
43
  /** The owned skills, rendered against one store's configuration — what `syncShippedSkills` writes. */
44
- export declare function renderProcedures(config: StoreConfig): Procedure[];
44
+ export declare function renderSkills(config: StoreConfig): Skill[];
45
45
  /**
46
46
  * entry-doc-generation spec: every skill actually on disk — the contexture-
47
47
  * owned ones plus any operator-authored ones. This is what the AGENTS.md
48
- * index and verify --portable consume; the static PROCEDURES const is only
48
+ * index and verify --portable consume; the static SKILLS const is only
49
49
  * the canonical content syncShippedSkills writes.
50
50
  */
51
- export declare function scanProcedures(root: string, config: StoreConfig): Promise<ScannedDoc[]>;
52
- export declare function procedurePaths(config: StoreConfig): string[];
51
+ export declare function scanSkills(root: string, config: StoreConfig): Promise<ScannedDoc[]>;
52
+ export declare function skillPaths(config: StoreConfig): string[];
53
53
  /**
54
54
  * Brings every contexture-owned skill copy to the installed package's
55
55
  * content: written when missing, rewritten when different (byte-stable —
@@ -61,4 +61,4 @@ export declare function procedurePaths(config: StoreConfig): string[];
61
61
  */
62
62
  export declare function syncShippedSkills(root: string, config: StoreConfig): Promise<string[]>;
63
63
  export {};
64
- //# sourceMappingURL=procedures.d.ts.map
64
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAcjF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,KAAK;IACpB,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,EAAE,CAAC;CACzC;AAED,eAAO,MAAM,oBAAoB,wIACiG,CAAC;AAYnI,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,EAAE,CAE5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,EAAE,CAExE;AA+LD,eAAO,MAAM,MAAM,EAAE,SAAS,SAAS,EAatC,CAAC;AAEF,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,EAAE,CAOzD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAEnF;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAExD;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA2C5F"}
@@ -1,32 +1,16 @@
1
- import { readFileSync } from 'node:fs';
2
1
  import { mkdir, readdir, readFile, rm } from 'node:fs/promises';
3
2
  import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
3
  import { scanDocsDir, SKILL_FILE_NAME } from './conventions.js';
4
+ import { GRAPH_DOCUMENT_RELATIVE_PATH } from './graph/persist.js';
6
5
  import { writeFileAtomic } from './fs/atomic.js';
6
+ import { packagedTemplate } from './templates.js';
7
7
  /**
8
- * extract-skill-templates: canonical skill bodies live as plain markdown
9
- * files under `templates/skills/` (reviewable, diffable, syntax-highlighted)
10
- * rather than as inline TypeScript string arrays — the same pattern
11
- * `hooks.ts`'s `templatesDir()` already uses for the git hook templates.
12
- * Loaded synchronously, once, at module init: `ProcedureSeed.body` is called
13
- * synchronously from many call sites (including throughout the test suite),
14
- * and these are fixed, package-bundled files whose content never changes
15
- * after the process starts — threading `async` through every call site to
16
- * read a file once would be a large, purely mechanical change for no
17
- * behavioral gain.
8
+ * The canonical skill bodies live as plain markdown under
9
+ * `templates/skills/` — see `templates.ts` for why they are loaded
10
+ * synchronously and cached.
18
11
  */
19
- function skillTemplatesDir() {
20
- return fileURLToPath(new URL('../../templates/skills', import.meta.url));
21
- }
22
- const skillTemplateCache = new Map();
23
12
  function skillTemplate(slug) {
24
- const cached = skillTemplateCache.get(slug);
25
- if (cached !== undefined)
26
- return cached;
27
- const text = readFileSync(path.join(skillTemplatesDir(), `${slug}.md`), 'utf8').replace(/\n$/, '');
28
- skillTemplateCache.set(slug, text);
29
- return text;
13
+ return packagedTemplate('skills', slug);
30
14
  }
31
15
  export const MANAGED_SKILL_HEADER = '<!-- Owned by contexture — written by `ctxr init`, refreshed by `ctxr update`. Do not edit; add your own skills alongside. -->';
32
16
  /**
@@ -101,13 +85,13 @@ const INGEST_ORCHESTRATION = {
101
85
  file: 'ctxr-ingest-orchestration',
102
86
  name: 'Ingest orchestration',
103
87
  description: 'Capture raw material into the inbox, run the dedupe check, read the existing cluster, decide new/update/merge/restructure, and ingest with source identity via the contexture CLI.',
104
- body: () => skillTemplate('ctxr-ingest-orchestration').split('\n'),
88
+ body: () => skillTemplate('ctxr-ingest-orchestration').replaceAll('__GRAPH_DOCUMENT_PATH__', GRAPH_DOCUMENT_RELATIVE_PATH).split('\n'),
105
89
  };
106
90
  const CONNECTION_FINDING = {
107
91
  file: 'ctxr-connection-finding',
108
92
  name: 'Connection finding',
109
93
  description: 'Traverse the wikilink graph of the store (neighbors, paths, hubs, orphans) to find what a note already connects to.',
110
- body: () => skillTemplate('ctxr-connection-finding').split('\n'),
94
+ body: () => skillTemplate('ctxr-connection-finding').replaceAll('__GRAPH_DOCUMENT_PATH__', GRAPH_DOCUMENT_RELATIVE_PATH).split('\n'),
111
95
  };
112
96
  /**
113
97
  * graph-context-document spec: the proposal skill groups by the CONFIGURED
@@ -140,6 +124,12 @@ const ROLLUP = {
140
124
  description: 'Regenerate the synthesized current-state region of an entity note from every source that references it, with provenance for every fact.',
141
125
  body: () => skillTemplate('ctxr-rollup').split('\n'),
142
126
  };
127
+ const MISSION = {
128
+ file: 'ctxr-mission',
129
+ name: 'Mission',
130
+ description: "Keep the store's mission document current from recent work and its taxonomy layers, with every active priority naming its status/purpose/next action, back-burner items stating why they're dormant, and sunset candidates and debt carried as their own sections.",
131
+ body: () => skillTemplate('ctxr-mission').split('\n'),
132
+ };
143
133
  const SUBMIT = {
144
134
  file: 'ctxr-submit',
145
135
  name: 'Submit',
@@ -152,11 +142,34 @@ const LAND = {
152
142
  description: 'Complete a reviewed session — merge its pull request, sync the default branch, and reclaim the worktree — one gated command, never a manual merge.',
153
143
  body: (config) => skillTemplate('ctxr-land').replaceAll('__DEFAULT_BRANCH__', config.git.default_branch).split('\n'),
154
144
  };
145
+ /**
146
+ * write-lifecycle spec: when `session.workspaces_external` is true, worktree
147
+ * lifecycle is owned by a process outside `ctxr` (e.g. an external
148
+ * agent-runtime WebUI) — the rendered skill must not instruct creating,
149
+ * switching, unlocking, removing, or pruning one. False/unset keeps the
150
+ * prior text byte-identical.
151
+ */
152
+ function reclaimingStep(config) {
153
+ if (config.session.workspaces_external) {
154
+ return [
155
+ 'Session worktrees are provided externally (`session.workspaces_external: true`) — this skill MUST NOT',
156
+ 'create, switch to, unlock, remove, or prune a worktree. `ctxr session reap` refuses to run under this',
157
+ 'configuration; reclaiming worktrees is the external process\'s responsibility, not this skill\'s.',
158
+ ];
159
+ }
160
+ return [
161
+ '`ctxr session reap` removes merged, clean worktrees (or use `ctxr-land`\'s `--reap`); `ctxr session abandon',
162
+ '<branch>` discards work and needs an explicit go. Never claim cleanup happened without having run one.',
163
+ ];
164
+ }
155
165
  const SESSION_LIFECYCLE = {
156
166
  file: 'ctxr-session-lifecycle',
157
167
  name: 'Session lifecycle',
158
168
  description: 'Start a session worktree, re-scan before any plan, resolve conflicts, and sequence multiple pull requests — the frame ctxr-submit and ctxr-land sit inside.',
159
- body: (config) => skillTemplate('ctxr-session-lifecycle').replaceAll('__DEFAULT_BRANCH__', config.git.default_branch).split('\n'),
169
+ body: (config) => skillTemplate('ctxr-session-lifecycle')
170
+ .replaceAll('__DEFAULT_BRANCH__', config.git.default_branch)
171
+ .replace('__RECLAIMING_STEP__', reclaimingStep(config).join('\n'))
172
+ .split('\n'),
160
173
  };
161
174
  const SESSION_CAPTURE = {
162
175
  file: 'ctxr-session-capture',
@@ -176,12 +189,13 @@ const ORGANIZE_AUDIT = {
176
189
  description: 'Audit store health with ctxr lint (observations) and ctxr doctor (blocking invariants), retire by moving, and classify broken links before fixing them.',
177
190
  body: () => skillTemplate('ctxr-organize-audit').split('\n'),
178
191
  };
179
- export const PROCEDURES = [
192
+ export const SKILLS = [
180
193
  INGEST_ORCHESTRATION,
181
194
  PLACEMENT,
182
195
  CONNECTION_FINDING,
183
196
  CONNECTION_PROPOSAL,
184
197
  ROLLUP,
198
+ MISSION,
185
199
  SESSION_LIFECYCLE,
186
200
  SUBMIT,
187
201
  LAND,
@@ -190,8 +204,8 @@ export const PROCEDURES = [
190
204
  ORGANIZE_AUDIT,
191
205
  ];
192
206
  /** The owned skills, rendered against one store's configuration — what `syncShippedSkills` writes. */
193
- export function renderProcedures(config) {
194
- return PROCEDURES.map((seed) => ({
207
+ export function renderSkills(config) {
208
+ return SKILLS.map((seed) => ({
195
209
  file: seed.file,
196
210
  name: seed.name,
197
211
  description: seed.description,
@@ -201,14 +215,14 @@ export function renderProcedures(config) {
201
215
  /**
202
216
  * entry-doc-generation spec: every skill actually on disk — the contexture-
203
217
  * owned ones plus any operator-authored ones. This is what the AGENTS.md
204
- * index and verify --portable consume; the static PROCEDURES const is only
218
+ * index and verify --portable consume; the static SKILLS const is only
205
219
  * the canonical content syncShippedSkills writes.
206
220
  */
207
- export function scanProcedures(root, config) {
208
- return scanDocsDir(root, config.harness.procedures_path);
221
+ export function scanSkills(root, config) {
222
+ return scanDocsDir(root, config.harness.skills_path);
209
223
  }
210
- export function procedurePaths(config) {
211
- return PROCEDURES.map((p) => path.join(config.harness.procedures_path, p.file, SKILL_FILE_NAME).split(path.sep).join('/'));
224
+ export function skillPaths(config) {
225
+ return SKILLS.map((p) => path.join(config.harness.skills_path, p.file, SKILL_FILE_NAME).split(path.sep).join('/'));
212
226
  }
213
227
  /**
214
228
  * Brings every contexture-owned skill copy to the installed package's
@@ -221,9 +235,9 @@ export function procedurePaths(config) {
221
235
  */
222
236
  export async function syncShippedSkills(root, config) {
223
237
  const changed = [];
224
- for (const procedure of renderProcedures(config)) {
238
+ for (const skill of renderSkills(config)) {
225
239
  const relativePath = path
226
- .join(config.harness.procedures_path, procedure.file, SKILL_FILE_NAME)
240
+ .join(config.harness.skills_path, skill.file, SKILL_FILE_NAME)
227
241
  .split(path.sep)
228
242
  .join('/');
229
243
  const absolutePath = path.join(root, relativePath);
@@ -234,14 +248,14 @@ export async function syncShippedSkills(root, config) {
234
248
  catch {
235
249
  existing = undefined;
236
250
  }
237
- if (existing !== procedure.content) {
251
+ if (existing !== skill.content) {
238
252
  await mkdir(path.dirname(absolutePath), { recursive: true });
239
- await writeFileAtomic(absolutePath, procedure.content);
253
+ await writeFileAtomic(absolutePath, skill.content);
240
254
  changed.push(relativePath);
241
255
  }
242
256
  }
243
- const shippedSlugs = new Set(PROCEDURES.map((p) => p.file));
244
- const skillsDir = path.join(root, config.harness.procedures_path);
257
+ const shippedSlugs = new Set(SKILLS.map((p) => p.file));
258
+ const skillsDir = path.join(root, config.harness.skills_path);
245
259
  let entries = [];
246
260
  try {
247
261
  entries = await readdir(skillsDir, { withFileTypes: true });
@@ -263,8 +277,8 @@ export async function syncShippedSkills(root, config) {
263
277
  if (!content.includes(MANAGED_SKILL_HEADER))
264
278
  continue; // operator-authored: never touched
265
279
  await rm(path.join(skillsDir, entry.name), { recursive: true, force: true });
266
- changed.push(path.join(config.harness.procedures_path, entry.name, SKILL_FILE_NAME).split(path.sep).join('/'));
280
+ changed.push(path.join(config.harness.skills_path, entry.name, SKILL_FILE_NAME).split(path.sep).join('/'));
267
281
  }
268
282
  return changed;
269
283
  }
270
- //# sourceMappingURL=procedures.js.map
284
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `templates/<dir>/<name>.md`, with exactly one trailing newline stripped —
3
+ * so a template file that looks like a normal file (ends with a newline)
4
+ * yields the same line array an inline `[...]` literal would have.
5
+ */
6
+ export declare function packagedTemplate(dir: string, name: string): string;
7
+ /**
8
+ * Splices a computed list of lines in where `token` sits alone on its own
9
+ * line. An EMPTY list removes that line entirely, rather than leaving a
10
+ * blank one behind — which is what a plain `.replace(token, '')` would do,
11
+ * and is the difference between byte-identical output and a stray blank
12
+ * line. The empty case is not hypothetical: an index block renders empty
13
+ * whenever its scanned directory is missing.
14
+ *
15
+ * Throws when the token is absent, so a mistyped placeholder name fails at
16
+ * render time instead of silently shipping the literal `__TOKEN__` string
17
+ * into a store's AGENTS.md.
18
+ */
19
+ export declare function substituteBlock(text: string, token: string, lines: readonly string[]): string;
20
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAe7F"}
@@ -0,0 +1,68 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * extract-skill-templates, extended by extract-agents-doc-templates: every
6
+ * piece of prose contexture ships into a store — owned-skill bodies, the
7
+ * generated AGENTS.md sections — is authored as a plain markdown file under
8
+ * `templates/`, reviewable and diffable as markdown rather than as quoted,
9
+ * escaped TypeScript string fragments. This module is the single loader for
10
+ * them, resolving the same way `hooks.ts`'s `templatesDir()` does.
11
+ *
12
+ * Loaded synchronously, once, and cached: the render functions in
13
+ * `skills.ts` and `agents-doc.ts` are synchronous with many synchronous
14
+ * call sites (the test suite especially), and these are fixed,
15
+ * package-bundled files whose content cannot change after process start.
16
+ * Threading `async` through every caller to read a file once would be a
17
+ * large mechanical change for no behavioral gain. `hooks.ts` deliberately
18
+ * does not share this loader: it is async because every caller awaits it,
19
+ * and a shell script must keep the trailing newline this strips.
20
+ */
21
+ function templatesDir(dir) {
22
+ return fileURLToPath(new URL(`../../templates/${dir}`, import.meta.url));
23
+ }
24
+ const cache = new Map();
25
+ /**
26
+ * `templates/<dir>/<name>.md`, with exactly one trailing newline stripped —
27
+ * so a template file that looks like a normal file (ends with a newline)
28
+ * yields the same line array an inline `[...]` literal would have.
29
+ */
30
+ export function packagedTemplate(dir, name) {
31
+ const key = `${dir}/${name}`;
32
+ const cached = cache.get(key);
33
+ if (cached !== undefined)
34
+ return cached;
35
+ const text = readFileSync(path.join(templatesDir(dir), `${name}.md`), 'utf8').replace(/\n$/, '');
36
+ cache.set(key, text);
37
+ return text;
38
+ }
39
+ /**
40
+ * Splices a computed list of lines in where `token` sits alone on its own
41
+ * line. An EMPTY list removes that line entirely, rather than leaving a
42
+ * blank one behind — which is what a plain `.replace(token, '')` would do,
43
+ * and is the difference between byte-identical output and a stray blank
44
+ * line. The empty case is not hypothetical: an index block renders empty
45
+ * whenever its scanned directory is missing.
46
+ *
47
+ * Throws when the token is absent, so a mistyped placeholder name fails at
48
+ * render time instead of silently shipping the literal `__TOKEN__` string
49
+ * into a store's AGENTS.md.
50
+ */
51
+ export function substituteBlock(text, token, lines) {
52
+ const out = [];
53
+ let found = false;
54
+ for (const line of text.split('\n')) {
55
+ if (line === token) {
56
+ found = true;
57
+ out.push(...lines);
58
+ }
59
+ else {
60
+ out.push(line);
61
+ }
62
+ }
63
+ if (!found) {
64
+ throw new Error(`template block placeholder ${token} not found on a line of its own`);
65
+ }
66
+ return out.join('\n');
67
+ }
68
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,mBAAmB,GAAG,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,IAAY;IACxD,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,KAAa,EAAE,KAAwB;IACnF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,KAAK,GAAG,IAAI,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,iCAAiC,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
@@ -17,4 +17,32 @@ export interface PathGateResult {
17
17
  * contexture-owned location passes.
18
18
  */
19
19
  export declare function sanctionedPath(config: StoreConfig, root: string, relativePath: string): Promise<PathGateResult>;
20
+ export interface WriteScopeResult {
21
+ inScope: boolean;
22
+ reason?: string;
23
+ }
24
+ /**
25
+ * The Claude Code write-gate hook's question: is `relativePath` safe for a
26
+ * session opened at the store root to edit directly? In scope when it
27
+ * resolves outside the store entirely (not this gate's concern — the
28
+ * store's canonical checkout is what it protects) or inside the configured
29
+ * session-worktree tree; out of scope, and denied, when it resolves inside
30
+ * the store root's own content, including when a symlink disguises the
31
+ * escape in either direction (reuses `resolveStorePath`'s escape check,
32
+ * same as `sanctionedPath`, so the two can never disagree on what counts as
33
+ * an escape).
34
+ *
35
+ * A `root` that is itself a linked worktree checkout is always in scope,
36
+ * regardless of `relativePath`: `openStore` resolves the store root by
37
+ * walking up from cwd for the nearest `contexture.yaml`, and every session
38
+ * worktree carries its own copy of that file — so a session whose cwd is
39
+ * already inside the worktree resolves the worktree itself as `root`, and
40
+ * without this carve-out every edit in it would read as "in the store root,
41
+ * outside the worktree" and be denied. The gate's actual job is protecting
42
+ * the canonical checkout; a linked worktree IS the sanctioned workspace,
43
+ * whichever directory a session happens to be driven from — this also
44
+ * covers `session.workspaces_external: true` stores, whose worktrees an
45
+ * external process may place outside `session.worktrees_path` entirely.
46
+ */
47
+ export declare function isWriteInScope(config: StoreConfig, root: string, relativePath: string): Promise<WriteScopeResult>;
20
48
  //# sourceMappingURL=path-gate.d.ts.map