ctxr-cli 0.7.0 → 0.9.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/README.md +303 -22
- package/dist/adapters/types.d.ts +0 -5
- 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 +2 -3
- package/dist/commands/adapters-generate.js.map +1 -1
- package/dist/commands/context-gather.d.ts +22 -0
- package/dist/commands/context-gather.d.ts.map +1 -0
- package/dist/commands/context-gather.js +36 -0
- package/dist/commands/context-gather.js.map +1 -0
- package/dist/commands/graph-query.d.ts.map +1 -1
- package/dist/commands/graph-query.js +6 -8
- package/dist/commands/graph-query.js.map +1 -1
- package/dist/commands/ingest.d.ts +22 -9
- package/dist/commands/ingest.d.ts.map +1 -1
- package/dist/commands/ingest.js +86 -24
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +21 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/source-check.d.ts.map +1 -1
- package/dist/commands/source-check.js +27 -9
- package/dist/commands/source-check.js.map +1 -1
- package/dist/commands/source-stamp.d.ts +6 -5
- package/dist/commands/source-stamp.d.ts.map +1 -1
- package/dist/commands/source-stamp.js +8 -7
- package/dist/commands/source-stamp.js.map +1 -1
- package/dist/config/defaults.d.ts +103 -4
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +76 -4
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/render.d.ts +11 -0
- package/dist/config/render.d.ts.map +1 -1
- package/dist/config/render.js +85 -3
- package/dist/config/render.js.map +1 -1
- package/dist/config/schema.d.ts +50 -30
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +151 -62
- package/dist/config/schema.js.map +1 -1
- package/dist/core/agents-doc.d.ts.map +1 -1
- package/dist/core/agents-doc.js +4 -1
- package/dist/core/agents-doc.js.map +1 -1
- package/dist/core/checks/harness-portability-checks.d.ts +1 -1
- package/dist/core/checks/harness-portability-checks.d.ts.map +1 -1
- package/dist/core/checks/harness-portability-checks.js +2 -3
- package/dist/core/checks/harness-portability-checks.js.map +1 -1
- package/dist/core/checks/manifest.d.ts.map +1 -1
- package/dist/core/checks/manifest.js +2 -0
- package/dist/core/checks/manifest.js.map +1 -1
- package/dist/core/checks/organize-checks.d.ts +11 -1
- package/dist/core/checks/organize-checks.d.ts.map +1 -1
- package/dist/core/checks/organize-checks.js +42 -12
- package/dist/core/checks/organize-checks.js.map +1 -1
- package/dist/core/checks/retrieval-checks.d.ts +9 -0
- package/dist/core/checks/retrieval-checks.d.ts.map +1 -0
- package/dist/core/checks/retrieval-checks.js +30 -0
- package/dist/core/checks/retrieval-checks.js.map +1 -0
- package/dist/core/content/canonicalize.d.ts +10 -0
- package/dist/core/content/canonicalize.d.ts.map +1 -1
- package/dist/core/content/canonicalize.js +12 -0
- package/dist/core/content/canonicalize.js.map +1 -1
- package/dist/core/errors.d.ts +19 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +53 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/fs/prefix.d.ts +13 -0
- package/dist/core/fs/prefix.d.ts.map +1 -0
- package/dist/core/fs/prefix.js +22 -0
- package/dist/core/fs/prefix.js.map +1 -0
- package/dist/core/graph/persist.d.ts +13 -0
- package/dist/core/graph/persist.d.ts.map +1 -1
- package/dist/core/graph/persist.js +24 -0
- package/dist/core/graph/persist.js.map +1 -1
- package/dist/core/hooks.d.ts +3 -12
- package/dist/core/hooks.d.ts.map +1 -1
- package/dist/core/hooks.js +24 -20
- package/dist/core/hooks.js.map +1 -1
- package/dist/core/ingest/capture-hash.d.ts +16 -0
- package/dist/core/ingest/capture-hash.d.ts.map +1 -0
- package/dist/core/ingest/capture-hash.js +34 -0
- package/dist/core/ingest/capture-hash.js.map +1 -0
- package/dist/core/ingest/identity.d.ts +7 -1
- package/dist/core/ingest/identity.d.ts.map +1 -1
- package/dist/core/ingest/identity.js +16 -1
- package/dist/core/ingest/identity.js.map +1 -1
- package/dist/core/ingest/model.d.ts +17 -2
- package/dist/core/ingest/model.d.ts.map +1 -1
- package/dist/core/ingest/model.js +5 -0
- package/dist/core/ingest/model.js.map +1 -1
- package/dist/core/migrations/config-defaults-as-the-convention.d.ts +21 -0
- package/dist/core/migrations/config-defaults-as-the-convention.d.ts.map +1 -0
- package/dist/core/migrations/config-defaults-as-the-convention.js +54 -0
- package/dist/core/migrations/config-defaults-as-the-convention.js.map +1 -0
- package/dist/core/migrations/registry.d.ts.map +1 -1
- package/dist/core/migrations/registry.js +4 -0
- package/dist/core/migrations/registry.js.map +1 -1
- package/dist/core/migrations/retain-captures-as-provenance.d.ts +22 -0
- package/dist/core/migrations/retain-captures-as-provenance.d.ts.map +1 -0
- package/dist/core/migrations/retain-captures-as-provenance.js +133 -0
- package/dist/core/migrations/retain-captures-as-provenance.js.map +1 -0
- package/dist/core/notes/list.d.ts +20 -0
- package/dist/core/notes/list.d.ts.map +1 -1
- package/dist/core/notes/list.js +27 -6
- package/dist/core/notes/list.js.map +1 -1
- package/dist/core/records.d.ts +7 -0
- package/dist/core/records.d.ts.map +1 -1
- package/dist/core/records.js +12 -2
- package/dist/core/records.js.map +1 -1
- package/dist/core/retrieval/pass.d.ts +66 -0
- package/dist/core/retrieval/pass.d.ts.map +1 -0
- package/dist/core/retrieval/pass.js +171 -0
- package/dist/core/retrieval/pass.js.map +1 -0
- package/dist/core/write-lifecycle/path-gate.d.ts +2 -2
- package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
- package/dist/core/write-lifecycle/path-gate.js +9 -10
- package/dist/core/write-lifecycle/path-gate.js.map +1 -1
- package/dist/run.d.ts +0 -5
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +38 -3
- package/dist/run.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +13 -5
- package/templates/agents/capture-and-ingest.md +27 -8
- package/templates/agents/retrieval-leg-routing.md +34 -8
- package/templates/hooks/_resolve-ctxr.sh +37 -0
- package/templates/hooks/claude-code-write-gate.sh +34 -6
- package/templates/hooks/pre-commit.sh +15 -8
- package/templates/skills/ctxr-connection-finding.md +7 -5
- package/templates/skills/ctxr-ingest-orchestration.md +15 -9
- package/templates/skills/ctxr-publish.md +7 -8
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Contexture (`ctxr`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/ctxr-cli) [](https://github.com/ayxuerui/contexture/actions/workflows/ci.yml) [](LICENSE)
|
|
4
|
+
|
|
5
|
+
**Your agents' long-term knowledge — they write it, you review it before it lands.**
|
|
6
|
+
|
|
7
|
+
Contexture turns a git repository into shared, durable knowledge, and ships the operating procedures an AI agent needs to work it: what to do with a new source, where a note belongs, when a synthesis has gone stale, how a change gets reviewed and landed. Every write lands the way code does — in a branch, past a health check, through a pull request you approve.
|
|
8
|
+
|
|
9
|
+
This is one layer of agent memory — the shared one. Your harness keeps what an agent knows about you and itself; contexture keeps what *you* know, reviewed and versioned, outliving any single agent or session. Claude Code, Codex, Cursor, Cline, Gemini CLI, a cron job, or you at a terminal all operate the same store through the same files.
|
|
10
|
+
|
|
11
|
+
A **store** is an ordinary git repository: markdown notes joined by `[[wikilinks]]`, with `contexture.yaml` as the single source of truth for how that particular store is shaped — its taxonomy, its paths, its relation vocabulary. `ctxr` is a mechanism-only CLI over it — it builds indexes, enforces invariants, and performs validated writes, but it makes no editorial decisions. The judgment lives in **skills**: portable markdown decision procedures that `ctxr init` installs into the store, which whatever agent you're talking to reads and follows. That split is the whole design, and it's what makes the same store operable from any harness.
|
|
4
12
|
|
|
5
13
|
## Install
|
|
6
14
|
|
|
@@ -8,36 +16,309 @@ The structured context platform for the organization — a context store that in
|
|
|
8
16
|
npm install -g ctxr-cli
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
Requires Node 22.13 or newer.
|
|
20
|
+
|
|
21
|
+
The package is `ctxr-cli`, the command it installs is `ctxr`, and the project is Contexture — which is why a store’s own files keep the full name (`contexture.yaml`, `.contexture/`, `CONTEXTURE_*`). A `contexture` alias executable is installed too; docs and generated files always say `ctxr`.
|
|
22
|
+
|
|
23
|
+
## Quickstart
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
mkdir my-store && cd my-store
|
|
27
|
+
ctxr init
|
|
28
|
+
ctxr adapters generate # writes the harness entry file (CLAUDE.md) and its permission config
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`ctxr init` asks two questions, then creates the git repository (if there isn't one), scaffolds the store, and commits it:
|
|
32
|
+
|
|
33
|
+
- **Which taxonomy profile?** `para` (Projects / Areas / Resources / Archives — the default), `zettelkasten` (no layers at all; structure emerges from links), or `diataxis` (Tutorials / How-to / Reference / Explanation). Or bring your own layer list with `--taxonomy <file.yaml>`.
|
|
34
|
+
- **Which agent harnesses?** `claude-code` (default — its adapter generates `CLAUDE.md` plus a `.claude/settings.json` wiring up the write-gate hook) and/or `hermes-agent` (reads `AGENTS.md` directly, so it needs no entry file at all). `--harness none` opts out.
|
|
12
35
|
|
|
13
|
-
|
|
36
|
+
Harness adapter output is the one part `init` doesn't write itself, which is why `ctxr adapters generate` is a separate line above; `ctxr update` regenerates it from then on.
|
|
37
|
+
|
|
38
|
+
Non-interactively, pass them as flags — nothing ever blocks on a prompt:
|
|
14
39
|
|
|
15
40
|
```sh
|
|
16
|
-
ctxr init
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
41
|
+
ctxr init --profile para --harness claude-code
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`init` is idempotent. Re-running it against an existing store reconciles it instead (the same code path as `ctxr update`) rather than overwriting anything.
|
|
45
|
+
|
|
46
|
+
## What a store looks like on disk
|
|
47
|
+
|
|
48
|
+
After `ctxr init --profile para`, plus `ctxr adapters generate`:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
contexture.yaml single source of truth — what this store chose; the rest takes shipped defaults
|
|
52
|
+
AGENTS.md generated entry document — six managed sections
|
|
53
|
+
CLAUDE.md harness entry file; a one-line managed import of AGENTS.md
|
|
54
|
+
.claude/
|
|
55
|
+
settings.json PreToolUse hook wiring for the write gate
|
|
56
|
+
hooks/ the write-gate shim
|
|
57
|
+
skills/ -> ../.agents/skills a bridge, so Claude Code auto-discovers the canonical skills
|
|
58
|
+
.agents/skills/ THE canonical skills location, read natively by most harnesses
|
|
59
|
+
ctxr-*/SKILL.md 13 contexture-owned skills (refreshed by `ctxr update`)
|
|
60
|
+
frontend-design/, eli5/ vendored third-party skills, with licenses and provenance
|
|
61
|
+
.contexture/guidance/
|
|
62
|
+
house-conventions.md your store's own rules — inlined into AGENTS.md verbatim
|
|
63
|
+
mission.md the standing "what's active right now" document
|
|
64
|
+
.githooks/
|
|
65
|
+
pre-commit runs `doctor --staged`
|
|
66
|
+
pre-push refuses a push to the default branch
|
|
67
|
+
projects/ areas/ resources/ archives/ the taxonomy's layers
|
|
68
|
+
raw/inbox/ where captured material lands, before ingest
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
These appear the first time they're needed rather than at init:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
raw/<YYYYMM>/ retained captures, one directory per month of ingest
|
|
75
|
+
.contexture/catalog/*.md one section per layer, plus uncategorized — tracked in git
|
|
76
|
+
.contexture/publish/ published pages
|
|
77
|
+
.contexture/cache/ gitignored — graph.json and the human-readable graph.md
|
|
78
|
+
.worktrees/ gitignored — session worktrees
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Two distinctions make the rest of this readable:
|
|
82
|
+
|
|
83
|
+
**Derived vs. authored.** Never hand-edit inside a `contexture:<region>` fence — the next build overwrites it. Edits *outside* a fence survive every rebuild, and that's where they belong: the catalog generates each note's entry line but preserves the one-line gloss you write next to it, forever.
|
|
84
|
+
|
|
85
|
+
**`.contexture/` is not content, and neither is `raw/`.** The store's own home directory, the skills directory, and the worktrees path are excluded from every retrieval leg by default (`retrieval.exclude_paths`), so the store's plumbing never shows up as an answer to a question about the store's subject matter. `raw/` — the capture tier — is excluded for a different reason: what arrived is not yet what you know. It is tracked in git all the same, because a retained capture is the provenance behind a note.
|
|
86
|
+
|
|
87
|
+
## How agents drive it
|
|
88
|
+
|
|
89
|
+
`ctxr init` writes two things an agent reads, both generated from your store's own config — never from a hardcoded layout:
|
|
90
|
+
|
|
91
|
+
**`AGENTS.md`**, with six managed sections: *Store fundamentals* (root resolution, the frontmatter schema, the write path), *Mission*, *Retrieval: which leg to use*, *Capturing and ingesting*, *Placing a new note* (rendered from your actual taxonomy layers), and *Store conventions*.
|
|
92
|
+
|
|
93
|
+
**The skills**, installed as full copies at `.agents/skills/ctxr-<name>/SKILL.md`. That path is the cross-harness canonical location; a harness that reads its own branded directory instead gets that directory bridged to it (`.claude/skills/` is a symlink), so skill auto-discovery works with no wrapper and no second copy. A harness without auto-discovery reaches the same file by path from `AGENTS.md`. They're contexture-owned — refreshed by `ctxr update`, never hand-edited — and they're written against *your* store's configured taxonomy and relation vocabulary, so no shipped profile's layer names leak into them. Your own skills live alongside, untouched by sync.
|
|
94
|
+
|
|
95
|
+
| Skill | What it decides |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| `ctxr-ingest-orchestration` | What the store should know after a source — not where to file it |
|
|
98
|
+
| `ctxr-placement` | Which layer and location a note belongs in, and why |
|
|
99
|
+
| `ctxr-connection-finding` | Traversing links that already exist |
|
|
100
|
+
| `ctxr-connection-proposal` | Discovering links a note *should* have |
|
|
101
|
+
| `ctxr-rollup` | Synthesizing an entity's current state from every note referencing it |
|
|
102
|
+
| `ctxr-mission` | Keeping the store's priorities / back burner / debt document current |
|
|
103
|
+
| `ctxr-organize-audit` | Placement review, retiring, classifying broken links |
|
|
104
|
+
| `ctxr-derived-artifacts` | Rebuilding catalog, graph, and generated docs without clobbering them |
|
|
105
|
+
| `ctxr-publish` | Whether a subject earns a page, and what may appear on it |
|
|
106
|
+
| `ctxr-session-lifecycle` | Starting a session, re-scanning, conflicts, sequencing several PRs |
|
|
107
|
+
| `ctxr-submit` | Everything up to and including opening the pull request |
|
|
108
|
+
| `ctxr-land` | Merging after review, and reclaiming the worktree |
|
|
109
|
+
| `ctxr-session-capture` | What a finished session produced that is worth keeping |
|
|
110
|
+
|
|
111
|
+
Your house rules go in `.contexture/guidance/house-conventions.md`. It's inlined into `AGENTS.md`'s *Store conventions* section in full, so it loads for every harness at the start of every session — there's no separate file an agent has to remember to open.
|
|
112
|
+
|
|
113
|
+
## A session, end to end
|
|
114
|
+
|
|
115
|
+
This is the loop you actually live in: start a session, talk to the agent, publish, submit, land.
|
|
116
|
+
|
|
117
|
+
```mermaid
|
|
118
|
+
flowchart LR
|
|
119
|
+
S["1 · ctxr session start<br/><small>new worktree</small>"]
|
|
120
|
+
C["2 · chat with the agent<br/><small>AGENTS.md + skills</small>"]
|
|
121
|
+
K["3 · capture<br/><small>approve by ID</small>"]
|
|
122
|
+
P["4 · publish<br/><small>optional</small>"]
|
|
123
|
+
U["5 · submit<br/><small>doctor, commit, PR</small>"]
|
|
124
|
+
R(["review"])
|
|
125
|
+
L["6 · land<br/><small>merge, reclaim</small>"]
|
|
126
|
+
|
|
127
|
+
S --> C --> K --> P --> U --> R --> L
|
|
128
|
+
|
|
129
|
+
G1["write-gate hook"]
|
|
130
|
+
G2["pre-commit · pre-push"]
|
|
131
|
+
C -.- G1
|
|
132
|
+
U -.- G2
|
|
133
|
+
|
|
134
|
+
classDef gate fill:#fbfbfb,stroke:#bbb,stroke-dasharray:4 3,color:#666
|
|
135
|
+
class G1,G2 gate
|
|
23
136
|
```
|
|
24
137
|
|
|
25
|
-
Every command accepts `--root <path>` (or `CONTEXTURE_ROOT`) and `--json`.
|
|
26
138
|
|
|
27
|
-
|
|
139
|
+
**1. Start.** `ctxr session start` creates a git worktree on a generated `session/…` branch off a freshly fetched `origin/<default-branch>`, and prints its path:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
Session worktree at "/path/to/my-store/.worktrees/session-20260903-060120-5ccbd6"
|
|
143
|
+
on branch "session/20260903-060120-5ccbd6" (from master).
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
With no remote configured it falls back honestly to the local branch tip rather than failing. `cd` there and open your agent. Never work in the canonical clone — `ctxr session list` shows what's active. (The default branch is whatever `git init` actually created, recorded once at init; nothing hardcodes `main`.)
|
|
28
147
|
|
|
29
|
-
|
|
30
|
-
already on the registry, via [`.github/workflows/release.yml`](.github/workflows/release.yml).
|
|
31
|
-
Ordinary merges are a no-op — only a version bump triggers a publish.
|
|
148
|
+
**2. Chat.** Your harness loads `AGENTS.md` — or `CLAUDE.md`, which imports it — at session start, and discovers the skills through the bridged directory. Describe what you want in plain language: *"read this article and file it"*, *"what do we know about Acme"*, *"roll up this entity"*, *"make me a page comparing these three"*. The agent picks the skill. There's nothing to memorize; the [knowledge loop](#the-knowledge-loop) below is what it runs on your behalf, documented for when you want to drive a step yourself.
|
|
32
149
|
|
|
33
|
-
|
|
150
|
+
**3. Wrap.** On *your* closing signal — "done", "ship it", a sign-off; never the agent's own summary — `ctxr-session-capture` fires exactly once. It proposes, in a single message with IDs, what the session produced that is durable, split by kind: a **fact** about what happened becomes a store note, a **rule for future work** becomes a house convention. Nothing is written until you approve by ID. Approved notes go through:
|
|
34
151
|
|
|
35
152
|
```sh
|
|
36
|
-
|
|
37
|
-
npm version X.Y.Z --no-git-tag-version # bumps package.json and package-lock.json together
|
|
38
|
-
# hand-edit src/version.ts's CLI_VERSION to match X.Y.Z
|
|
153
|
+
ctxr session capture --proposal approved.yaml
|
|
39
154
|
```
|
|
40
155
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
156
|
+
```yaml
|
|
157
|
+
notes:
|
|
158
|
+
- id: A1
|
|
159
|
+
path: resources/Acme.md
|
|
160
|
+
mode: create # or: append
|
|
161
|
+
frontmatter:
|
|
162
|
+
title: Acme
|
|
163
|
+
body: |
|
|
164
|
+
# Acme
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Each item is validated and applied independently, so one bad path refuses that item alone rather than the whole proposal. Approved *conventions* aren't notes — they're a direct edit to `house-conventions.md` followed by `ctxr update`, staged in the same commit. (A guidance edit without the matching `AGENTS.md` regeneration fails `doctor --staged`, and the pre-commit hook refuses it.)
|
|
168
|
+
|
|
169
|
+
**4. Publish**, if the session earned a page. Run it before submit so the page rides the same pull request. See [Express](#5-express--publish-a-page) below.
|
|
170
|
+
|
|
171
|
+
**5. Submit.** `ctxr-submit`: re-scan git state (never replay a plan from an earlier snapshot), run the capture pass, stage surgically with `git add <paths>` — never `-A`, and derived cache paths never stage — then `ctxr doctor` over the whole store, not `--staged`: a session's job is to leave the *store* healthy, not merely to pass one commit's gate. Then commit, rename the generated branch to something meaningful before it reaches the forge, `git push -u origin <branch>`, and `gh pr create`. If `gh` has no reachable GitHub remote, the push still succeeds on its own and you get manual pull-request instructions instead of a retry loop.
|
|
172
|
+
|
|
173
|
+
**6. Land.** `ctxr-land`, after review: name the pull request explicitly rather than inferring it from whichever checkout you're standing in, read its state and mergeability with `gh pr view`, then wait for an explicit go — plan consent is not fire consent. `gh pr merge --squash`, then re-read state to confirm the forge reports `MERGED`; a transport error can arrive after a merge already succeeded, so the exit code alone is never enough. Finally fast-forward the canonical clone (`git fetch origin && git merge --ff-only`) and reclaim the worktree (`git worktree remove`, `git branch -d`) — nothing sweeps up afterward, so a worktree left here is left indefinitely.
|
|
174
|
+
|
|
175
|
+
`ctxr-session-lifecycle` covers what surrounds both halves: when to re-scan, the conflict playbook, and sequencing several pull requests.
|
|
176
|
+
|
|
177
|
+
### Why steps 5 and 6 aren't CLI commands
|
|
178
|
+
|
|
179
|
+
They're ordinary `git` and `gh`. The CLI owns only what git cannot do — creating the worktree, applying validated note writes, running the health gates — and the sequencing, the confirmation gates, and the judgment live in the skills, where you can read and change them. That's why `ctxr session` has exactly three subcommands: `start`, `capture`, and `list`.
|
|
180
|
+
|
|
181
|
+
Three mechanical backstops hold the line underneath all of it: the **pre-commit** hook runs `doctor --staged`; the **pre-push** hook refuses a push to the default branch (`CONTEXTURE_ALLOW_DEFAULT_BRANCH_PUSH=1` is the emergency override, for emergencies); and for Claude Code the **write-gate** PreToolUse hook denies any edit under the store root made outside the active session worktree.
|
|
182
|
+
|
|
183
|
+
## The knowledge loop
|
|
184
|
+
|
|
185
|
+
What the agent is doing inside step 2 — and how to drive any of it by hand.
|
|
186
|
+
|
|
187
|
+
Four of these are the moves knowledge work is made of: **capture** what arrives, **organize** it so it stays navigable, **distill** it into something that answers a question, **express** it for a reader who wasn't there. Retrieval isn't a stage — it's what makes the other four worth doing — but it sits second here because it's the one you reach for constantly.
|
|
188
|
+
|
|
189
|
+
### 1. Capture — get material in without duplicating it
|
|
190
|
+
|
|
191
|
+
Capture is just writing the material into `raw/inbox/`; no CLI wraps it. It may already carry `source_type` and `source_id` — whatever fetched it usually knows them — but never `source_hash` or `ingested`, which contexture assigns once, at ingest. Then:
|
|
192
|
+
|
|
193
|
+
```sh
|
|
194
|
+
ctxr source check raw/inbox/note.md --source-id https://example.com/a
|
|
195
|
+
# ...read the cluster, decide, write or extend the note...
|
|
196
|
+
ctxr ingest raw/inbox/note.md --into resources/topic.md --source-type article --source-id https://example.com/a
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`source check` returns one of five verdicts: `new`, `already_ingested`, `drift` (same source, its content moved — read what changed before deciding), `alternate_source_match` (this content is already here under a different identity), or `multiple_matches` — which exits non-zero and means *stop and resolve the ambiguity yourself*, never guess which existing record it is. URLs are canonicalized first, with tracking parameters stripped (`ingest.tracking_params`). `ctxr source stamp` backfills a record with no hash on file; `ctxr source add-alt` records material re-published at a new URL, rather than ingesting it twice.
|
|
200
|
+
|
|
201
|
+
`ctxr ingest` stamps the four identity fields **onto the capture**, moves it out of the inbox into `raw/<YYYYMM>/`, records its path in the destination note's `sources` list, and rebuilds the catalog. The note carries no source identity of its own, which is what lets it be rewritten, merged or restructured without invalidating the frozen hash — and what lets one note cite the several captures it was built from. `--into` is required: ingest never creates the note, because deciding what the store should know is the work.
|
|
202
|
+
|
|
203
|
+
Material that isn't markdown can't carry frontmatter, so it travels with a markdown sidecar naming it in `capture_file`; the hash is taken over that file's bytes and the two move together.
|
|
204
|
+
|
|
205
|
+
The commands are the easy part. `ctxr-ingest-orchestration` exists because ingest is **synthesis, not filing** — "create a new note" is one option among several, and the skill's decision table (new note / expand an existing one / merge two / restructure / add a section to a hub) is the actual work. Every row of that table ends in the same `ingest` call, so provenance is recorded whichever one you take. `ctxr-placement` decides where the result lives, and says why.
|
|
206
|
+
|
|
207
|
+
### 2. Retrieve — three legs, no ranker
|
|
208
|
+
|
|
209
|
+
```sh
|
|
210
|
+
ctxr catalog show --section projects # curated index, one section per layer
|
|
211
|
+
ctxr graph build # then query it, or read .contexture/cache/graph.md
|
|
212
|
+
ctxr graph query neighbors <path> --depth 2
|
|
213
|
+
ctxr graph query hubs
|
|
214
|
+
ctxr graph query orphans
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The **catalog** is coverage-guaranteed: every retrievable note has exactly one section, so nothing is silently unindexed. Section ids are your layer paths plus `uncategorized` (or a single `notes` section under a zero-layer profile). The **graph** enumerates structure and ranks nothing — neighbors, shortest path, hubs, clusters, bridges, orphans; `--type <relation>` follows one configured relation. `graph build` also writes a human-readable `graph.md` summarizing hubs by cluster. The third leg is **your own grep**, for literal strings the first two can't answer, scoped to exclude `.contexture/`.
|
|
218
|
+
|
|
219
|
+
There is no `ctxr search`, and no semantic ranking. That's deliberate, not missing.
|
|
220
|
+
|
|
221
|
+
→ `ctxr-connection-finding` (traverse what exists), `ctxr-connection-proposal` (discover what should).
|
|
222
|
+
|
|
223
|
+
### 3. Organize — keep it navigable as it grows
|
|
224
|
+
|
|
225
|
+
```sh
|
|
226
|
+
ctxr lint # observations — orphans, broken links, material still in the inbox; always exits 0
|
|
227
|
+
ctxr doctor # invariants — exits non-zero, and gates every commit
|
|
228
|
+
ctxr catalog check --stale
|
|
229
|
+
ctxr archive <path>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The `lint` / `doctor` split is the point: lint reports what's *worth reviewing* and never blocks; doctor reports what's *broken* and does. `ctxr archive` retires a note as a single tracked rename into `organize.archive_destination`, leaving its frontmatter byte-identical and reporting every note that linked to it — move it, don't tag it, or the active layers stop meaning anything. (The note must be committed first; archive won't rename something git isn't tracking.)
|
|
233
|
+
|
|
234
|
+
→ `ctxr-organize-audit`, `ctxr-derived-artifacts`.
|
|
235
|
+
|
|
236
|
+
### 4. Distill — rollups and the mission document
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
ctxr rollup stale # entities whose backlinks moved since last synthesis
|
|
240
|
+
ctxr rollup gather <entity> # enumerate the source notes
|
|
241
|
+
ctxr rollup write <entity> --content-file draft.md # idempotent fenced write
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Gather and write are deterministic; the synthesis in between is the agent's, over *every* source rather than a sample. The write only ever touches the fenced region — hand-written content elsewhere in the note is never disturbed, and re-writing identical content reports `changed: false` and leaves the file byte-identical.
|
|
245
|
+
|
|
246
|
+
The store's own `.contexture/guidance/mission.md` uses the same write path, but is reported stale on elapsed time (`organize.rollup_stale_days`) rather than on backlinks.
|
|
247
|
+
|
|
248
|
+
→ `ctxr-rollup`, `ctxr-mission`.
|
|
249
|
+
|
|
250
|
+
### 5. Express — publish a page
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
ctxr publish gather --under resources/ # or --note <path>, or --entity <name>
|
|
254
|
+
ctxr publish new comparison # scaffolds the page folder and its sibling README
|
|
255
|
+
ctxr publish check .contexture/publish/comparison
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
`gather` resolves a subject to its note set — never a hand-picked list, which is how an unintended note slips onto a page unnoticed. `check` runs the structural gates: no external references, viewport meta, a print rule, provenance, the sibling README, script syntax. What a page may *contain*, given who will read it, is a judgment `ctxr-publish` walks you through and no check can make.
|
|
259
|
+
|
|
260
|
+
→ `ctxr-publish`, plus the vendored `frontend-design` and `eli5` skills for the craft contexture supplies none of.
|
|
261
|
+
|
|
262
|
+
## Reading a store in a browser
|
|
263
|
+
|
|
264
|
+
```sh
|
|
265
|
+
ctxr serve
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Renders notes, catalog sections, the graph document, and published pages as cross-linked HTML. It binds loopback (`127.0.0.1`) by default. `--host` widens that, but note what it does not change: `serve` applies **no per-requester filtering at any bind address**. Widening it exposes the whole store to whatever can reach that address, so only do it behind a front end you've arranged yourself.
|
|
269
|
+
|
|
270
|
+
## Keeping a store current
|
|
271
|
+
|
|
272
|
+
```sh
|
|
273
|
+
ctxr update # refresh every contexture-owned file to the installed version
|
|
274
|
+
ctxr migrate --dry-run # report what pending schema migrations would change
|
|
275
|
+
ctxr migrate
|
|
276
|
+
ctxr verify --portable # prove the store works from a harness with no harness-specific state
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
`ctxr update` re-renders the `AGENTS.md` sections, skill copies, hooks, and adapter outputs — run it after upgrading the CLI, and after editing your house conventions.
|
|
280
|
+
|
|
281
|
+
`schema_version` in `contexture.yaml` versions *store state* — the config shape and frontmatter conventions — as a monotonic integer independent of the npm package version. A store recorded at a newer schema than your CLI supports is refused rather than half-read.
|
|
282
|
+
|
|
283
|
+
### The config records decisions, not values
|
|
284
|
+
|
|
285
|
+
A generated `contexture.yaml` is short, and that's the design: **any key it doesn't declare takes contexture's shipped default.** So everything the file *does* contain is a choice someone made, and a store that simply agrees with a convention follows it as the convention improves — a later release that changes a shipped default reaches every store that never overrode it, with no migration.
|
|
286
|
+
|
|
287
|
+
Three kinds of key are always written out, because no constant could be right for them:
|
|
288
|
+
|
|
289
|
+
- **Store facts** — `taxonomy`, and `git.default_branch`, which records whatever branch your repository actually uses rather than a guess.
|
|
290
|
+
- **Taxonomy-derived** — `organize.archive_destination`, resolved from the profile at init. Defaulting it to a flat constant would send a PARA store's archived notes to `archive/` while its own taxonomy declares `archives/`.
|
|
291
|
+
- **Opt-ins** — `organize.mission_path`, where *not* declaring the key is what says the store has no mission document.
|
|
292
|
+
|
|
293
|
+
To pin a value against a future default change, declare it. `ctxr migrate` removes keys that merely restate a default; it never changes what any key resolves to.
|
|
294
|
+
|
|
295
|
+
## Command reference
|
|
296
|
+
|
|
297
|
+
| Command | What it does |
|
|
298
|
+
| --- | --- |
|
|
299
|
+
| `init` | Create a store, or reconcile an existing one |
|
|
300
|
+
| `doctor [--staged]` | Check real invariants; non-zero on any failure |
|
|
301
|
+
| `lint` | Health observations; always exits 0 |
|
|
302
|
+
| `catalog build \| check \| show` | Build, verify coverage, print a section |
|
|
303
|
+
| `graph build` | Rebuild the wikilink graph and its document |
|
|
304
|
+
| `graph query …` | `neighbors`, `path`, `subgraph`, `hubs`, `clusters`, `bridges`, `orphans` |
|
|
305
|
+
| `ingest <path> --into <note>` | Retain a capture with its source identity, and cite it from a note |
|
|
306
|
+
| `source hash \| check \| stamp \| add-alt` | Dedupe and source identity, ahead of ingest |
|
|
307
|
+
| `archive <path>` | Retire a note via one tracked rename |
|
|
308
|
+
| `entry append <path>` | Append a line into a `contexture:<region>` fenced region |
|
|
309
|
+
| `rollup gather \| write \| stale` | Entity synthesis: enumerate, write, find what's out of date |
|
|
310
|
+
| `publish gather \| new \| check` | Resolve a subject, scaffold a page, run the structural gates |
|
|
311
|
+
| `session start \| capture \| list` | Session worktrees, and applying an approved capture proposal |
|
|
312
|
+
| `adapters generate \| write-gate` | Regenerate harness outputs; the write-gate hook target |
|
|
313
|
+
| `serve` | Read the store in a browser |
|
|
314
|
+
| `update` | Bring contexture-owned files up to the installed version |
|
|
315
|
+
| `migrate [--dry-run]` | Apply pending schema migrations |
|
|
316
|
+
| `verify [--portable]` | Exercise core store operations end to end |
|
|
317
|
+
|
|
318
|
+
Every command accepts `--root <path>`, `--json`, and `--no-input`. The store root resolves in exactly one order: `--root`, then `CONTEXTURE_ROOT`, then walking up from the current directory looking for `contexture.yaml`. Nothing else selects it.
|
|
319
|
+
|
|
320
|
+
Exit codes are a fixed taxonomy, so scripts and hooks can rely on them: `0` success, `1` an internal error (a bug), `2` a usage error (bad arguments, no store root, not a git repository), `3` a check that ran correctly and found a real problem. Success never masks a finding — `doctor` and `catalog check` exit `3` on a violation, never `0`.
|
|
321
|
+
|
|
322
|
+
## Contributing
|
|
323
|
+
|
|
324
|
+
Build, test, the spec-first workflow, and the release process are in [CONTRIBUTING.md](CONTRIBUTING.md). Contexture is MIT licensed — see [LICENSE](LICENSE).
|
package/dist/adapters/types.d.ts
CHANGED
|
@@ -43,16 +43,11 @@ export declare const SUPPORTED_ADAPTER_INTERFACE_VERSION: Record<AdapterKind, nu
|
|
|
43
43
|
* itself is invoked by (a hook command): `root` is deleted the moment the
|
|
44
44
|
* session worktree that generated it lands, so a path anchored there goes
|
|
45
45
|
* stale as soon as that happens.
|
|
46
|
-
*
|
|
47
|
-
* `binPath` is this installation's own resolved CLI entrypoint, for a
|
|
48
|
-
* harness whose config needs to shell out back to `ctxr` (a generated hook
|
|
49
|
-
* script). See claude-code.ts's permissionConfig for the concrete case.
|
|
50
46
|
*/
|
|
51
47
|
export interface PermissionConfigInput {
|
|
52
48
|
root: string;
|
|
53
49
|
mainRoot: string;
|
|
54
50
|
worktreesPath: string;
|
|
55
|
-
binPath: string;
|
|
56
51
|
}
|
|
57
52
|
export interface HarnessGenerationAdapter extends Adapter<'harness-generation'> {
|
|
58
53
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAE/C,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IAC1D,IAAI,EAAE,CAAC,CAAC;IACR,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAI3E,CAAC;AAEF;;;;;;;;;GASG;AACH
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAE/C,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IAC1D,IAAI,EAAE,CAAC,CAAC;IACR,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAI3E,CAAC;AAEF;;;;;;;;;GASG;AACH;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAyB,SAAQ,OAAO,CAAC,oBAAoB,CAAC;IAC7E;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,0LAA0L;IAC1L,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,kFAAkF;IAClF,gBAAgB,CAAC,EAAE;QACjB,iEAAiE;QACjE,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9D;;;;;;WAMG;QACH,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpE,0GAA0G;QAC1G,QAAQ,CAAC,EAAE;YACT,uCAAuC;YACvC,gBAAgB,EAAE,MAAM,CAAC;YACzB,2EAA2E;YAC3E,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB,EAAE,wBAAwB,CAAC;CAChD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters-generate.d.ts","sourceRoot":"","sources":["../../src/commands/adapters-generate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAG7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAKrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AAE/D,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,0BAA0B,EAAE,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wDAAwD;AACxD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,0BAA0B,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"adapters-generate.d.ts","sourceRoot":"","sources":["../../src/commands/adapters-generate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAG7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAKrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AAE/D,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,0BAA0B,EAAE,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wDAAwD;AACxD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,0BAA0B,EAAE,CAAC,CAgDhH;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAWtG"}
|
|
@@ -4,7 +4,7 @@ import { agentsMdPath } from '../core/agents-doc.js';
|
|
|
4
4
|
import { ExitCode } from '../core/exit-codes.js';
|
|
5
5
|
import { upsertFencedRegionInFile } from '../core/fs/fenced-region.js';
|
|
6
6
|
import { mainWorktreePath } from '../core/git/worktree.js';
|
|
7
|
-
import { installTemplatedHookScript
|
|
7
|
+
import { installTemplatedHookScript } from '../core/hooks.js';
|
|
8
8
|
import { mergeJsonArrayLists } from '../core/json-config-merge.js';
|
|
9
9
|
import { harnessEntryFence } from '../core/markers.js';
|
|
10
10
|
export const requires = { store: 'required' };
|
|
@@ -33,11 +33,10 @@ export async function generateAdapterOutputs(git, store) {
|
|
|
33
33
|
root: store.root,
|
|
34
34
|
mainRoot,
|
|
35
35
|
worktreesPath: store.config.session.worktrees_path,
|
|
36
|
-
binPath: resolveOwnBinPath(),
|
|
37
36
|
};
|
|
38
37
|
let permChanged = false;
|
|
39
38
|
if (adapter.permissionConfig.hookFile) {
|
|
40
|
-
const { changed: hookScriptChanged } = await installTemplatedHookScript(store.root, adapter.permissionConfig.hookFile.targetPath, adapter.permissionConfig.hookFile.templateFileName
|
|
39
|
+
const { changed: hookScriptChanged } = await installTemplatedHookScript(store.root, adapter.permissionConfig.hookFile.targetPath, adapter.permissionConfig.hookFile.templateFileName);
|
|
41
40
|
permChanged = permChanged || hookScriptChanged;
|
|
42
41
|
}
|
|
43
42
|
const permPath = path.join(store.root, adapter.permissionConfig.path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters-generate.js","sourceRoot":"","sources":["../../src/commands/adapters-generate.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,
|
|
1
|
+
{"version":3,"file":"adapters-generate.js","sourceRoot":"","sources":["../../src/commands/adapters-generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CommandOutcome, CommandRequires } from '../core/command.js';
|
|
2
|
+
import { type GatherOutcome } from '../core/retrieval/pass.js';
|
|
3
|
+
import type { Store } from '../core/store.js';
|
|
4
|
+
export declare const requires: CommandRequires;
|
|
5
|
+
export interface ContextGatherFlags {
|
|
6
|
+
seed?: string[];
|
|
7
|
+
section?: string[];
|
|
8
|
+
under?: string[];
|
|
9
|
+
entity?: string[];
|
|
10
|
+
hops?: number;
|
|
11
|
+
direction?: 'in' | 'out' | 'both';
|
|
12
|
+
type?: string;
|
|
13
|
+
maxNotes?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* compose-the-retrieval-pass spec: entry selectors in, the graph-expanded
|
|
17
|
+
* neighbourhood out, each note carrying its gloss and the evidence for why it
|
|
18
|
+
* is there. Agent-facing enumeration only — like `rollup gather` and `publish
|
|
19
|
+
* gather`, it finds and orders candidates and never reads or synthesizes them.
|
|
20
|
+
*/
|
|
21
|
+
export declare function execute(store: Store, flags?: ContextGatherFlags): Promise<CommandOutcome<GatherOutcome>>;
|
|
22
|
+
//# sourceMappingURL=context-gather.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-gather.d.ts","sourceRoot":"","sources":["../../src/commands/context-gather.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1E,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAE,kBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAyBlH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ExitCode } from '../core/exit-codes.js';
|
|
2
|
+
import { readAdmittedGraph } from '../core/graph/persist.js';
|
|
3
|
+
import { listNotes } from '../core/notes/list.js';
|
|
4
|
+
import { gather } from '../core/retrieval/pass.js';
|
|
5
|
+
export const requires = { store: 'required' };
|
|
6
|
+
/**
|
|
7
|
+
* compose-the-retrieval-pass spec: entry selectors in, the graph-expanded
|
|
8
|
+
* neighbourhood out, each note carrying its gloss and the evidence for why it
|
|
9
|
+
* is there. Agent-facing enumeration only — like `rollup gather` and `publish
|
|
10
|
+
* gather`, it finds and orders candidates and never reads or synthesizes them.
|
|
11
|
+
*/
|
|
12
|
+
export async function execute(store, flags = {}) {
|
|
13
|
+
const notes = await listNotes(store.root, store.config);
|
|
14
|
+
const graph = await readAdmittedGraph(store);
|
|
15
|
+
const options = {
|
|
16
|
+
seeds: flags.seed,
|
|
17
|
+
sections: flags.section,
|
|
18
|
+
under: flags.under,
|
|
19
|
+
entities: flags.entity,
|
|
20
|
+
hops: flags.hops,
|
|
21
|
+
direction: flags.direction,
|
|
22
|
+
type: flags.type,
|
|
23
|
+
maxNotes: flags.maxNotes,
|
|
24
|
+
};
|
|
25
|
+
const data = await gather(store, notes, graph, options);
|
|
26
|
+
const truncated = data.budget.truncated ? `, ${data.budget.omitted} omitted by the cap of ${data.budget.maxNotes}` : '';
|
|
27
|
+
return {
|
|
28
|
+
exitCode: ExitCode.Ok,
|
|
29
|
+
data,
|
|
30
|
+
findings: [],
|
|
31
|
+
humanSummary: `${data.budget.returned} note(s) within ${data.hops} hop(s)${truncated}.`,
|
|
32
|
+
storeRoot: store.root,
|
|
33
|
+
schemaVersion: store.config.schema_version,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=context-gather.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-gather.js","sourceRoot":"","sources":["../../src/commands/context-gather.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,MAAM,EAA0C,MAAM,2BAA2B,CAAC;AAG3F,MAAM,CAAC,MAAM,QAAQ,GAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAa/D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAY,EAAE,KAAK,GAAuB,EAAE;IACxE,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAkB;QAC7B,KAAK,EAAE,KAAK,CAAC,IAAI;QACjB,QAAQ,EAAE,KAAK,CAAC,OAAO;QACvB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK,CAAC,MAAM;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,0BAA0B,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxH,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,EAAE;QACrB,IAAI;QACJ,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,mBAAmB,IAAI,CAAC,IAAI,UAAU,SAAS,GAAG;QACvF,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-query.d.ts","sourceRoot":"","sources":["../../src/commands/graph-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-query.d.ts","sourceRoot":"","sources":["../../src/commands/graph-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AA0B/D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,cAAc,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC,CAKlD;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,cAAc,CAAC;IAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC,CAUpD;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAKnH;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC,CAAC,CAIpH;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEjD,wBAAsB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAE,YAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC,CAI3H;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAElD,wBAAsB,eAAe,CACnC,KAAK,EAAE,KAAK,EACZ,KAAK,GAAE,aAAkB,GACxB,OAAO,CAAC,cAAc,CAAC;IAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CAAC,CAIvD;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,KAAK,EACZ,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,cAAc,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC,CAAC,CAIrD"}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { GraphNodeNotFoundError
|
|
1
|
+
import { GraphNodeNotFoundError } from '../core/errors.js';
|
|
2
2
|
import { ExitCode } from '../core/exit-codes.js';
|
|
3
3
|
import { bridges, clusters, hubs, neighbors, orphans, shortestPath, subgraph, } from '../core/graph/query.js';
|
|
4
|
-
import {
|
|
4
|
+
import { readAdmittedGraph } from '../core/graph/persist.js';
|
|
5
5
|
export const requires = { store: 'required' };
|
|
6
6
|
/**
|
|
7
|
-
* Every subcommand below routes through this one loader, so a query can
|
|
8
|
-
*
|
|
7
|
+
* Every subcommand below routes through this one loader, so a query can never
|
|
8
|
+
* read a graph the store has not built — nor one carrying a note the store no
|
|
9
|
+
* longer admits, which `readAdmittedGraph` refuses on behalf of every caller.
|
|
9
10
|
*/
|
|
10
11
|
async function loadGraph(store) {
|
|
11
|
-
|
|
12
|
-
if (!graph)
|
|
13
|
-
throw new GraphNotBuiltError();
|
|
14
|
-
return graph;
|
|
12
|
+
return readAdmittedGraph(store);
|
|
15
13
|
}
|
|
16
14
|
function assertNode(graph, nodeId) {
|
|
17
15
|
if (!graph.nodes.some((n) => n.id === nodeId))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-query.js","sourceRoot":"","sources":["../../src/commands/graph-query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"graph-query.js","sourceRoot":"","sources":["../../src/commands/graph-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,25 +4,38 @@ import type { Store } from '../core/store.js';
|
|
|
4
4
|
export declare const requires: CommandRequires;
|
|
5
5
|
export interface IngestFlags {
|
|
6
6
|
path: string;
|
|
7
|
+
into: string;
|
|
7
8
|
sourceType: string;
|
|
8
9
|
sourceId: string;
|
|
9
10
|
}
|
|
10
11
|
export interface IngestData {
|
|
11
|
-
path
|
|
12
|
+
/** Where the capture was retained — its path after the move out of the inbox. */
|
|
13
|
+
capture: string;
|
|
14
|
+
/** The note that now cites it. */
|
|
15
|
+
note: string;
|
|
12
16
|
sourceType: string;
|
|
13
17
|
sourceId: string;
|
|
14
18
|
sourceHash: string;
|
|
15
19
|
ingested: string;
|
|
16
20
|
}
|
|
17
21
|
/**
|
|
18
|
-
* context-ingest spec: identity
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* the
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* context-ingest spec: identity is assigned once, here, onto the CAPTURE —
|
|
23
|
+
* the file that arrived — and never recomputed from it afterwards. The
|
|
24
|
+
* destination note is the synthesis, free to be rewritten without touching
|
|
25
|
+
* the hash, and it may already exist: expanding, merging and restructuring
|
|
26
|
+
* record provenance on the same footing as creating, which is the whole point
|
|
27
|
+
* of retaining the capture rather than consuming it.
|
|
28
|
+
*
|
|
29
|
+
* Order matters for resumability. The capture is written to its retained
|
|
30
|
+
* location before the old one is removed, and the note is cited last, so an
|
|
31
|
+
* interruption leaves either an un-ingested capture or a retained one that a
|
|
32
|
+
* re-run can cite — never a note citing a path that does not exist.
|
|
33
|
+
*
|
|
34
|
+
* Rebuilding the catalog before returning (rather than documenting it as a
|
|
35
|
+
* required next step) is this codebase's choice: a successful write leaves
|
|
36
|
+
* its own derived-artifact consequence consistent immediately, matching every
|
|
37
|
+
* other writer in the system. The retained capture takes no catalog entry —
|
|
38
|
+
* the capture root is a retrieval exclusion, so it is not a note.
|
|
26
39
|
*/
|
|
27
40
|
export declare function execute(env: RunEnv, store: Store, flags: IngestFlags): Promise<CommandOutcome<IngestData>>;
|
|
28
41
|
//# sourceMappingURL=ingest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAiB7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AAE/D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CA2ChH"}
|