@kylecheng3146/agent-ops 0.1.3 → 0.1.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.
Files changed (80) hide show
  1. package/README.md +88 -13
  2. package/dist/packages/cli/src/args.js +39 -6
  3. package/dist/packages/cli/src/bin.js +33 -11
  4. package/dist/packages/cli/src/cli.js +8 -8
  5. package/dist/packages/cli/src/commands/doctor.js +31 -9
  6. package/dist/packages/cli/src/commands/hook.js +18 -16
  7. package/dist/packages/cli/src/commands/init.js +29 -7
  8. package/dist/packages/cli/src/commands/review.js +5 -1
  9. package/dist/packages/cli/src/commands/uninstall.js +6 -5
  10. package/dist/packages/cli/src/commands/update.js +13 -5
  11. package/dist/packages/cli/src/context.js +9 -3
  12. package/dist/packages/cli/src/hook-process.js +109 -7
  13. package/dist/packages/cli/src/plan-output.js +9 -4
  14. package/dist/packages/cli/src/public-plan.js +62 -0
  15. package/dist/packages/cli/src/ui.js +242 -1
  16. package/dist/packages/cli/src/version.js +1 -1
  17. package/dist/packages/cli/src/wizard.js +68 -2
  18. package/dist/runtime/src/adapters/claude/config.js +0 -8
  19. package/dist/runtime/src/adapters/claude/events.js +26 -0
  20. package/dist/runtime/src/adapters/claude/output.js +6 -6
  21. package/dist/runtime/src/adapters/claude/surfaces.js +70 -0
  22. package/dist/runtime/src/adapters/codex/config.js +29 -11
  23. package/dist/runtime/src/adapters/codex/events.js +26 -0
  24. package/dist/runtime/src/adapters/codex/output.js +10 -0
  25. package/dist/runtime/src/adapters/codex/surfaces.js +12 -0
  26. package/dist/runtime/src/adapters/opencode/config.js +170 -0
  27. package/dist/runtime/src/adapters/opencode/events.js +49 -0
  28. package/dist/runtime/src/adapters/opencode/input.js +32 -0
  29. package/dist/runtime/src/adapters/opencode/output.js +23 -0
  30. package/dist/runtime/src/adapters/opencode/surfaces.js +23 -0
  31. package/dist/runtime/src/config/explain.js +7 -0
  32. package/dist/runtime/src/config/hash.js +24 -0
  33. package/dist/runtime/src/config/merge.js +6 -2
  34. package/dist/runtime/src/config/migrate.js +19 -4
  35. package/dist/runtime/src/contracts.js +10 -1
  36. package/dist/runtime/src/fs/manifest.js +32 -1
  37. package/dist/runtime/src/fs/transaction.js +14 -2
  38. package/dist/runtime/src/hooks/advisory.js +16 -0
  39. package/dist/runtime/src/hooks/stop-service.js +70 -0
  40. package/dist/runtime/src/hooks/stop-verify.js +4 -1
  41. package/dist/runtime/src/install/doctor.js +119 -9
  42. package/dist/runtime/src/install/harness.js +296 -35
  43. package/dist/runtime/src/install/hooks.js +22 -17
  44. package/dist/runtime/src/install/ownership.js +110 -34
  45. package/dist/runtime/src/install/plan.js +207 -28
  46. package/dist/runtime/src/install/probes.js +9 -43
  47. package/dist/runtime/src/install/profiles.js +8 -1
  48. package/dist/runtime/src/install/surface-inspection.js +296 -0
  49. package/dist/runtime/src/install/surfaces.js +11 -0
  50. package/dist/runtime/src/install/uninstall.js +10 -3
  51. package/dist/runtime/src/install/update.js +8 -2
  52. package/dist/runtime/src/schema/validate.js +37 -18
  53. package/dist/runtime/src/task/service.js +3 -3
  54. package/dist/runtime/src/task/store.js +12 -3
  55. package/dist/runtime/src/verify/command-executor.js +113 -0
  56. package/dist/runtime/src/verify/evidence.js +4 -24
  57. package/dist/runtime/src/verify/service.js +20 -92
  58. package/dist/runtime/src/verify/spawn.js +6 -1
  59. package/docs/en/guides/configuration.md +83 -0
  60. package/docs/en/guides/quickstart.md +9 -0
  61. package/docs/en/guides/security.md +5 -0
  62. package/docs/en/spec/README.md +9 -0
  63. package/docs/en/spec/harness-adapters.md +66 -2
  64. package/docs/en/spec/maintenance.md +11 -0
  65. package/docs/en/spec/review.md +11 -0
  66. package/docs/zh-TW/guides/configuration.md +77 -0
  67. package/docs/zh-TW/guides/quickstart.md +9 -0
  68. package/docs/zh-TW/guides/security.md +5 -0
  69. package/docs/zh-TW/spec/README.md +9 -0
  70. package/docs/zh-TW/spec/harness-adapters.md +57 -3
  71. package/docs/zh-TW/spec/maintenance.md +11 -1
  72. package/docs/zh-TW/spec/review.md +10 -0
  73. package/package.json +8 -4
  74. package/postinstall.cjs +102 -0
  75. package/schemas/config.schema.json +55 -1
  76. package/schemas/manifest.schema.json +7 -2
  77. package/templates/common/AGENTS.block.md +2 -1
  78. package/templates/common/CLAUDE.block.md +2 -1
  79. package/dist/runtime/src/review/claude-runner.js +0 -4
  80. package/dist/runtime/src/review/codex-runner.js +0 -4
