@c4a/extract 0.7.1 → 0.7.5

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 CHANGED
@@ -14,13 +14,12 @@ knowledge through the normal lifecycle.
14
14
 
15
15
  ## Package Role
16
16
 
17
- `@c4a/extract` is the protocol and runner layer used by declared Context
18
- project extraction phases such as `extractTs({ source, collection: "codegraph" })`.
17
+ `@c4a/extract` is the protocol and runner layer used by Code Indexer Providers.
19
18
 
20
19
  - Language plugins implement `ExtractionPlugin` and return `ExtractionResult` v2.
21
20
  - The runner loads one or more plugins, scans repository modules, emits progress/module-error/summary events, and can build an optional low-level code snapshot payload.
22
- - `@c4a/context-cli` invokes the runner from `context run extract:<source>:codegraph` after the workspace declares an `extractTs` phase.
23
- - The project flow stages review candidates under `.tmp/context-runtime/lifecycle/candidates.jsonl` and keeps runtime candidate artifacts under `.tmp/context-runtime/extract/`; approved Markdown is written only by review/apply.
21
+ - The selected Provider invokes the runner through the controlled Indexer workset and returns typed facts and artifacts.
22
+ - Context stages Candidate state under `.tmp/context-runtime/`; approved Markdown is written only by Review apply and close.
24
23
 
25
24
  **Depends on:** `@c4a/core`, `web-tree-sitter`, `zod`
26
25
 
@@ -31,12 +30,12 @@ language plugins + repository runner
31
30
 
32
31
  versioned raw code snapshot
33
32
 
34
- Context candidatesreview → approved knowledge
33
+ Indexer factsreader-oriented Candidates → approved knowledge
35
34
  ```
36
35
 
37
36
  Knowledge-workspace users normally reach this package through the installed
38
- Agent entry and a declared extraction phase. The runner protocol below is for
39
- extractor authors, Context maintainers, and project-owned adapters.
37
+ Agent entry and selected Code Indexer Provider. The runner protocol below is
38
+ for parser authors, Provider authors, and Context maintainers.
40
39
 
41
40
  ## Protocol Layers
42
41
 
@@ -108,10 +107,9 @@ Every plugin returns:
108
107
 
109
108
  ### 3. Repository Runner Protocol
110
109
 
111
- The package exposes `c4a-extract-code`, a low-level NDJSON runner. The current
112
- Context project flow normally reaches it through a declared `extractTs` phase
113
- and `context run extract:<source>:codegraph`; agents should not hand-build runner
114
- input for normal workspace operation.
110
+ The package exposes `c4a-extract-code`, a low-level NDJSON runner. Code Indexer
111
+ Providers may invoke it as an implementation detail; agents should not
112
+ hand-build runner input for normal workspace operation.
115
113
 
116
114
  Input is JSON on stdin:
117
115
 
@@ -192,9 +190,8 @@ Minimum requirements:
192
190
  5. Emit `SymbolInfo[]` with stable `name`, `kind`, `visibility`, `file`, `line`, and `endLine`.
193
191
  6. Emit `RelationInfo[]` for imports and important type/inheritance/use edges.
194
192
  7. Keep paths module-relative inside the plugin; the repository runner prefixes them to repo-relative paths.
195
- 8. Register the plugin in the runner input used by the project extraction
196
- phase. User-facing workspaces should declare the matching phase in
197
- `src/index.ts` and execute it through `context run <phase-id>`.
193
+ 8. Register the plugin in the Code Indexer Provider's runner configuration.
194
+ User-facing workspaces select the Provider through `src/indexers.yaml`.
198
195
 
199
196
  Example skeleton:
200
197
 
@@ -229,31 +226,30 @@ export class PythonPlugin implements ExtractionPlugin {
229
226
  }
230
227
  ```
231
228
 
232
- ## Relationship to Context Project Extraction
229
+ ## Relationship to the Code Indexer
233
230
 
234
- `@c4a/extract` is upstream of the Context project extraction phase; it does not
235
- render approved knowledge itself.
231
+ `@c4a/extract` is upstream of the Code Indexer Provider; it does not render
232
+ approved knowledge itself.
236
233
 
237
234
  - `context source add repo <name> --local <repo-or-subdir>` registers the code
238
235
  source boundary.
239
- - `src/index.ts` declares `extractTs({ source: source("<name>"), collection: "codegraph" })`.
240
- - `context run extract:<name>:codegraph --dry-run` previews resolved modules,
241
- candidate estimates, knowledge path examples, and module warnings.
242
- - `context run extract:<name>:codegraph` writes draft candidates for review. It
243
- uses `.tmp/context-runtime/extract/` for candidate snapshots, source
244
- fingerprints, and symbol indexes; that scratch directory is not committed
245
- state.
236
+ - `src/indexers.yaml` binds the source scope and reader requirements to a Code
237
+ Indexer Provider.
238
+ - The current Route prepares a controlled workset and the Provider returns the
239
+ current Indexer result.
240
+ - Context writes draft Candidates and recoverable runtime artifacts under
241
+ `.tmp/context-runtime/`; that directory is not committed state.
246
242
  - `context review html` and `context review apply` own human approval and
