@c4a/context 0.6.0-beta.4 → 0.6.0-beta.6

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.
@@ -19,41 +19,110 @@ declaration list. Put heavy logic in imported transform files.
19
19
 
20
20
  ## Sources
21
21
 
22
- A source is a stable knowledge boundary, not only a display label. By default,
23
- `context source add repo/file/lark` uses today's local date (`YYYYMMDD`) as the
24
- source name. Do not derive the name from filenames, directory names, or document
25
- content. If today's date already exists, pass an explicit date name. The source
26
- name becomes a stable identity in source references, phase ids, and package
27
- naming. Approved knowledge paths are derived from collection, containment, and
28
- slug. NodeRef/ViewRef are identity fields, not path strings:
22
+ A source is a stable knowledge boundary, not only a display label. Repo, file,
23
+ and Lark sources use a date batch plus a concrete module name; multiple code or
24
+ document modules may share the date. The flattened selector `YYYYMMDD/module`
25
+ is the source identity used by phases, snapshot paths, and source refs.
26
+ Codegraph NodeRef/ViewRef and knowledge paths use the stable module name without
27
+ the date:
29
28
 
30
29
  ```text
31
30
  knowledge/<collection>/<containment>/<slug>.md
32
- repo:<source-name>#symbol:...
33
- file:<source-name>/<document>#span:...
34
- lark:<source-name>/<document>#span:...
35
- capture:file:<source-name>
36
- align:lark:<source-name>:architecture
31
+ knowledge/codegraph/<module>/symbol/<slug>.md
32
+ repo:<date>/<module>#symbol:...
33
+ file:<date>/<module>/<document>#span:...
34
+ lark:<date>/<module>/<document>#span:...
35
+ capture:file:<date>/<module>
36
+ align:lark:<date>/<module>:architecture
37
37
  dist/<source-name>-kb/...
38
38
  ```
39
39
 
40
- Choose the boundary before extraction. In a monorepo, a source can be the whole
41
- repo/subspace when the user wants one unified knowledge product, or a specific
42
- package/subdirectory when the user wants a focused package manual. Renaming a
43
- source later is a source-ref, phase-id, and package-output migration. Approved
44
- paths are not derived directly from the source name; align/compile derives them
45
- from collection, containment, and slug. Long term, extraction and structure
46
- planning can still choose containment such as `product-ui/component-web` for
47
- child codegraph views:
40
+ Choose the module boundary before extraction. In a monorepo, register each
41
+ confirmed package/subdirectory under the same date batch. A repo root that
42
+ resolves to multiple modules is for inspection; it is not an extraction unit.
43
+ Approved codegraph paths use the stable module name; the date remains only in
44
+ source selectors, phase ids, and evidence refs:
48
45
 
49
46
  ```text
50
- knowledge/codegraph/product-ui/component-web/...
51
- knowledge/codegraph/product-ui/component-lynx/...
47
+ knowledge/codegraph/module-a/...
48
+ knowledge/codegraph/module-b/...
49
+ ```
50
+
51
+ The registry stores this as one date entry containing several `modules` entries,
52
+ and materializes each module at `sources/repo/<date>/<module>`.
53
+ Repo module names are project-wide codegraph identities and therefore cannot be
54
+ reused under another date batch. Refresh an existing module through its original
55
+ date/module selector.
56
+ When a repo module and the Context workspace share the same Git root, the CLI
57
+ normalizes even an absolute `--local` input into a path relative to the
58
+ workspace and stores the package directory as `subpath`. Materialized repo
59
+ links always use relative symlink targets. This keeps the registry and links
60
+ valid when the whole checkout moves. Cross-repository absolute checkout roots
61
+ remain absolute because no shared movable root can be assumed.
62
+ The date entry must be a valid calendar date in `YYYYMMDD` form. Use
63
+ `context source ensure <date>` or `context source inspect <date>` for the whole
64
+ batch, and `<date>/<module>` when targeting one module.
65
+
66
+ ```yaml
67
+ sources:
68
+ - name: "20260712"
69
+ modules:
70
+ - name: module-a
71
+ local: ../monorepo
72
+ subpath: packages/module-a
73
+ git:
74
+ remote: https://git.example.com/product/monorepo.git
75
+ ref: <full-commit-sha>
76
+ - name: module-b
77
+ local: ../monorepo
78
+ subpath: packages/module-b
79
+ git:
80
+ remote: https://git.example.com/product/monorepo.git
81
+ ref: <full-commit-sha>
82
+ ```
83
+
84
+ File and Lark registries use the same outer shape. Their modules hold local
85
+ document boundaries or remote document identities:
86
+
87
+ ```yaml
88
+ sources:
89
+ - name: "20260712"
90
+ modules:
91
+ - name: local-manual
92
+ local: ../manual
93
+ - name: api-guide
94
+ local: ../api-guide
95
+ ```
96
+
97
+ ### Batch source registration
98
+
99
+ Use one command when a user confirms several source modules together:
100
+
101
+ ```bash
102
+ context source add batch [YYYYMMDD] --input <sources.yaml|json|-> --format json
52
103
  ```
