@pzy560117/codex-harness 0.1.5 → 0.1.7

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
@@ -26,6 +26,8 @@ npm install -g @pzy560117/codex-harness
26
26
  harness
27
27
  ```
28
28
 
29
+ 执行 `harness init` 时如果发现 `%USERPROFILE%\\.codex\\packages\\codex-harness\\` 的用户级 package cache 缺失或版本落后,会先自动刷新这层共享缓存,再继续项目初始化。
30
+
29
31
  ## Quick Start
30
32
 
31
33
  ### 1. 初始化当前项目
@@ -37,6 +39,7 @@ harness init
37
39
  ```
38
40
 
39
41
  如果当前目录还不是 Git 仓库,CLI 会调用安装器并按默认策略初始化项目所需的 Harness runtime。
42
+ 如果用户级 package cache 版本落后,CLI 会先自动补齐 `install-user.ps1` 对应的共享缓存。
40
43
 
41
44
  ### 2. 运行 doctor
42
45
 
@@ -103,7 +106,7 @@ harness init --plan
103
106
  ### 钉住远程版本初始化
104
107
 
105
108
  ```powershell
106
- npx @pzy560117/codex-harness init --version 0.1.5
109
+ npx @pzy560117/codex-harness init --version 0.1.7
107
110
  ```
108
111
 
109
112
  适合 release smoke 或回滚到某个已发布版本。
@@ -9,7 +9,8 @@ import {
9
9
  getDownloadedShaPath,
10
10
  getDownloadedZipPath,
11
11
  getPackageInstallRoot,
12
- getReleaseAssetNames
12
+ getReleaseAssetNames,
13
+ getUserPackageLockPath
13
14
  } from "../release/cache-layout.js";
14
15
  import { downloadToFile, fileExists } from "../release/download-release.js";
15
16
  import { buildReleaseAssetUrl } from "../release/release-config.js";
@@ -27,6 +28,57 @@ function getCliPackageRoot() {
27
28
  return path.resolve(import.meta.dirname, "..", "..");
28
29
  }
29
30
 