247
243
  approved Markdown materialization.
248
244
  - `context close`, `context verify`, and `context build` own final package
249
245
  readiness.
250
246
 
251
247
  That means language plugins affect published knowledge only through the current
252
- project flow: better symbols/relations produce better draft candidates, stable
248
+ Indexer flow: better symbols/relations produce better draft Candidates, stable
253
249
  `repo:<source>#symbol:...` source refs, review evidence, approved Markdown, and
254
250
  package output.
255
251
 
256
- Approved codegraph Markdown localizes canonical refs as
252
+ Approved code knowledge may localize canonical refs as
257
253
  `src-N#symbol:<file>:<symbol>:<kind>@<digest>`. The file segment is part of the
258
254
  deterministic evidence identity used by verification; agents copy the complete
259
255
  ref as an opaque token.
package/README.zh-CN.md CHANGED
@@ -7,8 +7,8 @@
7
7
  Tree-sitter 解析工具。
8
8
 
9
9
  它不判断代码对产品或读者意味着什么,也不写入正式知识。语言插件只输出结构事实;
10
- Context 运行时将这些事实绑定到来源身份、暂存审核候选,并通过标准生命周期应用
11
- 审核通过的知识。
10
+ Code Indexer Provider 将这些事实组织成当前 Indexer Result;Context 负责来源身份、
11
+ Candidate 状态和审核通过的知识。
12
12
 
13
13
  ## 在知识生产链中的职责
14
14
 
@@ -19,19 +19,19 @@ Context 运行时将这些事实绑定到来源身份、暂存审核候选,并
19
19
 
20
20
  版本化原始代码快照
21
21
 
22
- Context 候选审核 → 正式知识
22
+ Indexer 事实面向读者的 Candidate → 正式知识
23
23
  ```
24
24
 
25
25
  - 语言 package 实现 `ExtractionPlugin` 并返回 `ExtractionResult` v2。
26
26
  - Runner 加载一个或多个插件,扫描仓库模块,输出 progress、module-error 和
27
27
  summary 事件,并可生成底层代码快照。
28
- - Context runtime 在知识项目声明提取阶段后调用 Runner。
29
- - 草稿候选和运行快照留在 `.tmp/context-runtime/`;只有 review apply 会写入正式
28
+ - 选中的 Code Indexer Provider 通过受控 workset 调用 Runner。
29
+ - Candidate 和运行快照留在 `.tmp/context-runtime/`;只有 Review apply/close 会写入正式
30
30
  Markdown。
31
31
 
32
- 知识工作区用户通常通过已安装的 Agent 入口和声明好的提取阶段使用本包,不需要
33
- 手工构造 Runner 输入。下面的协议主要面向提取器作者、Context 维护者和项目自有
34
- Adapter。
32
+ 知识工作区用户通常通过已安装的 Agent 入口和选中的 Code Indexer Provider 使用
33
+ 本包,不需要手工构造 Runner 输入。下面的协议主要面向解析器作者、Provider 作者
34
+ 和 Context 维护者。
35
35
 
36
36
  **依赖:** `@c4a/core`、`web-tree-sitter`、`zod`
37
37
 
@@ -99,8 +99,8 @@ denominator。
99
99
 
100
100
  ### 3. Repository Runner
101
101
 
102
- 包暴露底层 NDJSON Runner `c4a-extract-code`。正常知识工作区由当前 Route 和已声明
103
- 阶段调用它;Agent 不应手工生成 stdin Payload。
102
+ 包暴露底层 NDJSON Runner `c4a-extract-code`。Code Indexer Provider 可以把它作为
103
+ 实现细节调用;Agent 不应手工生成 stdin Payload。
104
104
 
105
105
  Runner 输出一行一个 JSON 对象:
106
106
 
@@ -148,20 +148,20 @@ Agent 将完整 `source_ref` 当作不透明 token 复制,不自行解析或
148
148
  5. 输出稳定的符号名、kind、visibility、文件和行范围;
149
149
  6. 输出导入、调用、类型、继承或使用关系;
150
150
  7. 插件内部保持 module-relative 路径,由 Runner 加上 repo-relative 前缀;
151
- 8. 在项目提取阶段的 Runner 配置中注册插件。
151
+ 8. Code Indexer Provider 的 Runner 配置中注册插件。
152
152
 
153
- ## 与 Context 项目提取的关系
153
+ ## 与 Code Indexer 的关系
154
154
 
155
- `@c4a/extract` 位于项目提取阶段上游,不渲染正式知识。典型流程是:
155
+ `@c4a/extract` 位于 Code Indexer Provider 上游,不渲染正式知识。典型流程是:
156
156
 
157
157
  1. 用户确认代码来源边界;
158
- 2. `src/index.ts` 声明相应提取阶段;
159
- 3. 当前 Route 先运行 dry-run,展示解析出的模块、候选数量和知识路径;
160
- 4. 正式提取生成待审候选和来源指纹;
158
+ 2. `src/indexers.yaml` 将来源范围和读者需求绑定到 Code Indexer Provider;
159
+ 3. 当前 Route 准备受控 workset,Provider 返回当前 Indexer Result;
160
+ 4. Context 生成待审 Candidate 和可恢复运行态;
161
161
  5. review apply 将批准内容写入正式知识;
162
162
  6. close、verify 和 build 完成本轮并生成知识包。
163
163
 
164
- 因此,更好的符号和关系会产生更可靠的候选、证据引用和知识包,但业务分类继续由
164
+ 因此,更好的符号和关系会产生更可靠的 Candidate、来源引用和知识包,但业务分类继续由
165
165
  Agent 与用户依据证据决定。
166
166
 
167
167
  ## 开发
@@ -13163,6 +13163,8 @@ function keyTokens(key) {
13163
13163
  return key.replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replace(/[^A-Za-z0-9]+/gu, "-").toLowerCase().split("-").filter(Boolean);
13164
13164
  }
13165
13165
  function sensitiveKey(key, value) {
13166
+ if (value === INDEXER_OUTPUT_REDACTION_MARKER)
13167
+ return false;
13166
13168
  const tokens = keyTokens(key);
13167
13169
  if (tokens.length === 0)
13168
13170
  return false;
@@ -13204,12 +13206,12 @@ function replaceWithCount(value, pattern, replacement, count) {
13204
13206
  function redactKnownText(value, count) {
13205
13207
  let output = value;
13206
13208
  output = replaceWithCount(output, /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/gu, INDEXER_OUTPUT_REDACTION_MARKER, count);
13207
- output = replaceWithCount(output, /(\bauthorization\s*:\s*(?:bearer|basic)\s+)[^\s,;]+/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
13209
+ output = replaceWithCount(output, new RegExp(`(\\bauthorization\\s*:\\s*(?:bearer|basic)\\s+)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^\\s,;]+`, "giu"), (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
13208
13210
  output = replaceWithCount(output, /([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}@`, count);
