ctxr-cli 0.4.0 → 0.5.0
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.
- package/dist/adapters/harness/claude-code.d.ts +0 -6
- package/dist/adapters/harness/claude-code.d.ts.map +1 -1
- package/dist/adapters/harness/claude-code.js +44 -25
- package/dist/adapters/harness/claude-code.js.map +1 -1
- package/dist/adapters/types.d.ts +28 -9
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/commands/adapters-generate.d.ts.map +1 -1
- package/dist/commands/adapters-generate.js +15 -3
- package/dist/commands/adapters-generate.js.map +1 -1
- package/dist/commands/adapters-write-gate.d.ts +20 -0
- package/dist/commands/adapters-write-gate.d.ts.map +1 -0
- package/dist/commands/adapters-write-gate.js +77 -0
- package/dist/commands/adapters-write-gate.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +57 -9
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/rollup-write.d.ts.map +1 -1
- package/dist/commands/rollup-write.js +8 -0
- package/dist/commands/rollup-write.js.map +1 -1
- package/dist/commands/session-land.d.ts.map +1 -1
- package/dist/commands/session-land.js +55 -24
- package/dist/commands/session-land.js.map +1 -1
- package/dist/commands/verify.d.ts +9 -2
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +50 -27
- package/dist/commands/verify.js.map +1 -1
- package/dist/config/defaults.d.ts +20 -4
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +20 -4
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +29 -5
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +73 -5
- package/dist/config/schema.js.map +1 -1
- package/dist/core/agents-doc.d.ts +71 -16
- package/dist/core/agents-doc.d.ts.map +1 -1
- package/dist/core/agents-doc.js +220 -139
- package/dist/core/agents-doc.js.map +1 -1
- package/dist/core/checks/harness-portability-checks.d.ts +12 -0
- package/dist/core/checks/harness-portability-checks.d.ts.map +1 -0
- package/dist/core/checks/harness-portability-checks.js +39 -0
- package/dist/core/checks/harness-portability-checks.js.map +1 -0
- package/dist/core/checks/integrity-checks.d.ts +25 -1
- package/dist/core/checks/integrity-checks.d.ts.map +1 -1
- package/dist/core/checks/integrity-checks.js +136 -3
- package/dist/core/checks/integrity-checks.js.map +1 -1
- package/dist/core/checks/manifest.d.ts.map +1 -1
- package/dist/core/checks/manifest.js +2 -0
- package/dist/core/checks/manifest.js.map +1 -1
- package/dist/core/checks/organize-checks.d.ts +12 -0
- package/dist/core/checks/organize-checks.d.ts.map +1 -1
- package/dist/core/checks/organize-checks.js +51 -1
- package/dist/core/checks/organize-checks.js.map +1 -1
- package/dist/core/convention-doc.d.ts +33 -0
- package/dist/core/convention-doc.d.ts.map +1 -0
- package/dist/core/convention-doc.js +110 -0
- package/dist/core/convention-doc.js.map +1 -0
- package/dist/core/conventions.d.ts +25 -5
- package/dist/core/conventions.d.ts.map +1 -1
- package/dist/core/conventions.js +65 -3
- package/dist/core/conventions.js.map +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +2 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/fs/fenced-region.d.ts +38 -0
- package/dist/core/fs/fenced-region.d.ts.map +1 -1
- package/dist/core/fs/fenced-region.js +88 -2
- package/dist/core/fs/fenced-region.js.map +1 -1
- package/dist/core/git/repo.d.ts +10 -0
- package/dist/core/git/repo.d.ts.map +1 -1
- package/dist/core/git/repo.js +28 -0
- package/dist/core/git/repo.js.map +1 -1
- package/dist/core/git/worktree.d.ts +8 -0
- package/dist/core/git/worktree.d.ts.map +1 -1
- package/dist/core/git/worktree.js +11 -0
- package/dist/core/git/worktree.js.map +1 -1
- package/dist/core/hooks.d.ts +10 -0
- package/dist/core/hooks.d.ts.map +1 -1
- package/dist/core/hooks.js +37 -10
- package/dist/core/hooks.js.map +1 -1
- package/dist/core/json-config-merge.d.ts +26 -2
- package/dist/core/json-config-merge.d.ts.map +1 -1
- package/dist/core/json-config-merge.js +61 -7
- package/dist/core/json-config-merge.js.map +1 -1
- package/dist/core/migrations/registry.d.ts.map +1 -1
- package/dist/core/migrations/registry.js +7 -1
- package/dist/core/migrations/registry.js.map +1 -1
- package/dist/core/migrations/rename-conventions-path.d.ts +26 -0
- package/dist/core/migrations/rename-conventions-path.d.ts.map +1 -0
- package/dist/core/migrations/rename-conventions-path.js +86 -0
- package/dist/core/migrations/rename-conventions-path.js.map +1 -0
- package/dist/core/migrations/rename-procedures-path.d.ts +17 -0
- package/dist/core/migrations/rename-procedures-path.d.ts.map +1 -0
- package/dist/core/migrations/rename-procedures-path.js +45 -0
- package/dist/core/migrations/rename-procedures-path.js.map +1 -0
- package/dist/core/notes/list.js +5 -5
- package/dist/core/notes/list.js.map +1 -1
- package/dist/core/reconcile.d.ts.map +1 -1
- package/dist/core/reconcile.js +32 -5
- package/dist/core/reconcile.js.map +1 -1
- package/dist/core/rollup.d.ts +2 -2
- package/dist/core/rollup.d.ts.map +1 -1
- package/dist/core/rollup.js +24 -3
- package/dist/core/rollup.js.map +1 -1
- package/dist/core/{procedures.d.ts → skills.d.ts} +12 -12
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/{procedures.js → skills.js} +25 -41
- package/dist/core/skills.js.map +1 -0
- package/dist/core/templates.d.ts +20 -0
- package/dist/core/templates.d.ts.map +1 -0
- package/dist/core/templates.js +68 -0
- package/dist/core/templates.js.map +1 -0
- package/dist/core/write-lifecycle/path-gate.d.ts +28 -0
- package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
- package/dist/core/write-lifecycle/path-gate.js +78 -22
- package/dist/core/write-lifecycle/path-gate.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +12 -1
- package/dist/run.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/templates/agents/canonical.md +20 -0
- package/templates/agents/capture-and-ingest.md +17 -0
- package/templates/agents/conventions.md +5 -0
- package/templates/agents/mission.md +5 -0
- package/templates/agents/placement-no-layers.md +5 -0
- package/templates/agents/placement.md +7 -0
- package/templates/agents/retrieval-leg-routing.md +14 -0
- package/templates/conventions/baseline-convention.md +60 -0
- package/templates/conventions/custom-convention-seed.md +21 -0
- package/templates/hooks/claude-code-write-gate.sh +15 -0
- package/templates/skills/ctxr-connection-finding.md +1 -1
- package/templates/skills/ctxr-ingest-orchestration.md +1 -1
- package/templates/skills/ctxr-land.md +11 -6
- package/dist/core/procedures.d.ts.map +0 -1
- package/dist/core/procedures.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAiBvC,eAAO,MAAM,yBAAyB,8BAA4B,CAAC;AAwBnE,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAoD7G"}
|
package/dist/core/reconcile.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { DEFAULT_BASELINE_CONVENTION_FILE_NAME } from '../config/defaults.js';
|
|
3
|
+
import { agentsMdPath, AGENTS_MD_SECTION_ORDER, buildAgentsCanonicalSection, buildAgentsCaptureSection, buildAgentsConventionsSection, buildAgentsLegRoutingSection, buildAgentsMissionSection, buildAgentsPlacementSection, } from './agents-doc.js';
|
|
4
|
+
import { syncBaselineConvention } from './convention-doc.js';
|
|
5
|
+
import { removeFencedRegionFromFile, reorderFencedRegionsInFile, upsertFencedRegionInFile } from './fs/fenced-region.js';
|
|
4
6
|
import { configureHooksPath, installHooks } from './hooks.js';
|
|
5
7
|
import { commentFence, DERIVED_GITIGNORE_FENCE, htmlCommentFence } from './markers.js';
|
|
6
|
-
import { syncShippedSkills } from './
|
|
8
|
+
import { syncShippedSkills } from './skills.js';
|
|
7
9
|
export const WORKTREES_GITIGNORE_FENCE = commentFence('worktrees');
|
|
8
10
|
/**
|
|
9
11
|
* remove-agent-identity: AGENTS.md's old "Agent identity" section is an
|
|
@@ -15,6 +17,16 @@ export const WORKTREES_GITIGNORE_FENCE = commentFence('worktrees');
|
|
|
15
17
|
* contexture issue #14 tracks.
|
|
16
18
|
*/
|
|
17
19
|
const RETIRED_AGENTS_MD_IDENTITY_FENCE = htmlCommentFence('agent-identity');
|
|
20
|
+
/**
|
|
21
|
+
* compose-store-guidance-documents: the conventions fence was renamed from
|
|
22
|
+
* `store-conventions` to `conventions` (dropping the redundant "store-"
|
|
23
|
+
* prefix — every sibling fence/template already omits it, e.g. `canonical`,
|
|
24
|
+
* `placement`, `mission`). Same one-time cleanup shape as the identity
|
|
25
|
+
* retirement above: `buildAgentsConventionsSection` already writes the new
|
|
26
|
+
* `contexture:conventions` fence via the loop below, so this only needs to
|
|
27
|
+
* remove the orphaned old one.
|
|
28
|
+
*/
|
|
29
|
+
const RETIRED_AGENTS_MD_STORE_CONVENTIONS_FENCE = htmlCommentFence('store-conventions');
|
|
18
30
|
/**
|
|
19
31
|
* Brings every contexture-OWNED file in a store to the installed package's
|
|
20
32
|
* version: the managed .gitignore blocks, every generated AGENTS.md
|
|
@@ -32,15 +44,22 @@ export async function reconcileStore(env, root, config) {
|
|
|
32
44
|
const gitignorePath = path.join(root, '.gitignore');
|
|
33
45
|
note('.gitignore', (await upsertFencedRegionInFile(gitignorePath, DERIVED_GITIGNORE_FENCE, config.derived.paths)).changed);
|
|
34
46
|
note('.gitignore', (await upsertFencedRegionInFile(gitignorePath, WORKTREES_GITIGNORE_FENCE, [config.session.worktrees_path])).changed);
|
|
35
|
-
//
|
|
36
|
-
//
|
|
47
|
+
// The owned skill copies are refreshed unconditionally here — not because
|
|
48
|
+
// any AGENTS.md section reads them anymore (inline-conventions-and-mission
|
|
49
|
+
// removed the skill index), but because init/update must still deliver
|
|
50
|
+
// the skill files to disk regardless of what AGENTS.md renders.
|
|
37
51
|
changed.push(...(await syncShippedSkills(root, config)));
|
|
52
|
+
// Same reason, same ordering constraint as skills: the shipped baseline
|
|
53
|
+
// convention file must be current on disk BEFORE buildAgentsConventionsSection
|
|
54
|
+
// scans the guidance directory and inlines it (compose-store-guidance-documents).
|
|
55
|
+
note(path.join(config.harness.guidance_path, DEFAULT_BASELINE_CONVENTION_FILE_NAME).split(path.sep).join('/'), (await syncBaselineConvention(root, config)).changed);
|
|
38
56
|
let agentsChanged = false;
|
|
39
57
|
for (const build of [
|
|
40
58
|
buildAgentsLegRoutingSection,
|
|
41
59
|
buildAgentsCaptureSection,
|
|
42
60
|
buildAgentsPlacementSection,
|
|
43
61
|
buildAgentsCanonicalSection,
|
|
62
|
+
buildAgentsMissionSection,
|
|
44
63
|
buildAgentsConventionsSection,
|
|
45
64
|
]) {
|
|
46
65
|
if ((await build(root, config)).changed)
|
|
@@ -48,6 +67,14 @@ export async function reconcileStore(env, root, config) {
|
|
|
48
67
|
}
|
|
49
68
|
if ((await removeFencedRegionFromFile(agentsMdPath(root), RETIRED_AGENTS_MD_IDENTITY_FENCE)).changed)
|
|
50
69
|
agentsChanged = true;
|
|
70
|
+
if ((await removeFencedRegionFromFile(agentsMdPath(root), RETIRED_AGENTS_MD_STORE_CONVENTIONS_FENCE)).changed)
|
|
71
|
+
agentsChanged = true;
|
|
72
|
+
// harness-portability spec "Generated sections render in a fixed order":
|
|
73
|
+
// reorders once every section fence above has been written/refreshed, so
|
|
74
|
+
// a first-time init and a subsequent update converge on the same layout.
|
|
75
|
+
// A no-op when the fences aren't all contiguous — see `reorderFencedRegions`.
|
|
76
|
+
if ((await reorderFencedRegionsInFile(agentsMdPath(root), AGENTS_MD_SECTION_ORDER)).changed)
|
|
77
|
+
agentsChanged = true;
|
|
51
78
|
note('AGENTS.md', agentsChanged);
|
|
52
79
|
const { changed: hookFiles } = await installHooks(root, config.git.default_branch);
|
|
53
80
|
changed.push(...hookFiles);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"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"}
|
package/dist/core/rollup.d.ts
CHANGED
|
@@ -35,8 +35,8 @@ export declare function checkRollupStaleness(git: GitRunner, root: string, entit
|
|
|
35
35
|
export declare function checkMissionStaleness(note: Note, staleDays: number, now: Date): StaleRollupEntry | null;
|
|
36
36
|
/**
|
|
37
37
|
* Every entity with a rollup section (optionally narrowed to one), reported
|
|
38
|
-
* stale per `checkRollupStaleness`, plus — when `missionPath` names a
|
|
39
|
-
* that exists
|
|
38
|
+
* stale per `checkRollupStaleness`, plus — when `missionPath` names a
|
|
39
|
+
* document that exists on disk — that one path via `checkMissionStaleness`
|
|
40
40
|
* instead of the backlink-based entity scan, even when it carries no
|
|
41
41
|
* `ROLLUP_FENCE` yet (an unwritten mission document must surface as
|
|
42
42
|
* needing its first write, not be silently excluded by `hasRollupSection`).
|
|
@@ -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;
|
|
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;AAG5C,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;AAqBD;;;;;;;;;;;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"}
|
package/dist/core/rollup.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { extractLinkTargets } from './graph/model.js';
|
|
3
3
|
import { htmlCommentFence } from './markers.js';
|
|
4
|
+
import { parseNote } from './notes/parse.js';
|
|
4
5
|
/** The single fenced region `rollup write` writes into, and the frontmatter timestamp it stamps alongside it. */
|
|
5
6
|
export const ROLLUP_FENCE = htmlCommentFence('rollup');
|
|
6
7
|
export const ROLLED_UP_FIELD = 'rolled_up';
|
|
@@ -67,10 +68,30 @@ export function checkMissionStaleness(note, staleDays, now) {
|
|
|
67
68
|
return null;
|
|
68
69
|
return { entity: note.path, rolledUp, newestBacklink: null };
|
|
69
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* compose-store-guidance-documents: the mission document typically lives
|
|
73
|
+
* under the guidance directory, which is excluded from the store's note
|
|
74
|
+
* listing (tool-owned instruction docs are never notes — see
|
|
75
|
+
* `excludedPrefixesFor`), so it is read directly by path here rather than
|
|
76
|
+
* looked up in the `notes` array `findStaleRollups` already has. A missing
|
|
77
|
+
* file (never seeded, or a hand-configured path that doesn't exist yet)
|
|
78
|
+
* yields no candidate, the same as the old array-lookup did when nothing
|
|
79
|
+
* matched.
|
|
80
|
+
*/
|
|
81
|
+
async function readMissionNote(root, missionPath) {
|
|
82
|
+
try {
|
|
83
|
+
return await parseNote(path.join(root, missionPath), missionPath);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
if (err.code === 'ENOENT')
|
|
87
|
+
return null;
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
70
91
|
/**
|
|
71
92
|
* Every entity with a rollup section (optionally narrowed to one), reported
|
|
72
|
-
* stale per `checkRollupStaleness`, plus — when `missionPath` names a
|
|
73
|
-
* that exists
|
|
93
|
+
* stale per `checkRollupStaleness`, plus — when `missionPath` names a
|
|
94
|
+
* document that exists on disk — that one path via `checkMissionStaleness`
|
|
74
95
|
* instead of the backlink-based entity scan, even when it carries no
|
|
75
96
|
* `ROLLUP_FENCE` yet (an unwritten mission document must surface as
|
|
76
97
|
* needing its first write, not be silently excluded by `hasRollupSection`).
|
|
@@ -88,7 +109,7 @@ export async function findStaleRollups(git, root, notes, options = {}, staleDays
|
|
|
88
109
|
byPath.set(entry.entity, entry);
|
|
89
110
|
}
|
|
90
111
|
if (options.missionPath && (!options.entity || options.entity === options.missionPath)) {
|
|
91
|
-
const missionNote =
|
|
112
|
+
const missionNote = await readMissionNote(root, options.missionPath);
|
|
92
113
|
if (missionNote) {
|
|
93
114
|
const entry = checkMissionStaleness(missionNote, staleDays, now);
|
|
94
115
|
// The mission rule OWNS this path once configured: it overrides the
|
package/dist/core/rollup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rollup.js","sourceRoot":"","sources":["../../src/core/rollup.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;
|
|
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
|
|
6
|
-
* contexture-OWNED
|
|
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
|
-
* `<
|
|
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
|
|
24
|
-
/** Skill directory slug under config.harness.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
52
|
-
export declare function
|
|
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=
|
|
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
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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
|
-
|
|
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
|
|
@@ -168,7 +152,7 @@ const LAND = {
|
|
|
168
152
|
function reclaimingStep(config) {
|
|
169
153
|
if (config.session.workspaces_external) {
|
|
170
154
|
return [
|
|
171
|
-
'Session worktrees are provided externally (`session.workspaces_external: true`) — this
|
|
155
|
+
'Session worktrees are provided externally (`session.workspaces_external: true`) — this skill MUST NOT',
|
|
172
156
|
'create, switch to, unlock, remove, or prune a worktree. `ctxr session reap` refuses to run under this',
|
|
173
157
|
'configuration; reclaiming worktrees is the external process\'s responsibility, not this skill\'s.',
|
|
174
158
|
];
|
|
@@ -205,7 +189,7 @@ const ORGANIZE_AUDIT = {
|
|
|
205
189
|
description: 'Audit store health with ctxr lint (observations) and ctxr doctor (blocking invariants), retire by moving, and classify broken links before fixing them.',
|
|
206
190
|
body: () => skillTemplate('ctxr-organize-audit').split('\n'),
|
|
207
191
|
};
|
|
208
|
-
export const
|
|
192
|
+
export const SKILLS = [
|
|
209
193
|
INGEST_ORCHESTRATION,
|
|
210
194
|
PLACEMENT,
|
|
211
195
|
CONNECTION_FINDING,
|
|
@@ -220,8 +204,8 @@ export const PROCEDURES = [
|
|
|
220
204
|
ORGANIZE_AUDIT,
|
|
221
205
|
];
|
|
222
206
|
/** The owned skills, rendered against one store's configuration — what `syncShippedSkills` writes. */
|
|
223
|
-
export function
|
|
224
|
-
return
|
|
207
|
+
export function renderSkills(config) {
|
|
208
|
+
return SKILLS.map((seed) => ({
|
|
225
209
|
file: seed.file,
|
|
226
210
|
name: seed.name,
|
|
227
211
|
description: seed.description,
|
|
@@ -231,14 +215,14 @@ export function renderProcedures(config) {
|
|
|
231
215
|
/**
|
|
232
216
|
* entry-doc-generation spec: every skill actually on disk — the contexture-
|
|
233
217
|
* owned ones plus any operator-authored ones. This is what the AGENTS.md
|
|
234
|
-
* index and verify --portable consume; the static
|
|
218
|
+
* index and verify --portable consume; the static SKILLS const is only
|
|
235
219
|
* the canonical content syncShippedSkills writes.
|
|
236
220
|
*/
|
|
237
|
-
export function
|
|
238
|
-
return scanDocsDir(root, config.harness.
|
|
221
|
+
export function scanSkills(root, config) {
|
|
222
|
+
return scanDocsDir(root, config.harness.skills_path);
|
|
239
223
|
}
|
|
240
|
-
export function
|
|
241
|
-
return
|
|
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('/'));
|
|
242
226
|
}
|
|
243
227
|
/**
|
|
244
228
|
* Brings every contexture-owned skill copy to the installed package's
|
|
@@ -251,9 +235,9 @@ export function procedurePaths(config) {
|
|
|
251
235
|
*/
|
|
252
236
|
export async function syncShippedSkills(root, config) {
|
|
253
237
|
const changed = [];
|
|
254
|
-
for (const
|
|
238
|
+
for (const skill of renderSkills(config)) {
|
|
255
239
|
const relativePath = path
|
|
256
|
-
.join(config.harness.
|
|
240
|
+
.join(config.harness.skills_path, skill.file, SKILL_FILE_NAME)
|
|
257
241
|
.split(path.sep)
|
|
258
242
|
.join('/');
|
|
259
243
|
const absolutePath = path.join(root, relativePath);
|
|
@@ -264,14 +248,14 @@ export async function syncShippedSkills(root, config) {
|
|
|
264
248
|
catch {
|
|
265
249
|
existing = undefined;
|
|
266
250
|
}
|
|
267
|
-
if (existing !==
|
|
251
|
+
if (existing !== skill.content) {
|
|
268
252
|
await mkdir(path.dirname(absolutePath), { recursive: true });
|
|
269
|
-
await writeFileAtomic(absolutePath,
|
|
253
|
+
await writeFileAtomic(absolutePath, skill.content);
|
|
270
254
|
changed.push(relativePath);
|
|
271
255
|
}
|
|
272
256
|
}
|
|
273
|
-
const shippedSlugs = new Set(
|
|
274
|
-
const skillsDir = path.join(root, config.harness.
|
|
257
|
+
const shippedSlugs = new Set(SKILLS.map((p) => p.file));
|
|
258
|
+
const skillsDir = path.join(root, config.harness.skills_path);
|
|
275
259
|
let entries = [];
|
|
276
260
|
try {
|
|
277
261
|
entries = await readdir(skillsDir, { withFileTypes: true });
|
|
@@ -293,8 +277,8 @@ export async function syncShippedSkills(root, config) {
|
|
|
293
277
|
if (!content.includes(MANAGED_SKILL_HEADER))
|
|
294
278
|
continue; // operator-authored: never touched
|
|
295
279
|
await rm(path.join(skillsDir, entry.name), { recursive: true, force: true });
|
|
296
|
-
changed.push(path.join(config.harness.
|
|
280
|
+
changed.push(path.join(config.harness.skills_path, entry.name, SKILL_FILE_NAME).split(path.sep).join('/'));
|
|
297
281
|
}
|
|
298
282
|
return changed;
|
|
299
283
|
}
|
|
300
|
-
//# sourceMappingURL=
|
|
284
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;GAIG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAwCD,MAAM,CAAC,MAAM,oBAAoB,GAC/B,gIAAgI,CAAC;AAEnI;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,wEAAwE,CAAC;AACnG,MAAM,eAAe,GAAG,8DAA8D,CAAC;AAEvF,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;AACzI,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAmB;IAC/C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,aAAa,CAAC,IAAe,EAAE,MAAmB;IACzD,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,SAAS,IAAI,CAAC,IAAI,EAAE;QACpB,gBAAgB,IAAI,CAAC,WAAW,EAAE;QAClC,KAAK;QACL,EAAE;QACF,oBAAoB;QACpB,EAAE;QACF,KAAK,IAAI,CAAC,IAAI,EAAE;QAChB,EAAE;QACF,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;KACrB,CAAC;IACF,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,SAAS,CAAC,MAA6B;IAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAmB;IAC7C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,oBAAoB;YACpB,EAAE;YACF,0GAA0G;YAC1G,4GAA4G;YAC5G,wCAAwC;SACzC,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG;QACZ,oBAAoB;QACpB,EAAE;QACF,sGAAsG;QACtG,yGAAyG;QACzG,iFAAiF;KAClF,CAAC;IACF,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CACR,EAAE,EACF,0BAA0B,SAAS,CAAC,WAAW,CAAC,6DAA6D,EAC7G,0GAA0G,EAC1G,uGAAuG,EACvG,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CACR,EAAE,EACF,KAAK,SAAS,CAAC,OAAO,CAAC,qFAAqF,EAC5G,qFAAqF,CACtF,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,kGAAkG,CAAC,CAAC;IACnH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,SAAS,GAAc;IAC3B,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,qIAAqI;IAClJ,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CAC/H,CAAC;AAEF,MAAM,oBAAoB,GAAc;IACtC,IAAI,EAAE,2BAA2B;IACjC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,oLAAoL;IACjM,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC,UAAU,CAAC,yBAAyB,EAAE,4BAA4B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACvI,CAAC;AAEF,MAAM,kBAAkB,GAAc;IACpC,IAAI,EAAE,yBAAyB;IAC/B,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EAAE,qHAAqH;IAClI,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC,UAAU,CAAC,yBAAyB,EAAE,4BAA4B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACrI,CAAC;AAEF;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,SAA4B;IACxD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,2GAA2G;YAC3G,yEAAyE;SAC1E,CAAC;IACJ,CAAC;IACD,OAAO;QACL,sEAAsE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnH,yGAAyG;QACzG,0GAA0G;QAC1G,sCAAsC;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,mBAAmB,GAAc;IACrC,IAAI,EAAE,0BAA0B;IAChC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,qJAAqJ;IAClK,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC,OAAO,CAAC,4BAA4B,EAAE,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CAC3K,CAAC;AAEF,MAAM,MAAM,GAAc;IACxB,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,yIAAyI;IACtJ,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACrD,CAAC;AAEF,MAAM,OAAO,GAAc;IACzB,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,oQAAoQ;IACjR,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,GAAc;IACxB,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,qIAAqI;IAClJ,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,UAAU,CAAC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACvH,CAAC;AAEF,MAAM,IAAI,GAAc;IACtB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,oJAAoJ;IACjK,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACrH,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,MAAmB;IACzC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACvC,OAAO;YACL,uGAAuG;YACvG,uGAAuG;YACvG,mGAAmG;SACpG,CAAC;IACJ,CAAC;IACD,OAAO;QACL,6GAA6G;QAC7G,wGAAwG;KACzG,CAAC;AACJ,CAAC;AAED,MAAM,iBAAiB,GAAc;IACnC,IAAI,EAAE,wBAAwB;IAC9B,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,6JAA6J;IAC1K,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CACf,aAAa,CAAC,wBAAwB,CAAC;SACpC,UAAU,CAAC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;SAC3D,OAAO,CAAC,qBAAqB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACjE,KAAK,CAAC,IAAI,CAAC;CACjB,CAAC;AAEF,MAAM,eAAe,GAAc;IACjC,IAAI,EAAE,sBAAsB;IAC5B,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,gIAAgI;IAC7I,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CAC9D,CAAC;AAEF,MAAM,iBAAiB,GAAc;IACnC,IAAI,EAAE,wBAAwB;IAC9B,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,4JAA4J;IACzK,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC,UAAU,CAAC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CAClI,CAAC;AAEF,MAAM,cAAc,GAAc;IAChC,IAAI,EAAE,qBAAqB;IAC3B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,yJAAyJ;IACtK,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CAC7D,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAyB;IAC1C,oBAAoB;IACpB,SAAS;IACT,kBAAkB;IAClB,mBAAmB;IACnB,MAAM;IACN,OAAO;IACP,iBAAiB;IACjB,MAAM;IACN,IAAI;IACJ,eAAe;IACf,iBAAiB;IACjB,cAAc;CACf,CAAC;AAEF,sGAAsG;AACtG,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC;KACrC,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAAmB;IAC1D,OAAO,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAmB;IACvE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI;aACtB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC;aAC7D,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACnD,IAAI,QAA4B,CAAC;QACjC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,SAAS,CAAC;QACvB,CAAC;QACD,IAAI,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7D,MAAM,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,IAAI,OAAO,GAA+C,EAAE,CAAC;IAC7D,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACpE,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAAE,SAAS,CAAC,mCAAmC;QAC1F,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-gate.d.ts","sourceRoot":"","sources":["../../../src/core/write-lifecycle/path-gate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"path-gate.d.ts","sourceRoot":"","sources":["../../../src/core/write-lifecycle/path-gate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAoFD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAqBrH;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqBvH"}
|