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.
- 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 +16 -7
- 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 +7 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/rollup-stale.d.ts.map +1 -1
- package/dist/commands/rollup-stale.js +1 -1
- package/dist/commands/rollup-stale.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/session-reap.d.ts.map +1 -1
- package/dist/commands/session-reap.js +4 -0
- package/dist/commands/session-reap.js.map +1 -1
- package/dist/commands/verify.js +17 -17
- package/dist/commands/verify.js.map +1 -1
- package/dist/config/defaults.d.ts +4 -2
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +4 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +20 -4
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +53 -4
- package/dist/config/schema.js.map +1 -1
- package/dist/core/agents-doc.d.ts +13 -9
- package/dist/core/agents-doc.d.ts.map +1 -1
- package/dist/core/agents-doc.js +69 -107
- package/dist/core/agents-doc.js.map +1 -1
- package/dist/core/checks/integrity-checks.d.ts +14 -0
- package/dist/core/checks/integrity-checks.d.ts.map +1 -1
- package/dist/core/checks/integrity-checks.js +77 -1
- package/dist/core/checks/integrity-checks.js.map +1 -1
- package/dist/core/conventions.d.ts +1 -1
- package/dist/core/errors.d.ts +9 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +18 -1
- package/dist/core/errors.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/markers.d.ts +7 -0
- package/dist/core/markers.d.ts.map +1 -1
- package/dist/core/markers.js +9 -0
- package/dist/core/markers.js.map +1 -1
- package/dist/core/migrations/registry.d.ts.map +1 -1
- package/dist/core/migrations/registry.js +2 -1
- package/dist/core/migrations/registry.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/core/notes/list.js +9 -5
- package/dist/core/notes/list.js.map +1 -1
- package/dist/core/reconcile.js +2 -2
- package/dist/core/reconcile.js.map +1 -1
- package/dist/core/rollup.d.ts +25 -2
- package/dist/core/rollup.d.ts.map +1 -1
- package/dist/core/rollup.js +51 -5
- 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} +55 -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 +26 -0
- package/templates/agents/capture-and-ingest.md +17 -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/agents/store-conventions-empty.md +7 -0
- package/templates/agents/store-conventions.md +7 -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/templates/skills/ctxr-mission.md +36 -0
- package/templates/skills/ctxr-session-lifecycle.md +1 -2
- package/dist/core/procedures.d.ts.map +0 -1
- package/dist/core/procedures.js.map +0 -1
package/dist/core/notes/list.js
CHANGED
|
@@ -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
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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.
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAyBvC,wGAAwG;AACxG,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"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"}
|
package/dist/core/reconcile.js
CHANGED
|
@@ -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 './
|
|
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
|
|
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,
|
|
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"}
|
package/dist/core/rollup.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
|
|
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,
|
|
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"}
|
package/dist/core/rollup.js
CHANGED
|
@@ -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
|
-
/**
|
|
50
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
104
|
+
return [...byPath.values()].sort((a, b) => a.entity.localeCompare(b.entity));
|
|
59
105
|
}
|
|
60
106
|
//# sourceMappingURL=rollup.js.map
|
package/dist/core/rollup.js.map
CHANGED
|
@@ -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
|
|
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
|
|
@@ -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')
|
|
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
|
|
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
|
|
194
|
-
return
|
|
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
|
|
218
|
+
* index and verify --portable consume; the static SKILLS const is only
|
|
205
219
|
* the canonical content syncShippedSkills writes.
|
|
206
220
|
*/
|
|
207
|
-
export function
|
|
208
|
-
return scanDocsDir(root, config.harness.
|
|
221
|
+
export function scanSkills(root, config) {
|
|
222
|
+
return scanDocsDir(root, config.harness.skills_path);
|
|
209
223
|
}
|
|
210
|
-
export function
|
|
211
|
-
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('/'));
|
|
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
|
|
238
|
+
for (const skill of renderSkills(config)) {
|
|
225
239
|
const relativePath = path
|
|
226
|
-
.join(config.harness.
|
|
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 !==
|
|
251
|
+
if (existing !== skill.content) {
|
|
238
252
|
await mkdir(path.dirname(absolutePath), { recursive: true });
|
|
239
|
-
await writeFileAtomic(absolutePath,
|
|
253
|
+
await writeFileAtomic(absolutePath, skill.content);
|
|
240
254
|
changed.push(relativePath);
|
|
241
255
|
}
|
|
242
256
|
}
|
|
243
|
-
const shippedSlugs = new Set(
|
|
244
|
-
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);
|
|
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.
|
|
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=
|
|
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
|