ctxr-cli 0.1.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/LICENSE +201 -0
- package/README.md +25 -0
- package/dist/adapter.d.ts +18 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +4 -0
- package/dist/adapter.js.map +1 -0
- package/dist/adapters/builtin/index.d.ts +10 -0
- package/dist/adapters/builtin/index.d.ts.map +1 -0
- package/dist/adapters/builtin/index.js +11 -0
- package/dist/adapters/builtin/index.js.map +1 -0
- package/dist/adapters/forge/github.d.ts +9 -0
- package/dist/adapters/forge/github.d.ts.map +1 -0
- package/dist/adapters/forge/github.js +36 -0
- package/dist/adapters/forge/github.js.map +1 -0
- package/dist/adapters/forge/types.d.ts +23 -0
- package/dist/adapters/forge/types.d.ts.map +1 -0
- package/dist/adapters/forge/types.js +2 -0
- package/dist/adapters/forge/types.js.map +1 -0
- package/dist/adapters/harness/claude-code.d.ts +9 -0
- package/dist/adapters/harness/claude-code.d.ts.map +1 -0
- package/dist/adapters/harness/claude-code.js +42 -0
- package/dist/adapters/harness/claude-code.js.map +1 -0
- package/dist/adapters/identity/claude-code.d.ts +11 -0
- package/dist/adapters/identity/claude-code.d.ts.map +1 -0
- package/dist/adapters/identity/claude-code.js +18 -0
- package/dist/adapters/identity/claude-code.js.map +1 -0
- package/dist/adapters/registry.d.ts +16 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +29 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/types.d.ts +65 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +12 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +6 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/adapters-generate.d.ts +23 -0
- package/dist/commands/adapters-generate.d.ts.map +1 -0
- package/dist/commands/adapters-generate.js +59 -0
- package/dist/commands/adapters-generate.js.map +1 -0
- package/dist/commands/archive.d.ts +28 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +66 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/catalog-build.d.ts +7 -0
- package/dist/commands/catalog-build.d.ts.map +1 -0
- package/dist/commands/catalog-build.js +15 -0
- package/dist/commands/catalog-build.js.map +1 -0
- package/dist/commands/catalog-check.d.ts +22 -0
- package/dist/commands/catalog-check.d.ts.map +1 -0
- package/dist/commands/catalog-check.js +49 -0
- package/dist/commands/catalog-check.js.map +1 -0
- package/dist/commands/catalog-show.d.ts +13 -0
- package/dist/commands/catalog-show.d.ts.map +1 -0
- package/dist/commands/catalog-show.js +19 -0
- package/dist/commands/catalog-show.js.map +1 -0
- package/dist/commands/check.d.ts +22 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +43 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/doctor.d.ts +27 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +53 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/graph-build.d.ts +24 -0
- package/dist/commands/graph-build.d.ts.map +1 -0
- package/dist/commands/graph-build.js +36 -0
- package/dist/commands/graph-build.js.map +1 -0
- package/dist/commands/graph-query.d.ts +41 -0
- package/dist/commands/graph-query.d.ts.map +1 -0
- package/dist/commands/graph-query.js +63 -0
- package/dist/commands/graph-query.js.map +1 -0
- package/dist/commands/ingest.d.ts +28 -0
- package/dist/commands/ingest.d.ts.map +1 -0
- package/dist/commands/ingest.js +60 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/init.d.ts +28 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +203 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lint.d.ts +30 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +48 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/migrate.d.ts +30 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +56 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/note-resolve.d.ts +14 -0
- package/dist/commands/note-resolve.d.ts.map +1 -0
- package/dist/commands/note-resolve.js +24 -0
- package/dist/commands/note-resolve.js.map +1 -0
- package/dist/commands/rollup-gather.d.ts +21 -0
- package/dist/commands/rollup-gather.d.ts.map +1 -0
- package/dist/commands/rollup-gather.js +40 -0
- package/dist/commands/rollup-gather.js.map +1 -0
- package/dist/commands/rollup-write.d.ts +25 -0
- package/dist/commands/rollup-write.d.ts.map +1 -0
- package/dist/commands/rollup-write.js +43 -0
- package/dist/commands/rollup-write.js.map +1 -0
- package/dist/commands/session-abandon.d.ts +13 -0
- package/dist/commands/session-abandon.d.ts.map +1 -0
- package/dist/commands/session-abandon.js +22 -0
- package/dist/commands/session-abandon.js.map +1 -0
- package/dist/commands/session-list.d.ts +14 -0
- package/dist/commands/session-list.d.ts.map +1 -0
- package/dist/commands/session-list.js +19 -0
- package/dist/commands/session-list.js.map +1 -0
- package/dist/commands/session-reap.d.ts +22 -0
- package/dist/commands/session-reap.d.ts.map +1 -0
- package/dist/commands/session-reap.js +47 -0
- package/dist/commands/session-reap.js.map +1 -0
- package/dist/commands/session-start.d.ts +18 -0
- package/dist/commands/session-start.d.ts.map +1 -0
- package/dist/commands/session-start.js +36 -0
- package/dist/commands/session-start.js.map +1 -0
- package/dist/commands/session-submit.d.ts +27 -0
- package/dist/commands/session-submit.d.ts.map +1 -0
- package/dist/commands/session-submit.js +68 -0
- package/dist/commands/session-submit.js.map +1 -0
- package/dist/commands/source-check.d.ts +21 -0
- package/dist/commands/source-check.d.ts.map +1 -0
- package/dist/commands/source-check.js +54 -0
- package/dist/commands/source-check.js.map +1 -0
- package/dist/commands/source-hash.d.ts +14 -0
- package/dist/commands/source-hash.d.ts.map +1 -0
- package/dist/commands/source-hash.js +34 -0
- package/dist/commands/source-hash.js.map +1 -0
- package/dist/commands/update.d.ts +17 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +25 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +23 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +126 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/config/defaults.d.ts +69 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +71 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/load.d.ts +11 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +49 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/render.d.ts +9 -0
- package/dist/config/render.d.ts.map +1 -0
- package/dist/config/render.js +15 -0
- package/dist/config/render.js.map +1 -0
- package/dist/config/schema.d.ts +124 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +142 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/agents-doc.d.ts +80 -0
- package/dist/core/agents-doc.d.ts.map +1 -0
- package/dist/core/agents-doc.js +207 -0
- package/dist/core/agents-doc.js.map +1 -0
- package/dist/core/catalog/build.d.ts +49 -0
- package/dist/core/catalog/build.d.ts.map +1 -0
- package/dist/core/catalog/build.js +113 -0
- package/dist/core/catalog/build.js.map +1 -0
- package/dist/core/catalog/model.d.ts +33 -0
- package/dist/core/catalog/model.d.ts.map +1 -0
- package/dist/core/catalog/model.js +58 -0
- package/dist/core/catalog/model.js.map +1 -0
- package/dist/core/checks/catalog-checks.d.ts +4 -0
- package/dist/core/checks/catalog-checks.d.ts.map +1 -0
- package/dist/core/checks/catalog-checks.js +65 -0
- package/dist/core/checks/catalog-checks.js.map +1 -0
- package/dist/core/checks/identity-checks.d.ts +11 -0
- package/dist/core/checks/identity-checks.d.ts.map +1 -0
- package/dist/core/checks/identity-checks.js +39 -0
- package/dist/core/checks/identity-checks.js.map +1 -0
- package/dist/core/checks/integrity-checks.d.ts +23 -0
- package/dist/core/checks/integrity-checks.d.ts.map +1 -0
- package/dist/core/checks/integrity-checks.js +132 -0
- package/dist/core/checks/integrity-checks.js.map +1 -0
- package/dist/core/checks/manifest.d.ts +7 -0
- package/dist/core/checks/manifest.d.ts.map +1 -0
- package/dist/core/checks/manifest.js +20 -0
- package/dist/core/checks/manifest.js.map +1 -0
- package/dist/core/checks/organize-checks.d.ts +18 -0
- package/dist/core/checks/organize-checks.d.ts.map +1 -0
- package/dist/core/checks/organize-checks.js +97 -0
- package/dist/core/checks/organize-checks.js.map +1 -0
- package/dist/core/checks/registry.d.ts +24 -0
- package/dist/core/checks/registry.d.ts.map +1 -0
- package/dist/core/checks/registry.js +33 -0
- package/dist/core/checks/registry.js.map +1 -0
- package/dist/core/checks/types.d.ts +72 -0
- package/dist/core/checks/types.d.ts.map +1 -0
- package/dist/core/checks/types.js +4 -0
- package/dist/core/checks/types.js.map +1 -0
- package/dist/core/checks/write-lifecycle-checks.d.ts +24 -0
- package/dist/core/checks/write-lifecycle-checks.d.ts.map +1 -0
- package/dist/core/checks/write-lifecycle-checks.js +205 -0
- package/dist/core/checks/write-lifecycle-checks.js.map +1 -0
- package/dist/core/command.d.ts +23 -0
- package/dist/core/command.d.ts.map +1 -0
- package/dist/core/command.js +2 -0
- package/dist/core/command.js.map +1 -0
- package/dist/core/content/canonicalize.d.ts +14 -0
- package/dist/core/content/canonicalize.d.ts.map +1 -0
- package/dist/core/content/canonicalize.js +34 -0
- package/dist/core/content/canonicalize.js.map +1 -0
- package/dist/core/conventions.d.ts +21 -0
- package/dist/core/conventions.d.ts.map +1 -0
- package/dist/core/conventions.js +73 -0
- package/dist/core/conventions.js.map +1 -0
- package/dist/core/disclosure/model.d.ts +18 -0
- package/dist/core/disclosure/model.d.ts.map +1 -0
- package/dist/core/disclosure/model.js +45 -0
- package/dist/core/disclosure/model.js.map +1 -0
- package/dist/core/env.d.ts +40 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/env.js +24 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/envelope.d.ts +46 -0
- package/dist/core/envelope.d.ts.map +1 -0
- package/dist/core/envelope.js +21 -0
- package/dist/core/envelope.js.map +1 -0
- package/dist/core/errors.d.ts +96 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +267 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/exit-codes.d.ts +32 -0
- package/dist/core/exit-codes.d.ts.map +1 -0
- package/dist/core/exit-codes.js +31 -0
- package/dist/core/exit-codes.js.map +1 -0
- package/dist/core/fs/atomic.d.ts +10 -0
- package/dist/core/fs/atomic.d.ts.map +1 -0
- package/dist/core/fs/atomic.js +31 -0
- package/dist/core/fs/atomic.js.map +1 -0
- package/dist/core/fs/fenced-region.d.ts +47 -0
- package/dist/core/fs/fenced-region.d.ts.map +1 -0
- package/dist/core/fs/fenced-region.js +122 -0
- package/dist/core/fs/fenced-region.js.map +1 -0
- package/dist/core/git/exec.d.ts +28 -0
- package/dist/core/git/exec.d.ts.map +1 -0
- package/dist/core/git/exec.js +21 -0
- package/dist/core/git/exec.js.map +1 -0
- package/dist/core/git/repo.d.ts +63 -0
- package/dist/core/git/repo.d.ts.map +1 -0
- package/dist/core/git/repo.js +91 -0
- package/dist/core/git/repo.js.map +1 -0
- package/dist/core/git/staged.d.ts +10 -0
- package/dist/core/git/staged.d.ts.map +1 -0
- package/dist/core/git/staged.js +49 -0
- package/dist/core/git/staged.js.map +1 -0
- package/dist/core/git/worktree.d.ts +29 -0
- package/dist/core/git/worktree.d.ts.map +1 -0
- package/dist/core/git/worktree.js +61 -0
- package/dist/core/git/worktree.js.map +1 -0
- package/dist/core/graph/model.d.ts +43 -0
- package/dist/core/graph/model.d.ts.map +1 -0
- package/dist/core/graph/model.js +60 -0
- package/dist/core/graph/model.js.map +1 -0
- package/dist/core/graph/persist.d.ts +7 -0
- package/dist/core/graph/persist.d.ts.map +1 -0
- package/dist/core/graph/persist.js +23 -0
- package/dist/core/graph/persist.js.map +1 -0
- package/dist/core/graph/query.d.ts +16 -0
- package/dist/core/graph/query.d.ts.map +1 -0
- package/dist/core/graph/query.js +91 -0
- package/dist/core/graph/query.js.map +1 -0
- package/dist/core/graph/visibility-filter.d.ts +13 -0
- package/dist/core/graph/visibility-filter.d.ts.map +1 -0
- package/dist/core/graph/visibility-filter.js +26 -0
- package/dist/core/graph/visibility-filter.js.map +1 -0
- package/dist/core/hooks.d.ts +34 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +89 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/identity.d.ts +14 -0
- package/dist/core/identity.d.ts.map +1 -0
- package/dist/core/identity.js +36 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/ingest/identity.d.ts +15 -0
- package/dist/core/ingest/identity.d.ts.map +1 -0
- package/dist/core/ingest/identity.js +17 -0
- package/dist/core/ingest/identity.js.map +1 -0
- package/dist/core/ingest/model.d.ts +17 -0
- package/dist/core/ingest/model.d.ts.map +1 -0
- package/dist/core/ingest/model.js +24 -0
- package/dist/core/ingest/model.js.map +1 -0
- package/dist/core/json-config-merge.d.ts +13 -0
- package/dist/core/json-config-merge.d.ts.map +1 -0
- package/dist/core/json-config-merge.js +43 -0
- package/dist/core/json-config-merge.js.map +1 -0
- package/dist/core/markers.d.ts +17 -0
- package/dist/core/markers.d.ts.map +1 -0
- package/dist/core/markers.js +16 -0
- package/dist/core/markers.js.map +1 -0
- package/dist/core/migrations/registry.d.ts +6 -0
- package/dist/core/migrations/registry.d.ts.map +1 -0
- package/dist/core/migrations/registry.js +8 -0
- package/dist/core/migrations/registry.js.map +1 -0
- package/dist/core/migrations/rename-visibility-field.d.ts +3 -0
- package/dist/core/migrations/rename-visibility-field.d.ts.map +1 -0
- package/dist/core/migrations/rename-visibility-field.js +62 -0
- package/dist/core/migrations/rename-visibility-field.js.map +1 -0
- package/dist/core/migrations/types.d.ts +27 -0
- package/dist/core/migrations/types.d.ts.map +1 -0
- package/dist/core/migrations/types.js +2 -0
- package/dist/core/migrations/types.js.map +1 -0
- package/dist/core/notes/checks.d.ts +20 -0
- package/dist/core/notes/checks.d.ts.map +1 -0
- package/dist/core/notes/checks.js +58 -0
- package/dist/core/notes/checks.js.map +1 -0
- package/dist/core/notes/list.d.ts +26 -0
- package/dist/core/notes/list.d.ts.map +1 -0
- package/dist/core/notes/list.js +84 -0
- package/dist/core/notes/list.js.map +1 -0
- package/dist/core/notes/parse.d.ts +12 -0
- package/dist/core/notes/parse.d.ts.map +1 -0
- package/dist/core/notes/parse.js +36 -0
- package/dist/core/notes/parse.js.map +1 -0
- package/dist/core/notes/render.d.ts +7 -0
- package/dist/core/notes/render.d.ts.map +1 -0
- package/dist/core/notes/render.js +13 -0
- package/dist/core/notes/render.js.map +1 -0
- package/dist/core/notes/visibility.d.ts +26 -0
- package/dist/core/notes/visibility.d.ts.map +1 -0
- package/dist/core/notes/visibility.js +41 -0
- package/dist/core/notes/visibility.js.map +1 -0
- package/dist/core/procedures.d.ts +44 -0
- package/dist/core/procedures.d.ts.map +1 -0
- package/dist/core/procedures.js +154 -0
- package/dist/core/procedures.js.map +1 -0
- package/dist/core/queue.d.ts +16 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/queue.js +75 -0
- package/dist/core/queue.js.map +1 -0
- package/dist/core/reconcile.d.ts +18 -0
- package/dist/core/reconcile.d.ts.map +1 -0
- package/dist/core/reconcile.js +49 -0
- package/dist/core/reconcile.js.map +1 -0
- package/dist/core/records.d.ts +16 -0
- package/dist/core/records.d.ts.map +1 -0
- package/dist/core/records.js +36 -0
- package/dist/core/records.js.map +1 -0
- package/dist/core/reporter.d.ts +20 -0
- package/dist/core/reporter.d.ts.map +1 -0
- package/dist/core/reporter.js +25 -0
- package/dist/core/reporter.js.map +1 -0
- package/dist/core/root.d.ts +24 -0
- package/dist/core/root.d.ts.map +1 -0
- package/dist/core/root.js +51 -0
- package/dist/core/root.js.map +1 -0
- package/dist/core/security/secrets.d.ts +17 -0
- package/dist/core/security/secrets.d.ts.map +1 -0
- package/dist/core/security/secrets.js +21 -0
- package/dist/core/security/secrets.js.map +1 -0
- package/dist/core/session.d.ts +15 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +27 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/store.d.ts +15 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +19 -0
- package/dist/core/store.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/prompt/inquirer-prompter.d.ts +14 -0
- package/dist/prompt/inquirer-prompter.d.ts.map +1 -0
- package/dist/prompt/inquirer-prompter.js +27 -0
- package/dist/prompt/inquirer-prompter.js.map +1 -0
- package/dist/prompt/prompter.d.ts +24 -0
- package/dist/prompt/prompter.d.ts.map +1 -0
- package/dist/prompt/prompter.js +2 -0
- package/dist/prompt/prompter.js.map +1 -0
- package/dist/run.d.ts +16 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +464 -0
- package/dist/run.js.map +1 -0
- package/dist/taxonomy/profiles.d.ts +31 -0
- package/dist/taxonomy/profiles.d.ts.map +1 -0
- package/dist/taxonomy/profiles.js +45 -0
- package/dist/taxonomy/profiles.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +56 -0
- package/templates/.gitkeep +0 -0
- package/templates/hooks/pre-commit.sh +21 -0
- package/templates/hooks/pre-push.sh +24 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, rm } from 'node:fs/promises';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { writeFileAtomic } from './fs/atomic.js';
|
|
5
|
+
/**
|
|
6
|
+
* write-lifecycle spec: append-via-queue for shared append-only files. Two
|
|
7
|
+
* sessions on separate branches genuinely cannot both append to the same
|
|
8
|
+
* file (e.g. a chronological log) without conflicting when merged — so each
|
|
9
|
+
* queues a uniquely named, self-contained intent file instead, and a
|
|
10
|
+
* reconciler applies them in order (oldest first, by the epoch-ms prefix).
|
|
11
|
+
*/
|
|
12
|
+
const QUEUE_DIR_NAME = '.queue';
|
|
13
|
+
const TARGET_HEADER_PREFIX = 'target: ';
|
|
14
|
+
function isValidTarget(relativePath) {
|
|
15
|
+
return !path.isAbsolute(relativePath) && !relativePath.split('/').includes('..') && relativePath.endsWith('.md');
|
|
16
|
+
}
|
|
17
|
+
export async function queueAppend(storeRoot, targetRelativePath, content) {
|
|
18
|
+
if (!isValidTarget(targetRelativePath)) {
|
|
19
|
+
throw new Error(`Invalid queue target path: "${targetRelativePath}" (must be a relative .md path with no "..").`);
|
|
20
|
+
}
|
|
21
|
+
const queueDir = path.join(storeRoot, QUEUE_DIR_NAME);
|
|
22
|
+
await mkdir(queueDir, { recursive: true });
|
|
23
|
+
const fileName = `${Date.now()}__${randomBytes(4).toString('hex')}.append`;
|
|
24
|
+
const filePath = path.join(queueDir, fileName);
|
|
25
|
+
await writeFileAtomic(filePath, `${TARGET_HEADER_PREFIX}${targetRelativePath}\n${content}`);
|
|
26
|
+
return filePath;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Applies every pending queue file to its target, oldest first, deleting
|
|
30
|
+
* each as it's applied. A malformed entry (missing header, path escaping
|
|
31
|
+
* the store, or a non-.md target) throws rather than being silently
|
|
32
|
+
* skipped or guessed at.
|
|
33
|
+
*/
|
|
34
|
+
export async function reconcileQueue(storeRoot) {
|
|
35
|
+
const queueDir = path.join(storeRoot, QUEUE_DIR_NAME);
|
|
36
|
+
let entries;
|
|
37
|
+
try {
|
|
38
|
+
entries = await readdir(queueDir);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err.code === 'ENOENT')
|
|
42
|
+
return { applied: [] };
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
const appendFiles = entries.filter((e) => e.endsWith('.append')).sort();
|
|
46
|
+
const applied = [];
|
|
47
|
+
for (const fileName of appendFiles) {
|
|
48
|
+
const filePath = path.join(queueDir, fileName);
|
|
49
|
+
const raw = await readFile(filePath, 'utf8');
|
|
50
|
+
const newlineIndex = raw.indexOf('\n');
|
|
51
|
+
if (newlineIndex === -1 || !raw.startsWith(TARGET_HEADER_PREFIX)) {
|
|
52
|
+
throw new Error(`Malformed queue file "${fileName}": missing "target: <path>" header.`);
|
|
53
|
+
}
|
|
54
|
+
const targetRelativePath = raw.slice(TARGET_HEADER_PREFIX.length, newlineIndex).trim();
|
|
55
|
+
if (!isValidTarget(targetRelativePath)) {
|
|
56
|
+
throw new Error(`Malformed queue file "${fileName}": invalid target "${targetRelativePath}".`);
|
|
57
|
+
}
|
|
58
|
+
const body = raw.slice(newlineIndex + 1);
|
|
59
|
+
const targetPath = path.join(storeRoot, targetRelativePath);
|
|
60
|
+
let existing = '';
|
|
61
|
+
try {
|
|
62
|
+
existing = await readFile(targetPath, 'utf8');
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (err.code !== 'ENOENT')
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
const separator = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
|
|
69
|
+
await writeFileAtomic(targetPath, `${existing}${separator}${body}`);
|
|
70
|
+
await rm(filePath);
|
|
71
|
+
applied.push({ file: fileName, target: targetRelativePath });
|
|
72
|
+
}
|
|
73
|
+
return { applied };
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/core/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StoreConfig } from '../config/schema.js';
|
|
2
|
+
import type { RunEnv } from './env.js';
|
|
3
|
+
export declare const WORKTREES_GITIGNORE_FENCE: import("./markers.js").Fence;
|
|
4
|
+
export interface ReconcileResult {
|
|
5
|
+
/** Store-relative paths written this run (an up-to-date store yields none). */
|
|
6
|
+
changed: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Brings every contexture-OWNED file in a store to the installed package's
|
|
10
|
+
* version: the managed .gitignore blocks, every generated AGENTS.md
|
|
11
|
+
* section, the contexture-owned skill copies, and the git hooks. Operator
|
|
12
|
+
* content is never rewritten — identity files are created only when
|
|
13
|
+
* missing. Shared by `ctxr init` (reconciling an existing store) and
|
|
14
|
+
* `ctxr update` (after upgrading contexture). Byte-stable: a second run
|
|
15
|
+
* with nothing changed writes nothing.
|
|
16
|
+
*/
|
|
17
|
+
export declare function reconcileStore(env: RunEnv, root: string, config: StoreConfig): Promise<ReconcileResult>;
|
|
18
|
+
//# sourceMappingURL=reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAevC,eAAO,MAAM,yBAAyB,8BAA4B,CAAC;AAEnE,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAoC7G"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { buildAgentsCanonicalSection, buildAgentsCaptureSection, buildAgentsConventionsSection, buildAgentsIdentitySection, buildAgentsLegRoutingSection, buildAgentsPlacementSection, } from './agents-doc.js';
|
|
3
|
+
import { upsertFencedRegionInFile } from './fs/fenced-region.js';
|
|
4
|
+
import { configureHooksPath, installHooks } from './hooks.js';
|
|
5
|
+
import { ensureIdentityFiles } from './identity.js';
|
|
6
|
+
import { commentFence, DERIVED_GITIGNORE_FENCE } from './markers.js';
|
|
7
|
+
import { syncShippedSkills } from './procedures.js';
|
|
8
|
+
export const WORKTREES_GITIGNORE_FENCE = commentFence('worktrees');
|
|
9
|
+
/**
|
|
10
|
+
* Brings every contexture-OWNED file in a store to the installed package's
|
|
11
|
+
* version: the managed .gitignore blocks, every generated AGENTS.md
|
|
12
|
+
* section, the contexture-owned skill copies, and the git hooks. Operator
|
|
13
|
+
* content is never rewritten — identity files are created only when
|
|
14
|
+
* missing. Shared by `ctxr init` (reconciling an existing store) and
|
|
15
|
+
* `ctxr update` (after upgrading contexture). Byte-stable: a second run
|
|
16
|
+
* with nothing changed writes nothing.
|
|
17
|
+
*/
|
|
18
|
+
export async function reconcileStore(env, root, config) {
|
|
19
|
+
const changed = [];
|
|
20
|
+
const note = (relativePath, didChange) => {
|
|
21
|
+
if (didChange)
|
|
22
|
+
changed.push(relativePath);
|
|
23
|
+
};
|
|
24
|
+
const gitignorePath = path.join(root, '.gitignore');
|
|
25
|
+
note('.gitignore', (await upsertFencedRegionInFile(gitignorePath, DERIVED_GITIGNORE_FENCE, config.derived.paths)).changed);
|
|
26
|
+
note('.gitignore', (await upsertFencedRegionInFile(gitignorePath, WORKTREES_GITIGNORE_FENCE, [config.session.worktrees_path])).changed);
|
|
27
|
+
// Files the generated sections index (skills, identity) must be current
|
|
28
|
+
// BEFORE the sections are rendered — the procedure index is a disk scan.
|
|
29
|
+
changed.push(...(await ensureIdentityFiles(root, config)));
|
|
30
|
+
changed.push(...(await syncShippedSkills(root, config)));
|
|
31
|
+
let agentsChanged = false;
|
|
32
|
+
for (const build of [
|
|
33
|
+
buildAgentsLegRoutingSection,
|
|
34
|
+
buildAgentsCaptureSection,
|
|
35
|
+
buildAgentsPlacementSection,
|
|
36
|
+
buildAgentsCanonicalSection,
|
|
37
|
+
buildAgentsIdentitySection,
|
|
38
|
+
buildAgentsConventionsSection,
|
|
39
|
+
]) {
|
|
40
|
+
if ((await build(root, config)).changed)
|
|
41
|
+
agentsChanged = true;
|
|
42
|
+
}
|
|
43
|
+
note('AGENTS.md', agentsChanged);
|
|
44
|
+
const { changed: hookFiles } = await installHooks(root, config.git.default_branch);
|
|
45
|
+
changed.push(...hookFiles);
|
|
46
|
+
await configureHooksPath(env.git, root);
|
|
47
|
+
return { changed: [...new Set(changed)] };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,CAAC,MAAM,yBAAyB,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAOnE;;;;;;;;GAQG;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,wEAAwE;IACxE,yEAAyE;IACzE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3D,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,0BAA0B;QAC1B,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,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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Store } from './store.js';
|
|
2
|
+
/**
|
|
3
|
+
* context-retrieval spec: a stable per-note record `{id, path, visibility,
|
|
4
|
+
* gloss, hash}`, usable as input to a future (v2) search capability without
|
|
5
|
+
* re-deriving note identity. Shared by `graph build --emit-records` and
|
|
6
|
+
* `catalog build --emit-records` so both commands agree on the shape.
|
|
7
|
+
*/
|
|
8
|
+
export interface PerNoteRecord {
|
|
9
|
+
id: string;
|
|
10
|
+
path: string;
|
|
11
|
+
visibility: string;
|
|
12
|
+
gloss: string;
|
|
13
|
+
hash: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildPerNoteRecords(store: Store): Promise<PerNoteRecord[]>;
|
|
16
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/core/records.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAWD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAoBhF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { catalogSectionsFor, parseCatalogGlosses, sectionFileName } from './catalog/model.js';
|
|
4
|
+
import { contentHashOfBody } from './content/canonicalize.js';
|
|
5
|
+
import { listNotes } from './notes/list.js';
|
|
6
|
+
import { resolveVisibility } from './notes/visibility.js';
|
|
7
|
+
async function readIfExists(filePath) {
|
|
8
|
+
try {
|
|
9
|
+
return await readFile(filePath, 'utf8');
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
if (err.code === 'ENOENT')
|
|
13
|
+
return '';
|
|
14
|
+
throw err;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export async function buildPerNoteRecords(store) {
|
|
18
|
+
const notes = await listNotes(store.root, store.config);
|
|
19
|
+
const sections = catalogSectionsFor(store.config);
|
|
20
|
+
const catalogDir = path.join(store.root, store.config.catalog.path);
|
|
21
|
+
const glosses = new Map();
|
|
22
|
+
for (const section of sections) {
|
|
23
|
+
const body = await readIfExists(path.join(catalogDir, sectionFileName(section)));
|
|
24
|
+
for (const [notePath, entry] of parseCatalogGlosses(body)) {
|
|
25
|
+
glosses.set(notePath, entry.gloss);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return notes.map((note) => ({
|
|
29
|
+
id: note.path,
|
|
30
|
+
path: note.path,
|
|
31
|
+
visibility: resolveVisibility(store.config, note).value,
|
|
32
|
+
gloss: glosses.get(note.path) ?? '',
|
|
33
|
+
hash: contentHashOfBody(note.body),
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../../src/core/records.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAiB1D,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAChE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAY;IACpD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjF,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,EAAE,EAAE,IAAI,CAAC,IAAI;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK;QACvD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QACnC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;KACnC,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Io } from './env.js';
|
|
2
|
+
import type { Envelope } from './envelope.js';
|
|
3
|
+
/**
|
|
4
|
+
* The only object in the codebase permitted to write to stdout. This is what
|
|
5
|
+
* makes the "JSON output is parseable in isolation" scenario mechanical
|
|
6
|
+
* rather than a convention every command has to remember: a command that
|
|
7
|
+
* imports Reporter has no other way to reach stdout, and a guard test
|
|
8
|
+
* (single-source-literals.test.ts) fails on any direct `process.stdout` use
|
|
9
|
+
* under src/commands/**.
|
|
10
|
+
*/
|
|
11
|
+
export interface Reporter {
|
|
12
|
+
/** Emits the command's result exactly once: JSON in --json mode, a human summary otherwise. */
|
|
13
|
+
emitResult<T>(envelope: Envelope<T>, humanSummary: string): void;
|
|
14
|
+
/** Diagnostic narration — always stderr, safe to call in either mode. */
|
|
15
|
+
info(message: string): void;
|
|
16
|
+
warn(message: string): void;
|
|
17
|
+
error(message: string): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function createReporter(io: Io, jsonMode: boolean): Reporter;
|
|
20
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/core/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,+FAA+F;IAC/F,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACjE,yEAAyE;IACzE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAyBlE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function createReporter(io, jsonMode) {
|
|
2
|
+
let emitted = false;
|
|
3
|
+
function assertNotEmitted() {
|
|
4
|
+
if (emitted) {
|
|
5
|
+
throw new Error('Reporter.emitResult was called more than once in a single invocation.');
|
|
6
|
+
}
|
|
7
|
+
emitted = true;
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
emitResult(envelope, humanSummary) {
|
|
11
|
+
assertNotEmitted();
|
|
12
|
+
io.stdout.write(`${jsonMode ? JSON.stringify(envelope) : humanSummary}\n`);
|
|
13
|
+
},
|
|
14
|
+
info(message) {
|
|
15
|
+
io.stderr.write(`${message}\n`);
|
|
16
|
+
},
|
|
17
|
+
warn(message) {
|
|
18
|
+
io.stderr.write(`warning: ${message}\n`);
|
|
19
|
+
},
|
|
20
|
+
error(message) {
|
|
21
|
+
io.stderr.write(`error: ${message}\n`);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/core/reporter.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,cAAc,CAAC,EAAM,EAAE,QAAiB;IACtD,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,SAAS,gBAAgB;QACvB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO;QACL,UAAU,CAAC,QAAQ,EAAE,YAAY;YAC/B,gBAAgB,EAAE,CAAC;YACnB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,CAAC,OAAO;YACV,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,OAAO;YACV,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,CAAC,OAAO;YACX,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { RunEnv } from './env.js';
|
|
2
|
+
/** The one config filename every root-resolution function looks for. */
|
|
3
|
+
export declare const CONFIG_FILE_NAME = "contexture.yaml";
|
|
4
|
+
export interface RootFlags {
|
|
5
|
+
root?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Root resolution for every command except `init` (harness-portability spec):
|
|
9
|
+
* an explicit --root argument beats an inherited CONTEXTURE_ROOT env var,
|
|
10
|
+
* which beats walking up from cwd looking for contexture.yaml. If none
|
|
11
|
+
* resolves, throws NoStoreRootError rather than guessing a fallback.
|
|
12
|
+
*
|
|
13
|
+
* Exactly one env var (CONTEXTURE_ROOT) and one flag (--root) are recognized
|
|
14
|
+
* — no aliases are checked here, ever, by construction.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveExistingRoot(env: RunEnv, flags: RootFlags): string;
|
|
17
|
+
/**
|
|
18
|
+
* Root resolution for `init` only: --root -> CONTEXTURE_ROOT -> cwd.
|
|
19
|
+
* Deliberately never walks up — unlike every other command, init CREATES a
|
|
20
|
+
* store rather than finding one, and walking up would let `ctxr init`
|
|
21
|
+
* run in a subdirectory silently re-target and reinitialize a parent store.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveRootForInit(env: RunEnv, flags: RootFlags): string;
|
|
24
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/core/root.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAoBzE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CASxE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { NoStoreRootError } from './errors.js';
|
|
4
|
+
/** The one config filename every root-resolution function looks for. */
|
|
5
|
+
export const CONFIG_FILE_NAME = 'contexture.yaml';
|
|
6
|
+
/**
|
|
7
|
+
* Root resolution for every command except `init` (harness-portability spec):
|
|
8
|
+
* an explicit --root argument beats an inherited CONTEXTURE_ROOT env var,
|
|
9
|
+
* which beats walking up from cwd looking for contexture.yaml. If none
|
|
10
|
+
* resolves, throws NoStoreRootError rather than guessing a fallback.
|
|
11
|
+
*
|
|
12
|
+
* Exactly one env var (CONTEXTURE_ROOT) and one flag (--root) are recognized
|
|
13
|
+
* — no aliases are checked here, ever, by construction.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveExistingRoot(env, flags) {
|
|
16
|
+
if (flags.root) {
|
|
17
|
+
return path.resolve(env.cwd, flags.root);
|
|
18
|
+
}
|
|
19
|
+
const fromEnv = env.env.CONTEXTURE_ROOT;
|
|
20
|
+
if (fromEnv) {
|
|
21
|
+
return path.resolve(env.cwd, fromEnv);
|
|
22
|
+
}
|
|
23
|
+
let dir = path.resolve(env.cwd);
|
|
24
|
+
for (;;) {
|
|
25
|
+
if (existsSync(path.join(dir, CONFIG_FILE_NAME))) {
|
|
26
|
+
return dir;
|
|
27
|
+
}
|
|
28
|
+
const parent = path.dirname(dir);
|
|
29
|
+
if (parent === dir)
|
|
30
|
+
break;
|
|
31
|
+
dir = parent;
|
|
32
|
+
}
|
|
33
|
+
throw new NoStoreRootError({ flag: Boolean(flags.root), env: Boolean(fromEnv), cwd: env.cwd });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Root resolution for `init` only: --root -> CONTEXTURE_ROOT -> cwd.
|
|
37
|
+
* Deliberately never walks up — unlike every other command, init CREATES a
|
|
38
|
+
* store rather than finding one, and walking up would let `ctxr init`
|
|
39
|
+
* run in a subdirectory silently re-target and reinitialize a parent store.
|
|
40
|
+
*/
|
|
41
|
+
export function resolveRootForInit(env, flags) {
|
|
42
|
+
if (flags.root) {
|
|
43
|
+
return path.resolve(env.cwd, flags.root);
|
|
44
|
+
}
|
|
45
|
+
const fromEnv = env.env.CONTEXTURE_ROOT;
|
|
46
|
+
if (fromEnv) {
|
|
47
|
+
return path.resolve(env.cwd, fromEnv);
|
|
48
|
+
}
|
|
49
|
+
return path.resolve(env.cwd);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/core/root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAMlD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,KAAgB;IAC/D,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IAED,MAAM,IAAI,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;AACjG,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,KAAgB;IAC9D,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* write-lifecycle spec: pre-commit runs "a secret-pattern scan." A modest,
|
|
3
|
+
* documented set of high-confidence patterns — this is a safety net behind
|
|
4
|
+
* PR review, not a substitute for it (design.md: review is the layer that
|
|
5
|
+
* doesn't depend on hook cooperation).
|
|
6
|
+
*/
|
|
7
|
+
export interface SecretPattern {
|
|
8
|
+
id: string;
|
|
9
|
+
regex: RegExp;
|
|
10
|
+
}
|
|
11
|
+
export declare const SECRET_PATTERNS: readonly SecretPattern[];
|
|
12
|
+
export interface SecretMatch {
|
|
13
|
+
patternId: string;
|
|
14
|
+
line: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function scanForSecrets(content: string): SecretMatch[];
|
|
17
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../src/core/security/secrets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAMnD,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAY7D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const SECRET_PATTERNS = [
|
|
2
|
+
{ id: 'aws_access_key_id', regex: /AKIA[0-9A-Z]{16}/g },
|
|
3
|
+
{ id: 'private_key_block', regex: /-----BEGIN (RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/g },
|
|
4
|
+
{ id: 'github_token', regex: /gh[pousr]_[A-Za-z0-9]{36,}/g },
|
|
5
|
+
{ id: 'slack_token', regex: /xox[baprs]-[A-Za-z0-9-]{10,}/g },
|
|
6
|
+
{ id: 'generic_api_key', regex: /sk-[A-Za-z0-9]{20,}/g },
|
|
7
|
+
];
|
|
8
|
+
export function scanForSecrets(content) {
|
|
9
|
+
const matches = [];
|
|
10
|
+
const lines = content.split('\n');
|
|
11
|
+
lines.forEach((line, index) => {
|
|
12
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
13
|
+
pattern.regex.lastIndex = 0;
|
|
14
|
+
if (pattern.regex.test(line)) {
|
|
15
|
+
matches.push({ patternId: pattern.id, line: index + 1 });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return matches;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/core/security/secrets.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,EAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACvD,EAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,uDAAuD,EAAE;IAC3F,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,6BAA6B,EAAE;IAC5D,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,+BAA+B,EAAE;IAC7D,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,sBAAsB,EAAE;CACzD,CAAC;AAOF,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;YAC5B,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StoreConfig } from '../config/schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* write-lifecycle spec: session branch names are prefixed (configurable —
|
|
4
|
+
* default "session/") and unique. Sortable by creation time, since that's
|
|
5
|
+
* useful for reap/list ordering without needing to consult git history.
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateSessionBranchName(config: StoreConfig, now?: Date): string;
|
|
8
|
+
export declare function isSessionBranch(config: StoreConfig, branch: string): boolean;
|
|
9
|
+
/** A branch name may contain "/"; a directory name may not treat that as a separator. */
|
|
10
|
+
export declare function worktreeDirNameFor(branch: string): string;
|
|
11
|
+
export declare function worktreePathFor(store: {
|
|
12
|
+
root: string;
|
|
13
|
+
config: StoreConfig;
|
|
14
|
+
}, branch: string): string;
|
|
15
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,CAQ7F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5E;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* write-lifecycle spec: session branch names are prefixed (configurable —
|
|
5
|
+
* default "session/") and unique. Sortable by creation time, since that's
|
|
6
|
+
* useful for reap/list ordering without needing to consult git history.
|
|
7
|
+
*/
|
|
8
|
+
export function generateSessionBranchName(config, now = new Date()) {
|
|
9
|
+
const stamp = now
|
|
10
|
+
.toISOString()
|
|
11
|
+
.replace(/[-:]/g, '')
|
|
12
|
+
.replace(/\.\d+Z$/, '')
|
|
13
|
+
.replace('T', '-');
|
|
14
|
+
const suffix = randomBytes(3).toString('hex');
|
|
15
|
+
return `${config.session.branch_prefix}${stamp}-${suffix}`;
|
|
16
|
+
}
|
|
17
|
+
export function isSessionBranch(config, branch) {
|
|
18
|
+
return branch.startsWith(config.session.branch_prefix);
|
|
19
|
+
}
|
|
20
|
+
/** A branch name may contain "/"; a directory name may not treat that as a separator. */
|
|
21
|
+
export function worktreeDirNameFor(branch) {
|
|
22
|
+
return branch.replace(/\//g, '-');
|
|
23
|
+
}
|
|
24
|
+
export function worktreePathFor(store, branch) {
|
|
25
|
+
return path.join(store.root, store.config.session.worktrees_path, worktreeDirNameFor(branch));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAmB,EAAE,GAAG,GAAS,IAAI,IAAI,EAAE;IACnF,MAAM,KAAK,GAAG,GAAG;SACd,WAAW,EAAE;SACb,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;SACtB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAmB,EAAE,MAAc;IACjE,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;AACzD,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAA4C,EAAE,MAAc;IAC1F,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;AAChG,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StoreConfig } from '../config/schema.js';
|
|
2
|
+
import type { RunEnv } from './env.js';
|
|
3
|
+
import { type RootFlags } from './root.js';
|
|
4
|
+
export interface Store {
|
|
5
|
+
root: string;
|
|
6
|
+
config: StoreConfig;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The choke point every non-`init` command goes through: root resolution,
|
|
10
|
+
* then the git-repository check (context-store spec), then config load
|
|
11
|
+
* (which itself gates schema_version — store-lifecycle spec). Done once,
|
|
12
|
+
* structurally, here — so no command can skip either check by omission.
|
|
13
|
+
*/
|
|
14
|
+
export declare function openStore(env: RunEnv, flags: RootFlags): Promise<Store>;
|
|
15
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAO7E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readConfig } from '../config/load.js';
|
|
2
|
+
import { NotAGitRepositoryError } from './errors.js';
|
|
3
|
+
import { isInsideGitRepo } from './git/repo.js';
|
|
4
|
+
import { resolveExistingRoot } from './root.js';
|
|
5
|
+
/**
|
|
6
|
+
* The choke point every non-`init` command goes through: root resolution,
|
|
7
|
+
* then the git-repository check (context-store spec), then config load
|
|
8
|
+
* (which itself gates schema_version — store-lifecycle spec). Done once,
|
|
9
|
+
* structurally, here — so no command can skip either check by omission.
|
|
10
|
+
*/
|
|
11
|
+
export async function openStore(env, flags) {
|
|
12
|
+
const root = resolveExistingRoot(env, flags);
|
|
13
|
+
if (!(await isInsideGitRepo(env.git, root))) {
|
|
14
|
+
throw new NotAGitRepositoryError(root);
|
|
15
|
+
}
|
|
16
|
+
const config = await readConfig(root);
|
|
17
|
+
return { root, config };
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAkB,MAAM,WAAW,CAAC;AAOhE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,KAAgB;IAC3D,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** contexture's library public surface. */
|
|
2
|
+
export type { Io, RunEnv } from './core/env.js';
|
|
3
|
+
export { realEnv } from './core/env.js';
|
|
4
|
+
export type { Envelope, Finding, Status } from './core/envelope.js';
|
|
5
|
+
export { ExitCode } from './core/exit-codes.js';
|
|
6
|
+
export type { StoreConfig, TaxonomyLayerConfig } from './config/schema.js';
|
|
7
|
+
export { StoreConfigSchema, SUPPORTED_SCHEMA_VERSION } from './config/schema.js';
|
|
8
|
+
export type { Store } from './core/store.js';
|
|
9
|
+
export { openStore } from './core/store.js';
|
|
10
|
+
export type { TaxonomyLayer, TaxonomyProfile } from './taxonomy/profiles.js';
|
|
11
|
+
export { DEFAULT_PROFILE_ID, SHIPPED_PROFILES, defaultProfile, profileById } from './taxonomy/profiles.js';
|
|
12
|
+
export { run } from './run.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACjF,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC3G,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { realEnv } from './core/env.js';
|
|
2
|
+
export { ExitCode } from './core/exit-codes.js';
|
|
3
|
+
export { StoreConfigSchema, SUPPORTED_SCHEMA_VERSION } from './config/schema.js';
|
|
4
|
+
export { openStore } from './core/store.js';
|
|
5
|
+
export { DEFAULT_PROFILE_ID, SHIPPED_PROFILES, defaultProfile, profileById } from './taxonomy/profiles.js';
|
|
6
|
+
export { run } from './run.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC3G,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Prompter } from './prompter.js';
|
|
2
|
+
/**
|
|
3
|
+
* The real prompter. Renders entirely to stderr via @inquirer/prompts'
|
|
4
|
+
* `output` context option — never stdout, so no invocation mode can let
|
|
5
|
+
* prompt text corrupt a --json payload.
|
|
6
|
+
*
|
|
7
|
+
* Each choice's name embeds its description directly (rather than relying on
|
|
8
|
+
* @inquirer's "description of the currently-highlighted item" feature),
|
|
9
|
+
* because store-lifecycle's spec requires every shipped profile's name AND
|
|
10
|
+
* description to be presented together, not revealed one at a time as the
|
|
11
|
+
* operator moves the cursor.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createInquirerPrompter(): Prompter;
|
|
14
|
+
//# sourceMappingURL=inquirer-prompter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inquirer-prompter.d.ts","sourceRoot":"","sources":["../../src/prompt/inquirer-prompter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,IAAI,QAAQ,CAgBjD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { select } from '@inquirer/prompts';
|
|
2
|
+
/**
|
|
3
|
+
* The real prompter. Renders entirely to stderr via @inquirer/prompts'
|
|
4
|
+
* `output` context option — never stdout, so no invocation mode can let
|
|
5
|
+
* prompt text corrupt a --json payload.
|
|
6
|
+
*
|
|
7
|
+
* Each choice's name embeds its description directly (rather than relying on
|
|
8
|
+
* @inquirer's "description of the currently-highlighted item" feature),
|
|
9
|
+
* because store-lifecycle's spec requires every shipped profile's name AND
|
|
10
|
+
* description to be presented together, not revealed one at a time as the
|
|
11
|
+
* operator moves the cursor.
|
|
12
|
+
*/
|
|
13
|
+
export function createInquirerPrompter() {
|
|
14
|
+
return {
|
|
15
|
+
async selectProfile(input) {
|
|
16
|
+
return select({
|
|
17
|
+
message: input.message,
|
|
18
|
+
default: input.defaultId,
|
|
19
|
+
choices: input.choices.map((c) => ({
|
|
20
|
+
name: `${c.name} — ${c.description}`,
|
|
21
|
+
value: c.id,
|
|
22
|
+
})),
|
|
23
|
+
}, { output: process.stderr });
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=inquirer-prompter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inquirer-prompter.js","sourceRoot":"","sources":["../../src/prompt/inquirer-prompter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,KAAK;YACvB,OAAO,MAAM,CACX;gBACE,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,KAAK,CAAC,SAAS;gBACxB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACjC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE;oBACpC,KAAK,EAAE,CAAC,CAAC,EAAE;iBACZ,CAAC,CAAC;aACJ,EACD,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAC3B,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interactive-selection seam. No command or core module imports
|
|
3
|
+
* @inquirer/prompts directly — they depend on this interface, so a fake
|
|
4
|
+
* prompter can prove deterministic facts (which choices were offered, in
|
|
5
|
+
* what order, with what descriptions) without a real terminal.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProfileChoice {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Prompter {
|
|
13
|
+
/**
|
|
14
|
+
* Presents `choices` and returns the selected id. Implementations MUST
|
|
15
|
+
* render entirely to stderr — never stdout, so no invocation mode can let
|
|
16
|
+
* prompt text corrupt a --json payload.
|
|
17
|
+
*/
|
|
18
|
+
selectProfile(input: {
|
|
19
|
+
message: string;
|
|
20
|
+
choices: readonly ProfileChoice[];
|
|
21
|
+
defaultId: string;
|
|
22
|
+
}): Promise<string>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=prompter.d.ts.map
|