@@ -1,6 +1,6 @@
1
1
  # 維護
2
2
 
3
- English source version: 2026-07-23. Revalidate: when the English specification changes.
3
+ English source version: 2026-07-31. Revalidate: when the English specification changes.
4
4
 
5
5
  ## MAINTAIN-BACKUP-001
6
6
 
@@ -21,3 +21,13 @@ English source version: 2026-07-23. Revalidate: when the English specification c
21
21
  - Evidence: 文件含來源與 `Revalidate:` 條件。
22
22
  - Positive: `Revalidate:vendor hook reference 變更時。`
23
23
  - Negative: `把暫時性的 CLI flag 當永久核心規則。`
24
+
25
+ ## MAINTAIN-PLUGIN-001
26
+
27
+ 產生的 harness plugin MUST 視為 managed artifact,且 MUST NOT 直接在原位置手動編輯。
28
+
29
+ - Trigger: 更新 runtime、capabilities 或 vendor plugin contract。
30
+ - Action: 重新產生 opencode shim、驗證 manifest hash,並在 release 前重新檢查 vendor 行為。
31
+ - Evidence: artifact hash 與 shim import 測試通過;release 文件記錄重驗條件。
32
+ - Positive: `agent-ops update` 通過 ownership checks 後重寫已變更的 plugin。
33
+ - Negative: `手動修改 .opencode/plugins/agent-ops.js,卻保留舊的 manifest hash。`
@@ -21,3 +21,13 @@ English source version: 2026-07-23. Revalidate: when the English specification c
21
21
  - Evidence: 結果列出 harness、設定的 model 或限制、effort 與原因。
22
22
  - Positive: `NOT_RUN:需要登入;prompt 可複製。`
23
23
  - Negative: `沒有審查執行,仍標示 PASS。`
24
+
25
+ ## REVIEW-HARNESS-001
26
+
27
+ 即使 installation 支援多個 harness,一次 review invocation MUST 解析成恰好一個 concrete harness。
28
+
29
+ - Trigger: 使用 harness selection 執行 `review`。
30
+ - Action: 從 `codex`、`claude` 或 `opencode` 中選一個;multi-harness installation 與 review execution 分開處理。
31
+ - Evidence: argument parsing 會拒絕 review 使用 `all`、`both` 或逗號分隔的多 harness 值。
32
+ - Positive: `review --harness opencode` 解析成一個 harness。
33
+ - Negative: `讓一次 review invocation 隱式跑過所有已安裝 harness。`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kylecheng3146/agent-ops",
3
- "version": "0.1.3",
4
- "description": "Evidence-driven development loops for Codex and Claude Code",
3
+ "version": "0.1.5",
4
+ "description": "Evidence-driven development loops for Codex, Claude Code, and opencode",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": "github:kylecheng3146/agent-ops",
@@ -17,9 +17,12 @@
17
17
  "templates/",