53
104
 
54
- In the current repo extraction flow, treat multi-module parent sources as
55
- inspection/planning boundaries. Register the concrete package/subdirectory as
56
- the source before running extraction.
105
+ The payload is a non-empty `sources` array. Every item requires `type`. Repo
106
+ also requires `module` and accepts `local`/`remote`/`ref`. File requires `local`
107
+ and accepts `include`; Lark accepts exactly one of `url`, `docToken`, or
108
+ `wikiToken` plus optional `title`. File/Lark `module` is optional and is derived
109
+ with the same lowercase path-safe rule as the single-source commands. Resolved
110
+ module identities must be unique across the batch.
111
+
112
+ Source mutations share a project write lock, and every registry file is
113
+ replaced atomically. Never run separate `source add` processes in parallel. A
114
+ batch executes items in order; if a runtime item fails, its error lists the
115
+ completed items and the same payload may be rerun idempotently.
116
+
117
+ ```yaml
118
+ sources:
119
+ - name: "20260712"
120
+ modules:
121
+ - name: user-manual
122
+ url: https://example.larksuite.com/wiki/example-a
123
+ - name: migration-guide
124
+ url: https://example.larksuite.com/wiki/example-b
125
+ ```
57
126
 
58
127
  ### `source(name)`
59
128
 
@@ -64,9 +133,49 @@ is a repo, file, or lark source:
64
133
  ```ts
65
134
  import { source } from "@c4a/context";
66
135
 
67
- const docs = source("20260704");
136
+ const legacyDocs = source("product-docs");
137
+ ```
138
+
139
+ ### `source(namespace, module)`
140
+
141
+ Reference one registered repo module. Use the date batch and module name
142
+ returned by `context source add repo`:
143
+
144
+ ```ts
145
+ const moduleA = source("20260712", "module-a");
146
+ const moduleB = source("20260712", "module-b");
147
+ ```
148
+
149
+ These references resolve to `20260712/module-a` and `20260712/module-b`;
150
+ extraction and verification remain independent.
151
+
152
+ ### `source(namespace, module, { type })`
153
+
154
+ Reference one file or Lark module under a date batch:
155
+
156
+ ```ts
157
+ const localManual = source("20260712", "local-manual", { type: "file" });
158
+ const userManual = source("20260712", "user-manual", { type: "lark" });
68
159
  ```
69
160
 
161
+ These references produce module-scoped phase ids and manifest entries without
162
+ treating the date as one document identity. Captured document files remain
163
+ siblings under `sources/file|lark/<date>/` and share the date-level
164
+ `manifest.json`; the logical `date/module` identity does not create another
165
+ directory level.
166
+
167
+ For a confirmed multi-document request, declare one capture phase per module.
168
+ While any module is uncaptured, `context status --format json` reports either:
169
+
170
+ - `needs-capture-phase` with `routing.configuration` when a module is not yet
171
+ declared in `src/index.ts`; or
172
+ - `needs-capture` with every declared command in `routing.command_plan`.
173
+
174
+ Each command-plan item says whether it is `immediate` or
175
+ `after-human-confirmation`. The `routing.human_gate` object identifies the
176
+ decision type and whether its result lives only in the current conversation or
177
+ is persisted by a later workspace command.
178
+
70
179
  ### `allSources("repo")`
71
180
 
72
181
  Reference all repo sources as one collection:
@@ -78,7 +187,7 @@ const repoSources = allSources("repo");
78
187
  ```
79
188
 
80
189
  Use `allSources("repo")` only when the project should list every registered
81
- repo source. Prefer a specific `source("name")` for extraction phases.
190
+ repo module. Prefer a specific `source("date", "module")` for extraction phases.
82
191
 
83
192
  ## Phases
84
193
 
@@ -127,11 +236,12 @@ Phase id:
127
236
  capture:file:<source-name>
128
237
  ```
