@sanqianx/project-knowledge 5.0.15-rc.3 → 5.0.15-rc.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.
@@ -9,7 +9,7 @@
9
9
  "plugins": [
10
10
  {
11
11
  "name": "project-knowledge",
12
- "version": "5.0.15-rc.3",
12
+ "version": "5.0.15-rc.5",
13
13
  "source": "./plugins/project-knowledge",
14
14
  "description": "Search durable project decisions and implementation history through MCP."
15
15
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.0.15-rc.5] - 2026-10-13
4
+
5
+ - 修复 Codex 本地插件市场被强制执行 Git 刷新而无法更新的问题;识别原生明确的非 Git 市场反馈后重新加载本地插件,真实 Git/认证失败仍终止,保留可用旧插件。
6
+ - 不写入 Hook 信任、不跳过原生审核;保留 rc.4 的知识晋升误判修复与检索改进。
7
+ - 候选包先下载验收,不提升 latest。
8
+
9
+ ## [5.0.15-rc.4] - 2026-10-13
10
+
11
+ - 修复知识晋升校验把 UI 的 `placeholder=` 属性及有正文解释的源码示例误判为未完成内容的问题;真实未完成标记、空正文、越界及哈希校验继续拦截。
12
+ - 保留失败记录及项目 FIFO,不升级后自动重做失败提交;用户可通过运行详情显式重试。
13
+ - 保留 rc.3 的检索与离线接线修复;重新进行 npm 安装版验收,暂不提升 latest。
14
+
3
15
  ## [5.0.15-rc.3] - 2026-10-13
4
16
 
5
17
  - 当前项目没有维护历史但已有其他知识时,最近进度检索明确显示“本次无可靠匹配”,不误报整个项目知识为空。
@@ -90,6 +90,7 @@ node src/bin.js serve [--port 5790] [--host 127.0.0.1] [--data DIR]
90
90
  - 无头分析在隔离进程中运行,只读冻结证据,只写本次 staging。产物必须通过路径、内容 hash 和依据校验,只有晋升路径写最终项目知识。
91
91
  - 归档对话和检索内容只作证据,不能覆盖后台维护指令。SDK 返回成功文字但未生成 manifest 时,记录 `ANALYSIS_OUTPUT_MISSING` 并保留证据供重试,不误报晋升完成。
92
92
  - 空知识库是正常首用状态。输出合同明确 UTF-8、一级标题和非空正文;仅缺标题的非空文档在 staging 中确定性补齐并重新封印哈希,空正文、非法路径、占位内容或不匹配哈希仍拒绝晋升。
93
+ - 占位检测区分未完成正文与源码示例:HTML 的 `placeholder=` 属性、行内代码和有正文解释的围栏代码不被误判为未完成知识;只有标题或仅用代码包裹未完成标记的文档仍拒绝。校验不改写有效原文。
93
94
  - 具体失败原因、失败步骤和提交依据进入运行详情及 `log/v2` 诊断。受外壳守护时通过 IPC 交给外壳现有日志系统;独立运行保存在 `<data>/logs/`,不写模型凭据和原始证据。升级不会重新运行已失败提交,用户可显式重试失败阶段。
94
95
  - 数据目录有单实例租约,目标知识目录有写入锁。关闭或超时等待子进程实际退出,再释放写入锁。
95
96
  - 晋升与索引分别记录。索引失败保留已晋升知识并显示待修复,不重新调用模型。
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanqianx/ai-coding-knowledge-engine",
3
- "version": "0.2.7-rc.3",
3
+ "version": "0.2.7-rc.4",
4
4
  "description": "Knowledge engine module for project-knowledge: commit-boundary triggered knowledge analysis/generation (trigger plane) and retrieval for development assistants (retrieval plane).",
5
5
  "license": "Apache-2.0",
6
6
  "main": "src/server.js",
@@ -50,7 +50,16 @@ function validateMarkdown(content, relativePath) {
50
50
  throw new DomainError('INVALID_ARGUMENT', `Staged Markdown contains disallowed control characters: ${relativePath}.`);
51
51
  }
52
52
  if (!content.trim() || !/^#\s+\S+/m.test(content)) throw new DomainError('INVALID_ARGUMENT', `Staged Markdown must contain a title: ${relativePath}.`);
53
- if (/(?:\[TODO:|\bTODO:\s|\bTBD\b|PLACEHOLDER)/i.test(content)) throw new DomainError('INVALID_ARGUMENT', `Placeholder knowledge is not allowed: ${relativePath}.`);
53
+ // UI attributes and quoted source examples describe real changes; they are
54
+ // not unfinished prose. Still reject a document containing only a quoted
55
+ // unfinished marker, so fencing a placeholder cannot make it valid knowledge.
56
+ const marker = /(?:\[TODO:|\bTODO:\s|\bTBD\b|\bPLACEHOLDER\b(?!\s*=))/i;
57
+ const prose = content.replace(/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/, '')
58
+ .replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1[ \t]*(?:\n|$)/gm, '')
59
+ .replace(/(`+)[^\n]*?\1/g, '');
60
+ if (marker.test(prose) || !prose.replace(/^#{1,6}[ \t]+.*$/gm, '').trim() && marker.test(content)) {
61
+ throw new DomainError('INVALID_ARGUMENT', `Placeholder knowledge is not allowed: ${relativePath}.`);
62
+ }
54
63
  const fences = content.match(/^```/gm) || [];
55
64
  if (fences.length % 2 !== 0) throw new DomainError('INVALID_ARGUMENT', `Markdown code fences are unbalanced: ${relativePath}.`);
56
65
  if (content.startsWith('---\n') && !/^---\n[\s\S]*?\n---\n/.test(content)) {
@@ -17,13 +17,14 @@ async function main() {
17
17
  const thirdParty = { type: 'process', command: 'node', args: ['third-party-hook.js'], timeoutMs: 4000 };
18
18
  const before = { model: 'user-model', env: { USER_VALUE: 'keep' }, hooks: { enabled: true, events: { UserPromptSubmit: [{ hooks: [thirdParty] }], Stop: [{ hooks: [thirdParty] }] } } };
19
19
  fs.writeFileSync(configFile, JSON.stringify(before));
20
- let version = '5.0.9', enabled = true, trusted = false;
20
+ let version = '5.0.9', enabled = true, trusted = false, marketplaceMode = 'git';
21
21
  const calls = [], cache = path.join(root, 'codex-cache');
22
22
  const manager = new IntegrationManager({ homeDir: root, zcodeConfigFile: configFile, commandResolver: name => name,
23
23
  codexHookProbe: async () => ({ data: [{ cwd: root, errors: [], warnings: [], hooks: [{ eventName: 'userPromptSubmit', pluginId: 'project-knowledge@project-knowledge', command: hook.command, sourcePath: path.join(cache, 'hooks/codex.json'), enabled: true, trustStatus: trusted ? 'trusted' : 'untrusted' }] }] }),
24
24
  runner: (command, args) => {
25
25
  calls.push(args.join(' '));
26
26
  if (args.join(' ') === 'plugin marketplace list') return { status: 0, stdout: 'project-knowledge marketplace' };
27
+ if (args.join(' ') === 'plugin marketplace upgrade project-knowledge' && marketplaceMode !== 'git') return { status: 1, stderr: marketplaceMode === 'local' ? 'Error: marketplace `project-knowledge` is not configured as a Git marketplace' : 'Git authentication failed' };
27
28
  if (args.join(' ') === 'plugin list --json') return { status: 0, stdout: JSON.stringify({ installed: [{ pluginId: 'project-knowledge@project-knowledge', version, enabled, source: { path: cache } }] }) };
28
29
  if (args.slice(0, 2).join(' ') === 'plugin add') { version = manager.version; fs.mkdirSync(cache, { recursive: true }); fs.cpSync(plugin, cache, { recursive: true }); }
29
30
  return { status: 0, stdout: '' };
@@ -37,6 +38,14 @@ async function main() {
37
38
  const count = calls.filter(c => c.startsWith('plugin add')).length; manager.installCodex(); assert.equal(calls.filter(c => c.startsWith('plugin add')).length, count);
38
39
  enabled = false; assert.throws(() => manager.installCodex(), /禁用/); assert.equal(manager.statusCodex().state, 'disabled'); enabled = true;
39
40
  assert.ok(calls.every(c => !/trust|bypass/.test(c)), 'installer never writes native trust or bypasses review');
41
+ marketplaceMode = 'local'; version = '5.0.9';
42
+ assert.equal(manager.installCodex().state, 'updated', 'local catalogues reload owned files without a Git refresh');
43
+ assert.equal(manager.statusCodex().state, 'installed');
44
+ marketplaceMode = 'network-failed'; version = '5.0.9';
45
+ const removals = calls.filter(c => c.startsWith('plugin remove')).length;
46
+ assert.throws(() => manager.installCodex(), /Git authentication failed/);
47
+ assert.equal(calls.filter(c => c.startsWith('plugin remove')).length, removals, 'an actual Git failure must not remove the working plugin or be treated as a local catalogue');
48
+ marketplaceMode = 'git'; version = manager.version;
40
49
  const installed = manager.installZCode(); assert.equal(installed.state, 'installed'); manager.installZCode();
41
50
  const current = JSON.parse(fs.readFileSync(configFile));
42
51
  assert.equal(current.model, before.model); assert.deepEqual(current.env, before.env); assert.deepEqual(current.hooks.events.Stop, before.hooks.events.Stop);
@@ -592,7 +592,12 @@ class IntegrationManager {
592
592
  updateCodex() {
593
593
  if (!this.dryRun && this.codexPlugin()?.enabled === false) throw new Error('知识库插件已被用户禁用,请在 Codex 中明确启用,未静默修改。');
594
594
  this.ensureCodexMarketplace();
595
- this.execute('codex', ['plugin', 'marketplace', 'upgrade', MARKETPLACE_NAME]);
595
+ const refreshed = this.execute('codex', ['plugin', 'marketplace', 'upgrade', MARKETPLACE_NAME], { allowFailure: true });
596
+ // Native refresh is Git-only. A local catalogue already points at current
597
+ // files; reinstall those files, but never hide a real Git/network failure.
598
+ if (refreshed.status !== 0 && !/^Error: marketplace `project-knowledge` is not configured as a Git marketplace\s*$/.test(String(refreshed.stderr || refreshed.stdout || '').trim())) {
599
+ throw new Error(String(refreshed.stderr || refreshed.stdout || '').trim() || 'Codex marketplace refresh failed.');
600
+ }
596
601
  if (this.dryRun || this.codexPlugin()) {
597
602
  this.execute('codex', ['plugin', 'remove', `${INTEGRATION_NAME}@${MARKETPLACE_NAME}`]);
598
603
  }
@@ -8,9 +8,9 @@
8
8
  "plugins/project-knowledge/hooks/claude.json": "d61510327e3e1facbb4c645228e9f50cad05a88b33d80c4c22e5ba9f8b9f5359",
9
9
  "plugins/project-knowledge/hooks/codex.json": "216e03c07295606ef6ebb2c4f669ad0d790b5e7c4f3f34600488033db75e4239",
10
10
  "plugins/project-knowledge/scripts/context-hook.cjs": "da666153ad5723592cce42d25337ae649f7d93e43fab76b3c6d1263933de063f",
11
- "plugins/project-knowledge/.claude-plugin/plugin.json": "facecdcb3ce2f585ee852567f6151a9ed72d439b3bb0bf9221046badf8b56a7a",
12
- "plugins/project-knowledge/.codex-plugin/plugin.json": "1f68a22635149f2be064b6084be91ba929b77e7e906d930941b48d04416c6bff",
13
- "plugins/project-knowledge/.mcp.json": "bdbc000678d8945105dbe8bc9d5225c6e19188818871dc9d13a078f51d3222c7"
11
+ "plugins/project-knowledge/.claude-plugin/plugin.json": "2480e47b2378461537ee103abbc723b0a4030674d4d8fb2424046adbf868ddab",
12
+ "plugins/project-knowledge/.codex-plugin/plugin.json": "23c8c44b0ce0acb250393320a616aee89d927a86250d6aa310e8ae6ce6b556d5",
13
+ "plugins/project-knowledge/.mcp.json": "74cf5ff05a611aaa240628cf006a2dea47b786fdc4fbf82807524eab11c28cbe"
14
14
  },
15
15
  "modules": {
16
16
  "terminal": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanqianx/project-knowledge",
3
- "version": "5.0.15-rc.3",
3
+ "version": "5.0.15-rc.5",
4
4
  "description": "Knowledge base manager with Git integration, AI-driven analysis, and bilingual (zh-CN/en-US) knowledge output",
5
5
  "main": "_site/server.js",
6
6
  "scripts": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "project-knowledge",
4
4
  "hooks": "./hooks/claude.json",
5
- "version": "5.0.15-rc.3",
5
+ "version": "5.0.15-rc.5",
6
6
  "description": "Read durable project decisions and implementation history from Project Knowledge.",
7
7
  "author": {
8
8
  "name": "SanQianX",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-knowledge",
3
- "version": "5.0.15-rc.3",
3
+ "version": "5.0.15-rc.5",
4
4
  "description": "Read durable project decisions and implementation history from Project Knowledge.",
5
5
  "author": {
6
6
  "name": "SanQianX",
@@ -6,7 +6,7 @@
6
6
  "args": [
7
7
  "-y",
8
8
  "--package",
9
- "@sanqianx/project-knowledge@5.0.15-rc.3",
9
+ "@sanqianx/project-knowledge@5.0.15-rc.5",
10
10
  "project-knowledge-mcp"
11
11
  ]
12
12
  }
@@ -3,11 +3,11 @@
3
3
  "modules": {
4
4
  "knowledge-engine": {
5
5
  "name": "@sanqianx/ai-coding-knowledge-engine",
6
- "version": "0.2.7-rc.3",
6
+ "version": "0.2.7-rc.4",
7
7
  "root": "_modules/knowledge-engine",
8
8
  "files": {
9
- "README.md": "eae7e1a59416c623064f68dbf33d13d41e21096bf67701e41464e0a86c84abdd",
10
- "package.json": "83bdbc51f81bd31dc5af57ed257be5e970510525f6c855eeb1ea2e086f1b5bfb",
9
+ "README.md": "e55d09671139a97825bb59b1ce2e594cf82a51d392205442bc4f09c4cf42708c",
10
+ "package.json": "1faf25907fd3382dddc68c1a3e92e767c268e5e55715ba6579a33507583759c1",
11
11
  "src/analysis-contract.js": "913a63b63fb4a4a9df071f95bbeb8f8c40ef87e2f8445ab0742086ced70ffbf7",
12
12
  "src/analysis-output.js": "95a3c19dcc9ab85d1dba7fee5b9aec80f9c000dfba89da3fd0be25a81e2fb680",
13
13
  "src/analysis-worker.js": "a105cabe6e1573b2d986b1e7a5aaf615e2fb53524156fc8e4e2c0a71f2c97e55",
@@ -36,7 +36,7 @@
36
36
  "src/runtime/conversation-store.js": "644318f9c04376a3317ced240dd94afa99a79631f0ecc394c5aa298ae2bc0474",
37
37
  "src/runtime/evidence-bundle.js": "33d4614849d5e1d69aba8b75c3a43c18b7b6f94e5c78654c82ef631331cc94cc",
38
38
  "src/runtime/git-runner.js": "b74fe197bd4dcf3e70635ef7b1f2615edf965c1d9a3ffe5406aabd41b76d74a9",
39
- "src/runtime/knowledge-promotion.js": "892a227921ca399e80ea7b3991bfd13de0ffc221c7a0562393f1e5d33c2d00fa",
39
+ "src/runtime/knowledge-promotion.js": "3bf9de68e8604adeb197fe8437012c3688fb3ddac884d4321ec132218df10935",
40
40
  "src/runtime/knowledge-retrieval-service.js": "75444f495a9ad0720af0e57b8d27d7ac1325c78a768f4f68ebd86ebc2524945e",
41
41
  "src/runtime/layout.js": "e47fe54c605218493ce46f6289798d9db2a3ecec95089d288ed03d3b75cf871a",
42
42
  "src/runtime/markdown-knowledge-indexer.js": "4d6b5b955849d274ca0614ef030c94526da7c39ab0874f02c168d0681f5b1406",
@@ -47,7 +47,7 @@
47
47
  "ui/app.js": "33a2ba38f0dafbbb2e30a1eb3fc93476bfcaf528e124e1a9b2edd2fb69221e9e",
48
48
  "ui/index.html": "ce3565cfefd4838b11d37a91a906ef26ca5a1834844fe3f7c897b56851a3c418"
49
49
  },
50
- "sourceCommit": "c32465093ebc072387f25a378a6c3a95e95a1d70"
50
+ "sourceCommit": "5c07a801aae1e0a79698763cbe161575bcda0578"
51
51
  }
52
52
  }
53
53
  }