18
18
  "docs/en/spec/",
19
19
  "docs/zh-TW/spec/",
20
+ "docs/en/guides/",
21
+ "docs/zh-TW/guides/",
20
22
  "README.md",
21
23
  "LICENSE",
22
- "SECURITY.md"
24
+ "SECURITY.md",
25
+ "postinstall.cjs"
23
26
  ],
24
27
  "publishConfig": {
25
28
  "access": "public"
@@ -30,7 +33,8 @@
30
33
  "test:compile": "node scripts/clean.mjs .tmp && tsc -p tsconfig.test.json",
31
34
  "test": "npm run test:compile && node scripts/run-tests.mjs .tmp/test-dist/tests",
32
35
  "build": "node scripts/clean.mjs dist && tsc -p tsconfig.build.json",
33
- "package:check": "node scripts/package-check.mjs"
36
+ "package:check": "node scripts/package-check.mjs",
37
+ "postinstall": "node postinstall.cjs"
34
38
  },
35
39
  "devDependencies": {
36
40
  "@types/node": "26.1.1",
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ const { closeSync, existsSync, openSync, readFileSync } = require("node:fs");
4
+ const { join, resolve } = require("node:path");
5
+ const { spawnSync } = require("node:child_process");
6
+ const { isatty } = require("node:tty");
7
+
8
+ const PACKAGE_NAME = "@kylecheng3146/agent-ops";
9
+ const packageRoot = __dirname;
10
+ const installRoot = resolve(process.env.INIT_CWD ?? process.cwd());
11
+
12
+ function isDirectDependency() {
13
+ try {
14
+ const packageJson = JSON.parse(
15
+ readFileSync(join(installRoot, "package.json"), "utf8")
16
+ );
17
+ return [
18
+ packageJson.dependencies,
19
+ packageJson.devDependencies,
20
+ packageJson.optionalDependencies,
21
+ packageJson.peerDependencies
22
+ ].some(
23
+ (dependencies) =>
24
+ dependencies !== null &&
25
+ typeof dependencies === "object" &&
26
+ dependencies[PACKAGE_NAME] !== undefined
27
+ );
28
+ } catch {
29
+ return false;
30
+ }
31
+ }
32
+
33
+ function openTerminal() {
34
+ if (process.stdin.isTTY === true && process.stdout.isTTY === true) {
35
+ return { stdio: "inherit", close() {} };
36
+ }
37
+
38
+ const inputPath = process.platform === "win32" ? "CONIN$" : "/dev/tty";
39
+ const outputPath = process.platform === "win32" ? "CONOUT$" : "/dev/tty";
40
+ let inputFd;
41
+ let outputFd;
42
+ try {
43
+ inputFd = openSync(inputPath, "r");
44
+ outputFd = process.platform === "win32" ? openSync(outputPath, "a") : inputFd;
45
+ if (!isatty(inputFd) || !isatty(outputFd)) {
46
+ throw new Error("Interactive terminal is unavailable.");
47
+ }
48
+ return {
49
+ stdio: [inputFd, outputFd, outputFd],
50
+ close() {
51
+ if (outputFd !== inputFd) {
52
+ closeSync(outputFd);
53
+ }
54
+ closeSync(inputFd);
55
+ }
56
+ };
57
+ } catch {
58
+ if (outputFd !== undefined && outputFd !== inputFd) {
59
+ closeSync(outputFd);
60
+ }
61
+ if (inputFd !== undefined) {
62
+ closeSync(inputFd);
63
+ }
64
+ return null;
65
+ }
66
+ }
67
+
68
+ if (
69
+ installRoot === resolve(packageRoot) ||
70
+ process.env.CI !== undefined ||
71
+ !isDirectDependency()
72
+ ) {
73
+ process.exit(0);
74
+ }
75
+
76
+ const terminal = openTerminal();
77
+ if (terminal === null) {
78
+ process.exit(0);
79
+ }
80
+
81
+ const cliPath = join(packageRoot, "dist", "packages", "cli", "src", "bin.js");
82
+ if (!existsSync(cliPath)) {
83
+ process.stderr.write(
84
+ "agent-ops init was skipped because the installed CLI is unavailable.\n"
85
+ );
86
+ terminal.close();
87
+ process.exit(0);
88
+ }
89
+
90
+ const result = spawnSync(process.execPath, [cliPath], {
91
+ cwd: installRoot,
92
+ env: process.env,
93
+ stdio: terminal.stdio
94
+ });
95
+ terminal.close();
96
+
97
+ if (result.error !== undefined || result.status !== 0) {
98
+ process.stderr.write(
99
+ "agent-ops init was not applied; package installation completed. " +
100
+ "Run `agent-ops` to retry.\n"
101
+ );
102
+ }
@@ -8,12 +8,13 @@
8
8
  "schemaVersion",
9
9
  "profiles",
10
10
  "verification",
11
+ "features",
11
12
  "pathMappings",
12
13
  "securityExceptions"
13
14
  ],
