@c4a/context 0.7.20 → 0.7.25
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/docs/guides/knowledge-updates.md +5 -1
- package/docs/guides/workspace-prepare.md +4 -0
- package/docs/guides/workspace-restore.md +5 -1
- package/package.json +1 -1
- package/templates/package-templates/kb/skills/knowledge-query/SKILL.md +6 -4
- package/templates/package-templates/kb/skills/knowledge-query/scripts/search.mjs +19 -6
- package/templates/package-templates.zh-CN/kb/skills/knowledge-query/SKILL.md +2 -2
- package/templates/package-templates.zh-CN/kb/skills/knowledge-query/scripts/search.mjs +19 -6
|
@@ -217,7 +217,7 @@ In the work-start report or current plan, briefly state the affected articles'
|
|
|
217
217
|
intended placements and reused category intent. For proposed top-level additions,
|
|
218
218
|
renames, removals or changes of purpose, show the before/after tree, why reuse is
|
|
219
219
|
insufficient, affected existing pages and reading order. Present that change for
|
|
220
|
-
human review before applying it. This uses the existing report feedback where
|
|
220
|
+
human review under `context.gate.top_level_directory` before applying it. This uses the existing report feedback where
|
|
221
221
|
available; do not add a new CLI state, schema field or routine per-article gate.
|
|
222
222
|
Explicit user approval of that concrete structure is sufficient; do not ask again.
|
|
223
223
|
General permission to write knowledge or organize batches is not approval to
|
|
@@ -587,6 +587,10 @@ before delivery; inspect both new content and the old articles' disposition.
|
|
|
587
587
|
|
|
588
588
|
Preview approved-page retirement with `context task retire --input <file> --format json`:
|
|
589
589
|
|
|
590
|
+
This standalone retirement does not enter the article HTML Review. Apply
|
|
591
|
+
`context.gate.deletion_scope` to its target list; an already approved deletion
|
|
592
|
+
needs no second confirmation after the preview.
|
|
593
|
+
|
|
590
594
|
```yaml
|
|
591
595
|
reason: These reader tasks are now covered by the approved guide.
|
|
592
596
|
targets:
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Prepare a workspace for the next task
|
|
2
2
|
|
|
3
|
+
Agent policy: `context.gate.workspace_reset_restore`. A clear request to
|
|
4
|
+
prepare this workspace authorizes the described task-state cleanup; clarify
|
|
5
|
+
only an unresolved target or loss.
|
|
6
|
+
|
|
3
7
|
Use only for an explicit workspace preparation request. The goal is usable
|
|
4
8
|
registered sources and no unfinished task, while retaining approved knowledge
|
|
5
9
|
and configuration. Lead with Host tools and actual observations; do not start
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Restore a historical workspace version
|
|
2
2
|
|
|
3
|
+
Agent policy: `context.gate.workspace_reset_restore`. An explicit restore
|
|
4
|
+
request needs no second approval when the target and affected files are clear.
|
|
5
|
+
|
|
3
6
|
Use the Agent's Git and environment tools. This restores selected workspace
|
|
4
7
|
files and usable sources; it does not reset the entire repository, rewind source
|
|
5
8
|
repositories, or restore ignored runtime progress.
|
|
@@ -19,7 +22,8 @@ Compare target files with current tracked, untracked and staged files. Include
|
|
|
19
22
|
current additions absent at the target in the proposed removal scope. Keep
|
|
20
23
|
unrelated files, existing staged work and ignored source checkouts. Account for
|
|
21
24
|
workspace moves or renames instead of treating a missing old path as an empty
|
|
22
|
-
version. Reuse explicit authorization;
|
|
25
|
+
version. Reuse explicit authorization; clarify an unresolved target or loss
|
|
26
|
+
before acting rather than asking for a second approval of the same request.
|
|
23
27
|
|
|
24
28
|
## Restore files and environment
|
|
25
29
|
|
package/package.json
CHANGED
|
@@ -81,9 +81,10 @@ phrases, or several large indexes, run the bundled
|
|
|
81
81
|
node <current knowledge-query Skill directory>/scripts/search.mjs --query '<terms>' --limit 8
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
The script locates `{{packageName}}` when it runs inside the package tree.
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
The script locates `{{packageName}}` when it runs inside the package tree. It accepts
|
|
85
|
+
the build inventory at the package root or its distributed copy under
|
|
86
|
+
`others/context/`. If a package manager copied this Skill elsewhere, add
|
|
87
|
+
`--root <package directory>`, or use `--base <package collection>`
|
|
87
88
|
to locate this package by its inventory name. It chunks Markdown mechanically
|
|
88
89
|
by headings and bounded line ranges, then returns paths, line ranges, headings,
|
|
89
90
|
and previews; it does not interpret meaning.
|
|
@@ -138,7 +139,8 @@ explicitly accept the unchanged default during Context package-template review.
|
|
|
138
139
|
|
|
139
140
|
After answering from the pages actually read, optionally append one or more
|
|
140
141
|
related document links in the final summary. Read `context-site-map.json` from
|
|
141
|
-
the selected package
|
|
142
|
+
the selected package root, then `others/context/context-site-map.json`, or its
|
|
143
|
+
sibling website output in a workspace. Match the
|
|
142
144
|
read page to `pages[].package_path` or `approved_path`; use its `title` and resolve
|
|
143
145
|
`site_path` relative to `site_url`. The URL already includes the deployment base
|
|
144
146
|
path: do not prepend `base` again. Only cite matched articles, deduplicate links,
|
|
@@ -51,7 +51,14 @@ function parseArgs(argv) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function isPackageRoot(directory) {
|
|
54
|
-
return
|
|
54
|
+
return inventoryPath(directory) !== undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function inventoryPath(directory) {
|
|
58
|
+
return [
|
|
59
|
+
join(directory, "context-build-inventory.json"),
|
|
60
|
+
join(directory, "others", "context", "context-build-inventory.json"),
|
|
61
|
+
].find((path) => existsSync(path));
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
function ancestorPackageRoot(start) {
|
|
@@ -66,8 +73,8 @@ function ancestorPackageRoot(start) {
|
|
|
66
73
|
|
|
67
74
|
function findInventories(directory, depth = 0) {
|
|
68
75
|
if (!existsSync(directory) || depth > 5) return [];
|
|
69
|
-
const inventory =
|
|
70
|
-
if (
|
|
76
|
+
const inventory = inventoryPath(directory);
|
|
77
|
+
if (inventory !== undefined) return [inventory];
|
|
71
78
|
const matches = [];
|
|
72
79
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
73
80
|
if (!entry.isDirectory()) continue;
|
|
@@ -76,6 +83,12 @@ function findInventories(directory, depth = 0) {
|
|
|
76
83
|
return matches;
|
|
77
84
|
}
|
|
78
85
|
|
|
86
|
+
function packageRootFromInventory(inventory) {
|
|
87
|
+
return inventory.endsWith(join("others", "context", "context-build-inventory.json"))
|
|
88
|
+
? dirname(dirname(dirname(inventory)))
|
|
89
|
+
: dirname(inventory);
|
|
90
|
+
}
|
|
91
|
+
|
|
79
92
|
function inventoryPackageName(inventoryPath) {
|
|
80
93
|
try {
|
|
81
94
|
return JSON.parse(readFileSync(inventoryPath, "utf8"))?.package?.name;
|
|
@@ -99,7 +112,7 @@ function resolvePackageRoot(explicitRoot, packageCollection) {
|
|
|
99
112
|
}
|
|
100
113
|
const inventories = findInventories(resolve(packageCollection));
|
|
101
114
|
const matching = inventories.filter((path) => inventoryPackageName(path) === PACKAGE_NAME);
|
|
102
|
-
if (matching.length === 1) return
|
|
115
|
+
if (matching.length === 1) return packageRootFromInventory(matching[0]);
|
|
103
116
|
if (matching.length > 1) {
|
|
104
117
|
throw new Error(`multiple installed packages named ${PACKAGE_NAME}; pass --root explicitly`);
|
|
105
118
|
}
|
|
@@ -107,10 +120,10 @@ function resolvePackageRoot(explicitRoot, packageCollection) {
|
|
|
107
120
|
}
|
|
108
121
|
|
|
109
122
|
function knowledgeRoots(packageRoot) {
|
|
110
|
-
const
|
|
123
|
+
const packageInventoryPath = inventoryPath(packageRoot);
|
|
111
124
|
let declared = [];
|
|
112
125
|
try {
|
|
113
|
-
const inventory = JSON.parse(readFileSync(
|
|
126
|
+
const inventory = JSON.parse(readFileSync(packageInventoryPath, "utf8"));
|
|
114
127
|
declared = Object.values(inventory?.package?.distribution?.roots ?? {})
|
|
115
128
|
.filter((value) => typeof value === "string");
|
|
116
129
|
} catch {
|
|
@@ -60,7 +60,7 @@ description: 查询 {{displayName}} 中经过审核、可追溯来源的知识
|
|
|
60
60
|
node <当前 knowledge-query Skill 目录>/scripts/search.mjs --query '<关键词>' --limit 8
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
脚本位于知识包目录内时会自动定位 `{{packageName}}
|
|
63
|
+
脚本位于知识包目录内时会自动定位 `{{packageName}}`。它兼容包根的构建清单及 `others/context/` 下的分发副本。如果包管理工具将本 Skill 复制到了其他位置,增加 `--root <知识包目录>`;也可以使用 `--base <多包集合根目录>`,按构建清单中的包名定位。它按 Markdown 标题和固定行块机械切分,返回路径、行号、标题和短预览,不判断内容语义。
|
|
64
64
|
|
|
65
65
|
搜索命中只是线索。回答前打开命中的页面和章节;关系或影响范围须引用实际说明该关系的正文,不能用 BM25 分数或文本共现代替。
|
|
66
66
|
|
|
@@ -101,7 +101,7 @@ node <当前 knowledge-query Skill 目录>/scripts/search.mjs --query '<关键
|
|
|
101
101
|
## 总结中的网站文档链接
|
|
102
102
|
|
|
103
103
|
完成正文检索和回答后,仅在最终总结中按需附上一篇或多篇实际读取过的相关文档链接。
|
|
104
|
-
|
|
104
|
+
依次从当前知识包根、`others/context/context-site-map.json` 或工作区网站输出读取站点映射,按命中文章的包内路径匹配
|
|
105
105
|
`pages[].package_path`,使用 `title` 作链接文字,将 `site_path` 相对
|
|
106
106
|
`site_url` 拼接。`site_url` 已包含站点子路径,不再重复拼接 `base`。
|
|
107
107
|
同一文章只列一次,不凭标题推测页面地址或章节锚点。
|
|
@@ -51,7 +51,14 @@ function parseArgs(argv) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function isPackageRoot(directory) {
|
|
54
|
-
return
|
|
54
|
+
return inventoryPath(directory) !== undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function inventoryPath(directory) {
|
|
58
|
+
return [
|
|
59
|
+
join(directory, "context-build-inventory.json"),
|
|
60
|
+
join(directory, "others", "context", "context-build-inventory.json"),
|
|
61
|
+
].find((path) => existsSync(path));
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
function ancestorPackageRoot(start) {
|
|
@@ -66,8 +73,8 @@ function ancestorPackageRoot(start) {
|
|
|
66
73
|
|
|
67
74
|
function findInventories(directory, depth = 0) {
|
|
68
75
|
if (!existsSync(directory) || depth > 5) return [];
|
|
69
|
-
const inventory =
|
|
70
|
-
if (
|
|
76
|
+
const inventory = inventoryPath(directory);
|
|
77
|
+
if (inventory !== undefined) return [inventory];
|
|
71
78
|
const matches = [];
|
|
72
79
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
73
80
|
if (!entry.isDirectory()) continue;
|
|
@@ -76,6 +83,12 @@ function findInventories(directory, depth = 0) {
|
|
|
76
83
|
return matches;
|
|
77
84
|
}
|
|
78
85
|
|
|
86
|
+
function packageRootFromInventory(inventory) {
|
|
87
|
+
return inventory.endsWith(join("others", "context", "context-build-inventory.json"))
|
|
88
|
+
? dirname(dirname(dirname(inventory)))
|
|
89
|
+
: dirname(inventory);
|
|
90
|
+
}
|
|
91
|
+
|
|
79
92
|
function inventoryPackageName(inventoryPath) {
|
|
80
93
|
try {
|
|
81
94
|
return JSON.parse(readFileSync(inventoryPath, "utf8"))?.package?.name;
|
|
@@ -99,7 +112,7 @@ function resolvePackageRoot(explicitRoot, packageCollection) {
|
|
|
99
112
|
}
|
|
100
113
|
const inventories = findInventories(resolve(packageCollection));
|
|
101
114
|
const matching = inventories.filter((path) => inventoryPackageName(path) === PACKAGE_NAME);
|
|
102
|
-
if (matching.length === 1) return
|
|
115
|
+
if (matching.length === 1) return packageRootFromInventory(matching[0]);
|
|
103
116
|
if (matching.length > 1) {
|
|
104
117
|
throw new Error(`multiple installed packages named ${PACKAGE_NAME}; pass --root explicitly`);
|
|
105
118
|
}
|
|
@@ -107,10 +120,10 @@ function resolvePackageRoot(explicitRoot, packageCollection) {
|
|
|
107
120
|
}
|
|
108
121
|
|
|
109
122
|
function knowledgeRoots(packageRoot) {
|
|
110
|
-
const
|
|
123
|
+
const packageInventoryPath = inventoryPath(packageRoot);
|
|
111
124
|
let declared = [];
|
|
112
125
|
try {
|
|
113
|
-
const inventory = JSON.parse(readFileSync(
|
|
126
|
+
const inventory = JSON.parse(readFileSync(packageInventoryPath, "utf8"));
|
|
114
127
|
declared = Object.values(inventory?.package?.distribution?.roots ?? {})
|
|
115
128
|
.filter((value) => typeof value === "string");
|
|
116
129
|
} catch {
|