31
+ async function readManifestVersion(packageRoot) {
32
+ const manifestPath = path.join(packageRoot, "install-manifest.json");
33
+ const manifestDocument = JSON.parse(await fs.readFile(manifestPath, "utf8"));
34
+ const version = typeof manifestDocument.version === "string" ? manifestDocument.version.trim() : "";
35
+ if (version === "") {
36
+ throw new Error(`install-manifest.json 缺少 version: ${manifestPath}`);
37
+ }
38
+
39
+ return version;
40
+ }
41
+
42
+ async function readInstalledUserCacheVersion(userProfile) {
43
+ const lockPath = getUserPackageLockPath(userProfile);
44
+ if (!fileExists(lockPath)) {
45
+ return "";
46
+ }
47
+
48
+ try {
49
+ const lockDocument = JSON.parse(await fs.readFile(lockPath, "utf8"));
50
+ return typeof lockDocument.version === "string" ? lockDocument.version.trim() : "";
51
+ } catch {
52
+ return "";
53
+ }
54
+ }
55
+
56
+ export function shouldRefreshUserPackageCache(expectedVersion, installedVersion, installRootExists) {
57
+ if (!installRootExists) {
58
+ return true;
59
+ }
60
+
61
+ return expectedVersion !== installedVersion;
62
+ }
63
+
64
+ async function ensureUserPackageCache(options) {
65
+ const expectedVersion = await readManifestVersion(options.packageRoot);
66
+ const installedVersion = await readInstalledUserCacheVersion(options.userProfile);
67
+ const expectedInstallRoot = getPackageInstallRoot(options.userProfile, expectedVersion);
68
+
69
+ if (!shouldRefreshUserPackageCache(expectedVersion, installedVersion, fileExists(expectedInstallRoot))) {
70
+ return;
71
+ }
72
+
73
+ const scriptPath = path.join(options.packageRoot, "tools", "install", "install-user.ps1");
74
+ process.stdout.write(`刷新用户级 codex-harness 缓存到 ${expectedVersion}...\n`);
75
+ const args = [];
76
+ if (options.force) {
77
+ args.push("-Force");
78
+ }
79
+ await invokePowerShellScript(scriptPath, args, { cwd: options.packageRoot });
80
+ }
81
+
30
82
  export async function initCommand(options) {
31
83
  const localPackageRoot = getLocalPackageRoot();
32
84
  const embeddedPackageRoot = path.join(getCliPackageRoot(), "package-source");
@@ -80,6 +132,14 @@ export async function initCommand(options) {
80
132
  effectivePackageRoot = packageInstallRoot;
81
133
  }
82
134
 
135
+ if (!options.plan) {
136
+ await ensureUserPackageCache({
137
+ packageRoot: effectivePackageRoot,
138
+ userProfile,
139
+ force: options.force
140
+ });
141
+ }
142
+
83
143
  const scriptPath = path.join(effectivePackageRoot, "tools", "install", "install-agent.ps1");
84
144
  const args = ["-ProjectRoot", projectRoot];
85
145
 
@@ -1,13 +1,25 @@
1
1
  export const RELEASE_SOURCE_ENTRIES = [
2
- "AGENTS.md",
3
- "README.md",
4
- "PACKAGE.md",
5
- "install-manifest.json",
6
- "install-manifest.schema.json",
7
- "tools/install",
8
- "docs/codex-harness-engineering/templates"
2
+ { source: "AGENTS.md", destination: "AGENTS.md" },
3
+ {
4
+ source: "docs/codex-harness-engineering/templates/package-assets/root/README.md",
5
+ destination: "README.md"
6
+ },
7
+ {
8
+ source: "docs/codex-harness-engineering/templates/package-assets/root/PACKAGE.md",
9
+ destination: "PACKAGE.md"
10
+ },
11
+ { source: "install-manifest.json", destination: "install-manifest.json" },
12
+ {
13
+ source: "install-manifest.schema.json",
14
+ destination: "install-manifest.schema.json"
15
+ },
16
+ { source: "tools/install", destination: "tools/install" },
17
+ {
18
+ source: "docs/codex-harness-engineering/templates",
19
+ destination: "docs/codex-harness-engineering/templates"
20
+ }
9
21
  ];
10
22
 
11
23
  export function shouldIncludeReleaseSource(relativePath) {
12
- return RELEASE_SOURCE_ENTRIES.includes(relativePath);
24
+ return RELEASE_SOURCE_ENTRIES.some((entry) => entry.source === relativePath || entry.destination === relativePath);
13
25
  }
@@ -25,19 +25,19 @@ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agen
25
25
  显式 thin project:
26
26
 
27
27
  ```powershell
28
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agent.ps1 -ProjectRoot . -Scope project
28
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\\install/install-agent.ps1 -ProjectRoot . -Scope project
29
29
  ```
30
30
 
31
31
  显式 legacy full:
32
32
 
33
33
  ```powershell
34
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agent.ps1 -ProjectRoot . -Mode full -Force
34
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\\install/install-agent.ps1 -ProjectRoot . -Mode full -Force
35
35
  ```
36
36
 
37
37
  显式 vendor:
38
38
 
39
39
  ```powershell
40
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agent.ps1 -ProjectRoot . -Scope vendor
40
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\\install/install-agent.ps1 -ProjectRoot . -Scope vendor
41
41
  ```
42
42
 
43
43
  ## Smoke
@@ -4,34 +4,9 @@
4
4
 
5
5
  SpecKit 相关 `.specify/`、`workflows/speckit.*` 和 `speckit-*` skills 仍随 full 包安装,但它们用于需求、计划和任务输入生成;方案确认后应转入 `task.json`,再交给 full driver 执行。
6
6
 
7
- ## 云端 CLI 安装
7
+ ## 安装
8
8
 
9
- 全局安装:
10
-
11
- ```powershell
12
- npm install -g @pzy560117/codex-harness
13
- ```
14
-
15
- 一次性使用:
16
-
17
- ```powershell
18
- npx @pzy560117/codex-harness init
19
- ```
20
-
21
- 项目内常用命令:
22
-
23
- ```powershell
24
- harness init
25
- harness doctor
26
- harness verify
27
- harness run
28
- ```
29
-
30
- `harness init` 优先使用 npm 包内置的 `package-source/` 完成初始化;只有在 npm 包未携带内置 source 时,才回退到 GitHub Release 下载 package source 到 `%USERPROFILE%\.codex\packages\codex-harness\<version>\`。项目级 `.agents/skills/` 与 `.agents/workflows/` 仍只安装到当前项目,不会提升成全局 active surface。
31
-
32
- ## 本地源码安装
33
-
34
- 从包含 `agent/` 包目录的项目父目录运行:
9
+ 从包含 当前仓库包根目录的项目父目录运行:
35
10
 
36
11
  ```powershell
37
12
  powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agent-here.ps1 -InitGitIfNeeded
@@ -40,46 +15,38 @@ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agen
40
15
  从已安装的 `.agents/` 自更新:
41
16
 
42
17
  ```powershell
43
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\install\install-agent.ps1 -ProjectRoot . -Mode full -Force
18
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\\install/install-agent.ps1 -ProjectRoot . -Mode full -Force
44
19
  ```
45
20
 
46
21
  ## 安装产物
47
22
 
48
23
  - 项目根 `AGENTS.md`
49
- - `tools/harness/` 下的 `codex-loop.ps1`、`doctor.ps1`、`verify.ps1`
50
- - `tools/install/` 下的 `bootstrap-codex-harness.ps1`、`env-check.ps1`、安装脚本
24
+ - `tools/harness/` 下的 `tools/harness/codex-loop.ps1`、`tools/harness/doctor.ps1`、`tools/harness/verify.ps1`
25
+ - `tools/install/` 下的 `tools/install/bootstrap-codex-harness.ps1`、`tools/install/env-check.ps1`、安装脚本
51
26
  - 项目根 `task.json`、`progress.txt`
52
- - `tools/harness/templates/` 下的 `smoke-task.json`、`project-task-template.json`
27
+ - `tools/harness/templates/` 下的 `smoke-task.json`、`tools/harness/templates/project-task-template.json`
53
28
  - `docs/harness/trace.schema.json`
54
29
  - 项目根 `.codex/`
55
- - 项目根 `.agents/` active surface,包括 skills、workflows 和安装后需要的运行辅助面
56
-
57
- 说明:
58
-
59
- - 默认 `thin project` 安装不会把 `docs/harness/`、`docs/testing/`、`docs/knowledge/` 整包复制到项目根。
60
- - 这些深文档默认位于 `.codex-harness/state/config.json` 里的 `packageRoot` 下;只有显式 `-Mode full` / legacy full 场景才会在项目根保留完整副本。
30
+ - 项目根 `docs/harness/`、`docs/testing/`
31
+ - 项目根 `.agents/` 完整能力包,包括 rules、skills、workflows、`.specify/` 和模板复制源
61
32
 
62
33
  ## 使用顺序
63
34
 
64
35
  1. 读取项目根 `AGENTS.md`。
65
- 2. 如果项目根存在 `docs/harness/new-project-usage.md`、`docs/harness/architecture.md` 和 `docs/testing/*`,直接读取;若是 thin project 且这些文件缺失,则先读 `.codex-harness/state/config.json`,再到其中 `packageRoot` 下读取同路径文件。
36
+ 2. `docs/harness/new-project-usage.md`、`docs/harness/architecture.md` 和 `docs/testing/*` 收敛项目上下文。
66
37
  3. 必要时使用 SpecKit workflow 生成 spec / plan / tasks 输入。
67
38
  4. 将确认后的任务写入 `task.json`。
68
39
  5. 运行:
69
40
 
70
41
  ```powershell
71
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\harness\verify.ps1
72
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\harness\codex-loop.ps1
42
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\\harness/verify.ps1
43
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\\harness/codex-loop.ps1
73
44
  ```
74
45
 
75
46
  ## 验证安装包
76
47
 
77
48
  ```powershell
78
- powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\release\build-release.ps1
49
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\harness\test-install-modes.ps1
79
50
  ```
80
51
 
81
- 发布产物会输出到 `dist/release/<version>/`,包含:
82
-
83
- - `codex-harness-<version>-win.zip`
84
- - `codex-harness-<version>-win.sha256`
85
- - `release-manifest.json`
52
+ 该脚本现在只验证 full 安装形状。
@@ -27,6 +27,8 @@
27
27
 
28
28
  `full` 行为作为显式 legacy 兼容入口保留。当前包已经提供 package lock、只读升级/卸载计划、安全 `-Upgrade` 和 vendor `-Uninstall`。新分层入口优先使用 wrapper 或等价 `-Scope user|project|vendor` 命令:`tools\\install/install-user.ps1` 等价于 `tools\\install/install-agent.ps1 -Scope user`,`tools\\install/init-project.ps1` 等价于 `tools\\install/install-agent.ps1 -ProjectRoot . -Scope project`。当前不提供 `harness install-user` 子命令。当前不提供 `harness init-project` 子命令。Windows PowerShell 主链路请直接运行这两个 wrapper,避免误以为存在独立 CLI。`-Scope project` 与无参数 `tools\\install/install-agent.ps1 -ProjectRoot .` 等价,都是新项目默认 thin 输出,只生成项目运行必需 runtime、项目级 `.agents/` active surface、`.codex/`、`.codex-harness/state/config.json`、`.codex-harness/locks/package.lock.json`、`.codex-harness/manifests/install-manifest.json`、`docs/ai/`、`docs/architecture/constraints.md`、`docs/spec/01..14` 和 `tools/`,不复制完整 vendor 镜像、`docs/harness/`、`docs/testing/`、`docs/knowledge/` 或 `docs/requirement-prep-kit/`。`-Scope user` 只安装用户级 package source 并写入用户级 lock。
29
29
 
30
+ 如果你是通过全局 npm CLI 执行 `harness init`,当前实现会先检查 `%USERPROFILE%/.codex/packages/codex-harness/` 的 user package cache;发现缺失或版本落后时,会自动执行等价于 `install-user.ps1` 的刷新,再继续项目初始化。只有在 `harness init --plan` 下,这层缓存不会被改写。
31
+
30
32
  ## `docs/ai/` 导航层
31
33
 
32
34
  - `repo-map.md`
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": "0.1",
3
3
  "status": "draft",
4
4
  "package": "codex-harness",
5
- "version": "0.1.5",
5
+ "version": "0.1.7",
6
6
  "installModes": [
7
7
  {
8
8
  "name": "user",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pzy560117/codex-harness",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Codex Harness installer and project runtime CLI",
5
5
  "type": "module",
6
6
  "bin": {