14
15
  "properties": {
15
16
  "schemaVersion": {
16
- "const": 1
17
+ "const": 2
17
18
  },
18
19
  "profiles": {
19
20
  "type": "array",
@@ -42,6 +43,23 @@
42
43
  }
43
44
  }
44
45
  },
46
+ "features": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": ["stopVerification"],
50
+ "properties": {
51
+ "stopVerification": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": ["enabled"],
55
+ "properties": {
56
+ "enabled": {
57
+ "type": "boolean"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ },
45
63
  "pathMappings": {
46
64
  "type": "array",
47
65
  "items": {
@@ -94,6 +112,42 @@
94
112
  }
95
113
  }
96
114
  },
115
+ "allOf": [
116
+ {
117
+ "if": {
118
+ "type": "object",
119
+ "properties": {
120
+ "features": {
121
+ "type": "object",
122
+ "properties": {
123
+ "stopVerification": {
124
+ "type": "object",
125
+ "properties": {
126
+ "enabled": {
127
+ "const": true
128
+ }
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
134
+ },
135
+ "then": {
136
+ "type": "object",
137
+ "properties": {
138
+ "verification": {
139
+ "type": "object",
140
+ "properties": {
141
+ "commands": {
142
+ "type": "array",
143
+ "minItems": 1
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ ],
97
151
  "$defs": {
98
152
  "id": {
99
153
  "type": "string",
@@ -7,13 +7,18 @@
7
7
  "required": ["schemaVersion", "scope", "harness", "artifacts", "markers"],
8
8
  "properties": {
9
9
  "schemaVersion": {
10
- "const": 1
10
+ "const": 2
11
11
  },
12
12
  "scope": {
13
13
  "enum": ["project", "user"]
14
14
  },
15
15
  "harness": {
16
- "enum": ["codex", "claude", "both"]
16
+ "type": "array",
17
+ "minItems": 1,
18
+ "uniqueItems": true,
19
+ "items": {
20
+ "enum": ["codex", "claude", "opencode"]
21
+ }
17
22
  },
18
23
  "artifacts": {
19
24
  "type": "array",
@@ -1,3 +1,4 @@
1
1
  ## Loop Engineering
2
2
 
3
- Use `.agent-ops/AGENTS.md` as the canonical Loop Engineering specification for this project.
3
+ Load `.agent-ops/AGENTS.md` as the agent-ops managed baseline.
4
+ Project-specific instructions in this file remain authoritative.
@@ -1,3 +1,4 @@
1
1
  ## Loop Engineering
2
2
 
3
- Use `.agent-ops/CLAUDE.md` as the canonical Loop Engineering specification for this project.
3
+ Load `.agent-ops/CLAUDE.md` as the agent-ops managed baseline.
4
+ Project-specific instructions in this file remain authoritative.
@@ -1,4 +0,0 @@
1
- import { runIndependentReview } from "./runner.js";
2
- export function runClaudeReview(options) {
3
- return runIndependentReview(options);
4
- }
@@ -1,4 +0,0 @@
1
- import { runIndependentReview } from "./runner.js";
2
- export function runCodexReview(options) {
3
- return runIndependentReview(options);
4
- }