13209
- output = replaceWithCount(output, /([?&](?:access_token|refresh_token|api_key|password|secret)=)[^&#\s]+/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
13211
+ output = replaceWithCount(output, new RegExp(`([?&](?:access_token|refresh_token|api_key|password|secret)=)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^&#\\s]+`, "giu"), (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
13210
13212
  const key = "(?:[A-Za-z0-9_.-]*(?:password|passwd|pwd|secret|token|credential|cookie)[A-Za-z0-9_.-]*|api[-_]?key|access[-_]?(?:key|token)|private[-_]?key|client[-_]?secret|authorization)";
13211
13213
  const assignment = `(?:=\\s*|:\\s+(?=\\S)|:\\s*(?=["']))`;
13212
- output = replaceWithCount(output, new RegExp(`((?:["']?${key}["']?)\\s*${assignment})(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu"), (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
13214
+ output = replaceWithCount(output, new RegExp(`((?:["']?${key}["']?)\\s*${assignment})` + `(?!["']?${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})` + `(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu"), (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
13213
13215
  return output;
13214
13216
  }
13215
13217
  function redactBlockedText(value, blocked, count) {
@@ -14926,7 +14928,7 @@ function selectedEntryFiles(input) {
14926
14928
  for (const entry of input.detected.entries) {
14927
14929
  const sourcePath = input.module.path === "." ? safeSourceRelativePath(entry.path) : safeSourceRelativePath(`${input.module.path}/${entry.path}`);
14928
14930
  if (!includedSourceFiles.has(sourcePath)) {
14929
- throw new Error(`Auto-detected entry is outside extractTs include: ${sourcePath}. Update include or configure entries in the Context project.`);
14931
+ throw new Error(`Auto-detected entry is outside the parser include: ${sourcePath}. Update the Provider include or configured entries.`);
14930
14932
  }
14931
14933
  }
14932
14934
  return input.detected.entries;
@@ -14937,7 +14939,7 @@ function selectedEntryFiles(input) {
14937
14939
  }
14938
14940
  return sourceEntries.map((sourcePath, index) => {
14939
14941
  if (!includedSourceFiles.has(sourcePath)) {
14940
- throw new Error(`Configured extraction entry is missing or outside extractTs include: ${sourcePath}. Update entries or include in the Context project.`);
14942
+ throw new Error(`Configured extraction entry is missing or outside the parser include: ${sourcePath}. Update the Provider entries or include.`);
14941
14943
  }
14942
14944
  const modulePath = moduleRelativeEntryPath(input.module.path, sourcePath);
14943
14945
  return {