129
238
 
130
- Register the source first with `context source add file --local <path>`.
239
+ Register the source first with
240
+ `context source add file [YYYYMMDD] --module <module> --local <path>`.
131
241
  The first registration requires `--local`; the registry may later keep `local`
132
- only as a refresh hint while committed snapshots remain verifiable. If the
133
- default date source name already exists, pass an explicit date name:
134
- `context source add file 20260703 --local <path>`.
242
+ only as a refresh hint while committed snapshots remain verifiable. Multiple
243
+ file modules may share one date. When `--module` is omitted, the CLI derives it
244
+ from the local file or directory name.
135
245
 
136
246
  ### `captureLark`
137
247
 
@@ -148,12 +258,21 @@ Phase id:
148
258
  capture:lark:<source-name>
149
259
  ```
150
260
 
151
- Register the source first with `context source add lark` and exactly one
152
- identity flag: `--url`, `--doc-token`, or `--wiki-token`. Capture reads the
261
+ Register each source with
262
+ `context source add lark [YYYYMMDD] --module <module>` and exactly one identity
263
+ flag: `--url`, `--doc-token`, or `--wiki-token`. Multiple documents may share
264
+ one date batch; when `--module` is omitted, the CLI derives an opaque,
265
+ credential-safe module id. Capture reads the
153
266
  remote document through the CLI runner, writes normalized snapshot files under
154
- `sources/lark/<source-name>/`, and does not write access credentials into the
155
- workspace. Multi-document Lark organization goes through `alignProse`; the
156
- current workflow does not provide a one-step Lark stage shortcut.
267
+ `sources/lark/<date>/` as sibling document files tracked by one date-level `manifest.json`, and does not write access credentials into the
268
+ workspace.
269
+
270
+ Use a typed document reference in project declarations:
271
+
272
+ ```ts
273
+ const handbook = source("20260712", "user-manual", { type: "lark" });
274
+ const localDocs = source("20260712", "local-manual", { type: "file" });
275
+ ```
157
276
 
158
277
  ### `alignProse`
159
278
 
@@ -232,6 +351,12 @@ context run compile:file:<source-name>:architecture --validate --input <compile-
232
351
  context run compile:file:<source-name>:architecture --stage --input <compile-actions.yaml> --format json
233
352
  ```
234
353
 
354
+ Compile remains one View per write for evidence isolation. After staging, follow
355
+ `continue_compile_batch` to prepare the next View. Only the final View returns
356
+ the human Review action, so one confirmed structure produces one review
357
+ payload. `context close` is blocked while a planned View is unprepared, still
358
+ draft, or rejected without a structure revision.
359
+
235
360
  Compile action payloads use `schema_version: "context.compile-actions.v1"`.
236
361
  By default, actions should omit body content and let the CLI mirror cited source
237
362
  spans into `verbatim` sections. Explicit reader-visible content is not accepted
@@ -256,24 +381,58 @@ Options:
256
381
 
257
382
  | Field | Meaning |
258
383
  |---|---|
259
- | `source` | `source("name")` |
384
+ | `source` | `source("date", "module")` for one repo module |
260
385
  | `collection` | Code extraction uses `"codegraph"` |
261
386
  | `include` | Optional glob list inside the selected source; default is `["src/**/*.{ts,tsx}"]` |
262
- | `exportedOnly` | Default `true` |
387
+ | `mode` | `"exports"` (default) traces public exports from automatic or configured entries; `"scan"` uses every file matched by `include` as an entry root |
388
+ | `entries` | Optional source-relative entry files for `"exports"` mode. They override `package.json` entry detection and live only in the Context project configuration |
389
+ | `exportedOnly` | Defaults to `true` in `"exports"` mode and `false` in `"scan"` mode |
263
390
  | `transform` | Optional markdown transform function or functions |
264
391
 
265
- In monorepos, make the package/subdirectory the source boundary. Register the
266
- chosen package path with `context source add repo --local <package-dir>` and
267
- reference the CLI-returned date source name with `source("<source-name>")`.
392
+ `source` is the only package/module boundary. `include` narrows files inside
393
+ that source; it does not select a second module. Standard packages can omit
394
+ `entries` and use `package.json` `exports`, `main`, or `bin` detection. For a
395
+ non-standard package, configure `entries` in the Context project instead of
396
+ editing the source repository:
397
+
398
+ ```ts
399
+ extractTs({
400
+ source: componentLib,
401
+ collection: "codegraph",
402
+ include: ["src/**/*.ts"],
403
+ entries: ["src/api.ts"],
404
+ });
405
+ ```
406
+
407
+ When the intended knowledge scope is every declaration in the selected files
408
+ rather than a public export graph, use `mode: "scan"`. Scan mode does not accept
409
+ `entries`; `include` supplies its file roots.
410
+
411
+ Entry failures use the stable machine code `NO_ENTRY_DETECTED`. This includes
412
+ `entries: []`, exports mode with no detected/configured entry, and scan mode
413
+ with no files matched by `include`; these cases never succeed silently.
414
+
415
+ TypeScript extraction reads the selected module's `tsconfig.json` or
416
+ `jsconfig.json`. JSONC comments/trailing commas, local or installed `extends`,
417
+ `compilerOptions.baseUrl`, and `compilerOptions.paths` are used for export
418
+ tracing and internal dependency relations, so aliases such as `@/*` resolve to
419
+ their source files.
420
+
421
+ In monorepos, make each package/subdirectory a module boundary. Register the
422
+ chosen package path with `context source add repo [YYYYMMDD] --module <module> --local <package-dir>` and
423
+ reference it with `source("<date>", "<module>")`.
268
424
  Do not use `include` to choose a
269
425
  package from a larger monorepo source.
270
426
 
271
- Use `context source inspect <source-name>` to list detected module/package
427
+ Use `context source inspect <date>/<module>` to list detected module/package
272
428
  boundaries before choosing the source. Use `context run <phase-id> --dry-run
273
429
  --format json` to check the resolved modules, file counts, symbol counts, and
274
430
  candidate estimate before writing `unapproved/entities.jsonl`. The dry-run
275
431
  preview also includes `knowledgeTree` and `knowledgePathExamples`, which show
276
432
  where approved Markdown will land after review apply.
433
+ Its module and total summaries distinguish `discoveredFiles`, `analyzedFiles`,
434
+ `skippedFiles`, `symbols`, and `relations`; modules with skipped files include
435
+ the reason, such as files not reachable from exports-mode entries.
277
436
 
278
437
  Phase id shape:
279
438
 
@@ -281,6 +440,43 @@ Phase id shape:
281
440
  extract:<source-name-or-repo>:codegraph
282
441
  ```
283
442
 
443
+ Codegraph extraction has two execution policies:
444
+
445
+ - `context run <phase-id>` is the Agent/user default. The first run sends every
446
+ code symbol to Review. Later runs preserve unchanged approved symbols and send
447
+ only `add`, `update`, and `remove` deltas to Review. If there is no delta, the
448
+ result returns `next_action.human_gate=false` and the Agent continues.
449
+ - `context run <phase-id> --auto-promote` is the explicit CI/CD path. It is valid
450
+ only for `phase.extract.ts` codegraph phases, applies deterministic code deltas
451
+ without Review, refreshes deterministic close when approved knowledge changed,
452
+ then runs project verification. Close or verification errors make the command
453
+ fail; JSON output reports applied/materialized/removed counts plus a `close`
454
+ state of `refreshed`, `current`, or `not-required`. Package build remains a
455
+ separate pipeline step; existing package outputs are reported stale.
456
+
457
+ This policy never auto-promotes architecture, business, decision, test, or
458
+ other semantic knowledge. Agents must follow the returned
459
+ `next_action.human_gate` instead of assuming every extraction requires Review.
460
+
461
+ Approved codegraph sections use the local evidence form
462
+ `src-N#symbol:<file>:<symbol>:<kind>@<digest>`. The file segment makes reverse
463
+ lookup exact when multiple files contain the same symbol name, kind, and digest;
464
+ the complete ref remains opaque to agents. New pages keep only top-level
465
+ `candidate_fingerprint` and do not emit `code_origin`.
466
+
467
+ Projects created by the beta.5 protocol can upgrade approved pages without a
468
+ second human decision. Rerun every declared codegraph extraction phase to write
469
+ the current file-aware symbol index, then run:
470
+
471
+ ```bash
472
+ context review migrate-codegraph-refs
473
+ context verify
474
+ ```
475
+
476
+ Migration resolves each legacy ref against the trusted index and its existing
477
+ origin metadata, removes `code_origin`, preserves the approved body and review
478
+ state, and rolls back all page writes if final verification fails.
479
+
284
480
  ### `reviewValidity`
285
481
 
286
482
  Declare the review step for a collection:
@@ -304,10 +500,16 @@ review:all:validity
304
500
 
305
501
  The review HTML and apply flow are CLI-owned.
306
502
 
307
- This phase marks a human review gate. Agents should open `context review html
308
- <collection> --open` or `context review html --all --open` and wait for the
309
- user-copied payload; they should not run the phase as an automatic approval step
310
- or synthesize a payload themselves.
503
+ This phase marks a human review gate when current candidates exist. Agents
504
+ should run `context review html <collection> --open --format json` or `context
505
+ review html --all --open --format json`, confirm the returned `opened` field,
506
+ and wait for the user-copied payload. They should not run the phase as an
507
+ automatic approval step or synthesize a payload themselves.
508
+
509
+ The gate is batch-scoped: prose waits for every planned View in the confirmed
510
+ structure, and codegraph waits for every pending extract phase in the confirmed
511
+ module round. Candidate count/hash therefore describes the complete current
512
+ batch rather than one page or module.
311
513
 
312
514
  If the user explicitly asks for an automated or quick approval/rejection path,
313
515
  use the scoped quick commands instead of hand-writing a payload:
@@ -326,9 +528,9 @@ default human review gate.
326
528
  Use only when the typed factories cannot express a project-specific workflow:
327
529
 
328
530
  ```ts
329
- const sample = source("sample");
531
+ const sample = source("20260712", "sample");
330
532
 
331
- customPhase("custom:sample:review", async (ctx) => {
533
+ customPhase("custom:20260712/sample:review", async (ctx) => {
332
534
  await ctx.ensureSources({ source: sample });
333
535
  await ctx.extract.ts(extractTs({ source: sample, collection: "codegraph" }));
334
536
  await ctx.review.html(reviewValidity({ collection: "codegraph" }));
package/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export type { CodegraphCollection, DocumentMainlineCollection, EntityStatus, Kno
5
5
  export { assertDocumentMainlineCollection, assertKnowledgeCollection, assertMainlineCollection, assertOkfRoot, assertTopLevelNamespace, DOC_MAINLINE_COLLECTIONS, KNOWLEDGE_COLLECTIONS, MAINLINE_COLLECTIONS, OKF_ROOTS, TOP_LEVEL_NAMESPACES, } from "./contracts.js";
6
6
  export { assertDocumentEvidenceSectionMetadata, DOCUMENT_COMPILE_ACTION_SCHEMA_VERSION, DOCUMENT_EVIDENCE_SECTION_VALIDATION_STAGES, DOCUMENT_SECTION_CONTENT_MODES, DOCUMENT_STRUCTURE_SCHEMA_VERSION, } from "./documentEvidence.js";
7
7
  export type { DocumentEvidenceSectionMetadata, DocumentEvidenceSectionValidationOptions, DocumentEvidenceSectionValidationStage, DocumentSectionContentMode, } from "./documentEvidence.js";
8
- export { alignProse, captureFile, captureLark, compileProse, customPhase, extractTs, mdxJsonDocs, reviewValidity, } from "./phases.js";
8
+ export { alignProse, captureFile, captureLark, compileProse, customPhase, extractTs, ExtractTsConfigurationError, NO_ENTRY_DETECTED, mdxJsonDocs, reviewValidity, } from "./phases.js";
9
9
  export type { AlignProsePhaseDefinition, CaptureFilePhaseDefinition, CaptureLarkPhaseDefinition, CompileProsePhaseDefinition, ContextPhase, ContextPhaseContext, CustomPhaseDefinition, ExtractTsPhaseDefinition, PhaseDefinition, PhaseResourceReference, ReviewValidityPhaseDefinition, ReviewValidityScope, } from "./phases.js";
10
10
  export { allSources, DEFAULT_FILE_SOURCES_REGISTRY_PATH, DEFAULT_LARK_SOURCES_REGISTRY_PATH, DEFAULT_REPO_SOURCES_REGISTRY_PATH, loadSourcesRegistry, resolveSourceReference, source, } from "./sources.js";
11
11
  export type { DocumentSourceDefinition, DocumentSourceReference, DocumentSourceType, FileSourceDefinition, FileSourceReference, FileSourceRegistryEntry, LarkSourceDefinition, LarkSourceReference, LarkSourceRegistryEntry, LoadSourcesRegistryOptions, ProjectSourceDefinition, RepoProjectSourceDefinition, RepoSourceDefinition, RepoSourceReference, RepoSourceRegistryEntry, RepoSourcesRegistry, SourceCollectionReference, SourceDefinition, SourceReference, SourcesRegistry, SourceType, } from "./sources.js";