ultra-builder-pro-cli 0.5.2 → 0.6.0
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/CHANGELOG.md +44 -7
- package/README.md +14 -16
- package/adapters/_shared/codex-assets.cjs +32 -151
- package/adapters/_shared/frontmatter.cjs +2 -2
- package/adapters/_shared/handbook.cjs +3 -3
- package/adapters/_shared/path-rewrite.cjs +0 -3
- package/adapters/_shared/runtime-assets.cjs +11 -4
- package/adapters/_shared/tests/path-rewrite.test.cjs +1 -3
- package/adapters/_shared/tests/resolve-target.test.cjs +1 -11
- package/adapters/_shared/tests/runtime-assets.test.cjs +17 -6
- package/adapters/opencode.js +1 -6
- package/adapters/tests/claude.test.cjs +1 -4
- package/adapters/tests/codex.test.cjs +5 -6
- package/adapters/tests/opencode.test.cjs +1 -2
- package/agents/tdd-runner.md +4 -3
- package/bin/install.js +6 -9
- package/bin/orchestrator.js +11 -4
- package/docs/AGENT-CONTEXT.md +4 -5
- package/docs/ARCHITECTURE.md +3 -4
- package/docs/LEGACY-HERMES.md +5 -81
- package/docs/PLAN.zh-CN.md +35 -42
- package/docs/ROADMAP.md +3 -3
- package/docs/RUNTIME-COMPAT-MATRIX.md +61 -60
- package/mcp-server/lib/pricing.cjs +0 -6
- package/mcp-server/lib/state-ops.cjs +7 -0
- package/mcp-server/lib/telemetry.cjs +4 -0
- package/mcp-server/tests/server-contract.test.cjs +17 -0
- package/mcp-server/tests/state-ops.test.cjs +23 -0
- package/mcp-server/tests/telemetry.test.cjs +14 -0
- package/orchestrator/dispatch-rules.cjs +15 -4
- package/orchestrator/tests/daemon.test.cjs +13 -12
- package/orchestrator/tests/dispatch-rules.test.cjs +12 -10
- package/package.json +3 -5
- package/skills/ultra-init/SKILL.md +0 -1
- package/skills/ultra-verify/SKILL.md +22 -41
- package/skills/ultra-verify/evals/evals.json +22 -24
- package/skills/ultra-verify/references/confidence-system.md +15 -32
- package/skills/ultra-verify/references/cross-verify-modes.md +14 -59
- package/skills/ultra-verify/scripts/verify_wait.py +44 -81
- package/spec/mcp-tools.yaml +3 -3
- package/spec/schemas/skill-manifest.schema.json +2 -2
- package/spec/schemas/state-db.sql +2 -2
- package/adapters/_shared/md-to-toml.cjs +0 -54
- package/adapters/_shared/tests/md-to-toml.test.cjs +0 -48
- package/adapters/gemini.js +0 -204
- package/adapters/tests/gemini.test.cjs +0 -112
- package/skills/gemini-collab/SKILL.md +0 -51
- package/skills/gemini-collab/evals/evals.json +0 -42
|
@@ -9,6 +9,7 @@ const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
|
9
9
|
const {
|
|
10
10
|
CORE_PUBLIC_SKILLS,
|
|
11
11
|
INTERNAL_AGENT_SKILLS,
|
|
12
|
+
SUPPORTED_RUNTIMES,
|
|
12
13
|
COLLAB_SKILLS_BY_RUNTIME,
|
|
13
14
|
RETIRED_SKILLS,
|
|
14
15
|
WORKFLOW_HOOK_FILES,
|
|
@@ -51,19 +52,17 @@ test('runtime asset manifest exposes only Ultra-owned core and internal skills',
|
|
|
51
52
|
assert.deepEqual(RETIRED_SKILLS, RETIRED);
|
|
52
53
|
|
|
53
54
|
assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.claude, [
|
|
54
|
-
'codex-collab', '
|
|
55
|
+
'codex-collab', 'ultra-verify',
|
|
55
56
|
]);
|
|
56
57
|
assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.codex, [
|
|
57
|
-
'cc-collab', '
|
|
58
|
+
'cc-collab', 'ultra-verify',
|
|
58
59
|
]);
|
|
59
60
|
assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.opencode, [
|
|
60
|
-
'cc-collab', 'codex-collab', 'gemini-collab', 'ultra-verify',
|
|
61
|
-
]);
|
|
62
|
-
assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.gemini, [
|
|
63
61
|
'cc-collab', 'codex-collab', 'ultra-verify',
|
|
64
62
|
]);
|
|
63
|
+
assert.deepEqual(SUPPORTED_RUNTIMES, ['claude', 'opencode', 'codex']);
|
|
65
64
|
|
|
66
|
-
for (const runtime of
|
|
65
|
+
for (const runtime of SUPPORTED_RUNTIMES) {
|
|
67
66
|
const names = skillsForRuntime(runtime);
|
|
68
67
|
for (const retired of RETIRED) assert.ok(!names.includes(retired));
|
|
69
68
|
assert.ok(!names.some((name) => /impeccable/i.test(name)));
|
|
@@ -89,6 +88,18 @@ test('workflow hook allowlist contains no memory, prompt capture, or generic pol
|
|
|
89
88
|
assert.doesNotMatch(WORKFLOW_HOOK_FILES.join('\n'), /memory|recall|journal|observation|prompt|dangerous|post_edit/);
|
|
90
89
|
});
|
|
91
90
|
|
|
91
|
+
test('bundled agents never instruct workers to own persistent memory', () => {
|
|
92
|
+
const agentsDir = path.join(REPO_ROOT, 'agents');
|
|
93
|
+
const agentText = fs.readdirSync(agentsDir)
|
|
94
|
+
.filter((name) => name.endsWith('.md'))
|
|
95
|
+
.map((name) => fs.readFileSync(path.join(agentsDir, name), 'utf8'))
|
|
96
|
+
.join('\n');
|
|
97
|
+
|
|
98
|
+
assert.doesNotMatch(agentText, /^## Memory$/m);
|
|
99
|
+
assert.doesNotMatch(agentText, /Update your project memory|Consult memory before starting work/);
|
|
100
|
+
assert.doesNotMatch(agentText, /\.ultra\/memory|\/recall(?:\s|`|$)/m);
|
|
101
|
+
});
|
|
102
|
+
|
|
92
103
|
test('npm publish list uses the same explicit skill boundary', () => {
|
|
93
104
|
const pkg = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'package.json'), 'utf8'));
|
|
94
105
|
const publishedSkills = pkg.files
|
package/adapters/opencode.js
CHANGED
|
@@ -94,7 +94,7 @@ function openCodeTextTransform(input, assetName = '') {
|
|
|
94
94
|
text = text.replaceAll('Claude runtime', 'OpenCode runtime');
|
|
95
95
|
text = text.replaceAll('Claude-only', 'OpenCode-only');
|
|
96
96
|
|
|
97
|
-
if (assetName === 'codex-collab'
|
|
97
|
+
if (assetName === 'codex-collab') {
|
|
98
98
|
text = text.replaceAll('within Claude Code', 'from OpenCode');
|
|
99
99
|
text = text.replaceAll('Claude Code remains primary', 'OpenCode remains primary');
|
|
100
100
|
text = text.replaceAll('Claude orchestrates', 'OpenCode remains primary and orchestrates');
|
|
@@ -104,13 +104,8 @@ function openCodeTextTransform(input, assetName = '') {
|
|
|
104
104
|
}
|
|
105
105
|
if (assetName === 'ultra-verify') {
|
|
106
106
|
text = text.replaceAll('claude-analysis.md', 'opencode-analysis.md');
|
|
107
|
-
text = text.replaceAll('Claude + Gemini + Codex', 'OpenCode + Gemini + Codex');
|
|
108
107
|
text = text.replaceAll('Claude Code', 'OpenCode');
|
|
109
108
|
text = text.replaceAll('Claude', 'OpenCode');
|
|
110
|
-
text = text.replace(
|
|
111
|
-
/Orchestrate OpenCode \+ Gemini \+ Codex for independent three-way analysis\./,
|
|
112
|
-
'OpenCode remains primary while Gemini and Codex provide independent read-only analyses.',
|
|
113
|
-
);
|
|
114
109
|
}
|
|
115
110
|
if (assetName === 'learn') {
|
|
116
111
|
text = text.replaceAll(
|
|
@@ -52,7 +52,6 @@ test('Claude plugin collaboration and learn workflows are safe native plugin ass
|
|
|
52
52
|
const read = (name) => fs.readFileSync(path.join(target, 'skills', name, 'SKILL.md'), 'utf8');
|
|
53
53
|
const learn = read('learn');
|
|
54
54
|
const codexCollab = read('codex-collab');
|
|
55
|
-
const geminiCollab = read('gemini-collab');
|
|
56
55
|
const verify = read('ultra-verify');
|
|
57
56
|
const review = read('ultra-review');
|
|
58
57
|
const plan = read('ultra-plan');
|
|
@@ -61,8 +60,6 @@ test('Claude plugin collaboration and learn workflows are safe native plugin ass
|
|
|
61
60
|
assert.match(learn, /~\/.claude\/skills\/learned-<pattern-slug>-unverified\/SKILL\.md/);
|
|
62
61
|
assert.doesNotMatch(learn, /_unverified\.md/);
|
|
63
62
|
assert.match(codexCollab, /-s read-only/);
|
|
64
|
-
assert.match(geminiCollab, /--approval-mode plan/);
|
|
65
|
-
assert.match(verify, /--approval-mode plan/);
|
|
66
63
|
assert.match(verify, /-s read-only/);
|
|
67
64
|
assert.match(verify, /\$CLAUDE_PLUGIN_ROOT\/skills\/ultra-verify\/scripts\/verify_wait\.py/);
|
|
68
65
|
assert.match(review, /\$CLAUDE_PLUGIN_ROOT\/skills\/ultra-review\/scripts\/review_wait\.py/);
|
|
@@ -71,7 +68,7 @@ test('Claude plugin collaboration and learn workflows are safe native plugin ass
|
|
|
71
68
|
assert.match(status, /never fall back .*tasks\.json/i);
|
|
72
69
|
assert.doesNotMatch(plan, /ultra-tools task create/);
|
|
73
70
|
|
|
74
|
-
for (const [name, contents] of Object.entries({ codexCollab,
|
|
71
|
+
for (const [name, contents] of Object.entries({ codexCollab, verify })) {
|
|
75
72
|
assert.doesNotMatch(contents, /--yolo|--full-auto|\/codex:/, name);
|
|
76
73
|
}
|
|
77
74
|
} finally {
|
|
@@ -89,7 +89,7 @@ test('install builds one Codex-native plugin with complete skill and command cov
|
|
|
89
89
|
|
|
90
90
|
const expectedSkills = skillsForRuntime('codex').sort();
|
|
91
91
|
assert.deepEqual(skillNames(layout.pluginRoot), expectedSkills);
|
|
92
|
-
assert.equal(expectedSkills.length,
|
|
92
|
+
assert.equal(expectedSkills.length, 16);
|
|
93
93
|
assert.ok(!fs.existsSync(path.join(layout.pluginRoot, 'skills', 'codex-collab')));
|
|
94
94
|
assert.ok(!fs.existsSync(path.join(layout.pluginRoot, 'skills', 'learned')));
|
|
95
95
|
|
|
@@ -117,7 +117,7 @@ test('every generated skill is Codex-valid, UI-visible, and free of Claude host
|
|
|
117
117
|
assert.equal(fm.name, name);
|
|
118
118
|
assert.doesNotMatch(
|
|
119
119
|
text,
|
|
120
|
-
/~\/\.claude|CLAUDE\.md|AskUserQuestion|(^|[\s`(>])\/(?:ultra-[a-z-]+|recall|learn|
|
|
120
|
+
/~\/\.claude|CLAUDE\.md|AskUserQuestion|(^|[\s`(>])\/(?:ultra-[a-z-]+|recall|learn|codex-collab)(?=$|[\s`,.;):])/m,
|
|
121
121
|
);
|
|
122
122
|
assert.doesNotMatch(text, /TaskCreate|TaskUpdate|TaskList|TaskOutput|run_in_background|~\/\.codex\/skills|mcp__claude/);
|
|
123
123
|
|
|
@@ -135,13 +135,12 @@ test('every generated skill is Codex-valid, UI-visible, and free of Claude host
|
|
|
135
135
|
const verify = fs.readFileSync(path.join(layout.pluginRoot, 'skills', 'ultra-verify', 'SKILL.md'), 'utf8');
|
|
136
136
|
assert.match(verify, /Codex owns the task/);
|
|
137
137
|
assert.match(verify, /claude --safe-mode/);
|
|
138
|
-
assert.match(verify, /gemini --approval-mode plan/);
|
|
139
138
|
assert.match(verify, /codex-analysis\.md/);
|
|
140
139
|
assert.doesNotMatch(verify, /codex-output\.md|Claude synthesizes|Claude-only/);
|
|
141
140
|
|
|
142
141
|
const waiter = fs.readFileSync(path.join(layout.pluginRoot, 'skills', 'ultra-verify', 'scripts', 'verify_wait.py'), 'utf8');
|
|
143
|
-
assert.match(waiter, /
|
|
144
|
-
assert.
|
|
142
|
+
assert.match(waiter, /ADVISOR = "claude"/);
|
|
143
|
+
assert.match(waiter, /OUTPUT_FILE = "claude-output\.md"/);
|
|
145
144
|
|
|
146
145
|
const review = fs.readFileSync(path.join(layout.pluginRoot, 'skills', 'ultra-review', 'SKILL.md'), 'utf8');
|
|
147
146
|
assert.match(review, /native Codex custom agents/);
|
|
@@ -179,7 +178,7 @@ test('install converts all nine Claude agents into native Codex agent TOML', ()
|
|
|
179
178
|
assert.match(text, /^developer_instructions = """/m);
|
|
180
179
|
assert.doesNotMatch(
|
|
181
180
|
text,
|
|
182
|
-
/model = "opus"|^tools =|^memory =|maxTurns|CLAUDE\.md|AskUserQuestion|(^|[\s`(>])\/(?:ultra-[a-z-]+|recall|learn|
|
|
181
|
+
/model = "opus"|^tools =|^memory =|maxTurns|CLAUDE\.md|AskUserQuestion|(^|[\s`(>])\/(?:ultra-[a-z-]+|recall|learn|codex-collab)(?=$|[\s`,.;):])/m,
|
|
183
182
|
);
|
|
184
183
|
}
|
|
185
184
|
} finally {
|
|
@@ -60,7 +60,6 @@ test('install performs content-level OpenCode adaptation for commands, skills, r
|
|
|
60
60
|
const learn = fs.readFileSync(path.join(target, 'skills', 'learn', 'SKILL.md'), 'utf8');
|
|
61
61
|
const review = fs.readFileSync(path.join(target, 'skills', 'ultra-review', 'SKILL.md'), 'utf8');
|
|
62
62
|
const codexCollab = fs.readFileSync(path.join(target, 'skills', 'codex-collab', 'SKILL.md'), 'utf8');
|
|
63
|
-
const geminiCollab = fs.readFileSync(path.join(target, 'skills', 'gemini-collab', 'SKILL.md'), 'utf8');
|
|
64
63
|
const verify = fs.readFileSync(path.join(target, 'skills', 'ultra-verify', 'SKILL.md'), 'utf8');
|
|
65
64
|
|
|
66
65
|
assert.deepEqual(Object.keys(parseFm(plan).fm), ['name', 'description']);
|
|
@@ -68,9 +67,9 @@ test('install performs content-level OpenCode adaptation for commands, skills, r
|
|
|
68
67
|
assert.doesNotMatch(learn, /_unverified\.md/);
|
|
69
68
|
assert.match(review, /~\/.config\/opencode\/skills\/ultra-review\/scripts\/review_wait\.py/);
|
|
70
69
|
assert.match(codexCollab, /OpenCode remains primary/);
|
|
71
|
-
assert.match(geminiCollab, /OpenCode remains primary/);
|
|
72
70
|
assert.match(verify, /OpenCode remains primary/);
|
|
73
71
|
assert.match(verify, /opencode-analysis\.md/);
|
|
72
|
+
assert.match(verify, /codex exec -s read-only/);
|
|
74
73
|
assert.match(plan, /LEGACY_STATE_MIGRATION_REQUIRED/);
|
|
75
74
|
assert.match(plan, /never read or write .*tasks\.json/i);
|
|
76
75
|
assert.doesNotMatch(plan, /ultra-tools task create/);
|
package/agents/tdd-runner.md
CHANGED
|
@@ -86,7 +86,8 @@ Scan test files for forbidden patterns:
|
|
|
86
86
|
ALL PASS / X FAILURES NEED ATTENTION
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
##
|
|
89
|
+
## Handoff
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
Return reusable test patterns, common failure causes, and framework quirks to the
|
|
92
|
+
parent agent as explicit evidence. Do not create or update a private Ultra memory
|
|
93
|
+
store; persistent memory belongs to the host's separately installed provider.
|
package/bin/install.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* ultra-builder-pro-cli — multi-runtime installer.
|
|
5
5
|
*
|
|
6
6
|
* Distributes Ultra Builder Pro assets — commands, agents, skills, hooks,
|
|
7
|
-
* MCP server — to Claude Code, OpenCode,
|
|
7
|
+
* MCP server — to Claude Code, OpenCode, and Codex CLI via
|
|
8
8
|
* runtime-specific adapters under adapters/. Install is idempotent and
|
|
9
9
|
* uses atomic writes; uninstall reverses via sentinel/manifest blocks.
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
12
|
* npx ultra-builder-pro-cli [options]
|
|
13
13
|
*
|
|
14
|
-
* --claude / --opencode / --codex
|
|
14
|
+
* --claude / --opencode / --codex select runtime(s)
|
|
15
15
|
* --all install to all supported runtimes
|
|
16
16
|
* -g, --global install to runtime's global config dir
|
|
17
17
|
* -l, --local install into current working directory
|
|
@@ -29,8 +29,7 @@ const os = require('node:os');
|
|
|
29
29
|
|
|
30
30
|
const pkg = require('../package.json');
|
|
31
31
|
const { validateConfigDir } = require('../adapters/_shared/validate.cjs');
|
|
32
|
-
|
|
33
|
-
const SUPPORTED_RUNTIMES = ['claude', 'opencode', 'codex', 'gemini'];
|
|
32
|
+
const { SUPPORTED_RUNTIMES } = require('../adapters/_shared/runtime-assets.cjs');
|
|
34
33
|
|
|
35
34
|
const COLORS = {
|
|
36
35
|
reset: '\x1b[0m',
|
|
@@ -58,7 +57,7 @@ function printBanner() {
|
|
|
58
57
|
paint('cyan', ' ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝╚══════╝╚═╝'),
|
|
59
58
|
'',
|
|
60
59
|
` ${paint('bold', 'Ultra Builder Pro CLI')} ${paint('dim', 'v' + pkg.version)}`,
|
|
61
|
-
` ${paint('dim', 'Multi-runtime installer for Claude Code, OpenCode, Codex
|
|
60
|
+
` ${paint('dim', 'Multi-runtime installer for Claude Code, OpenCode, and Codex')}`,
|
|
62
61
|
'',
|
|
63
62
|
];
|
|
64
63
|
console.log(banner.join('\n'));
|
|
@@ -71,7 +70,6 @@ function printHelp() {
|
|
|
71
70
|
${paint('cyan', '--claude')} Claude Code
|
|
72
71
|
${paint('cyan', '--opencode')} OpenCode
|
|
73
72
|
${paint('cyan', '--codex')} Codex CLI (OpenAI)
|
|
74
|
-
${paint('cyan', '--gemini')} Gemini CLI (Google)
|
|
75
73
|
${paint('cyan', '--all')} all supported runtimes
|
|
76
74
|
|
|
77
75
|
${paint('yellow', 'Scope:')}
|
|
@@ -89,7 +87,7 @@ function printHelp() {
|
|
|
89
87
|
${paint('dim', '# Install to Claude Code globally')}
|
|
90
88
|
npx ultra-builder-pro-cli --claude --global
|
|
91
89
|
|
|
92
|
-
${paint('dim', '# Install to all
|
|
90
|
+
${paint('dim', '# Install to all supported runtimes locally in this repo')}
|
|
93
91
|
npx ultra-builder-pro-cli --all --local
|
|
94
92
|
|
|
95
93
|
${paint('dim', '# Uninstall from OpenCode')}
|
|
@@ -116,7 +114,6 @@ function parseArgs(argv) {
|
|
|
116
114
|
case '--claude': runtimes.add('claude'); break;
|
|
117
115
|
case '--opencode': runtimes.add('opencode'); break;
|
|
118
116
|
case '--codex': runtimes.add('codex'); break;
|
|
119
|
-
case '--gemini': runtimes.add('gemini'); break;
|
|
120
117
|
case '--all':
|
|
121
118
|
SUPPORTED_RUNTIMES.forEach(r => runtimes.add(r));
|
|
122
119
|
break;
|
|
@@ -193,7 +190,7 @@ async function main() {
|
|
|
193
190
|
}
|
|
194
191
|
|
|
195
192
|
if (runtimes.length === 0) {
|
|
196
|
-
bail('no runtime selected; use --claude / --opencode / --codex / --
|
|
193
|
+
bail('no runtime selected; use --claude / --opencode / --codex / --all');
|
|
197
194
|
}
|
|
198
195
|
|
|
199
196
|
const scope = resolveScope(flags);
|
package/bin/orchestrator.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
const fs = require('node:fs');
|
|
23
23
|
const path = require('node:path');
|
|
24
24
|
const { spawn } = require('node:child_process');
|
|
25
|
+
const { isSupportedRuntime } = require('../adapters/_shared/runtime-assets.cjs');
|
|
25
26
|
|
|
26
27
|
const REPO_ROOT = process.env.UBP_REPO_ROOT || process.cwd();
|
|
27
28
|
const PIDFILE = path.join(REPO_ROOT, '.ultra', 'orchestrator.pid');
|
|
@@ -46,8 +47,13 @@ function optInAllowed(settings) {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
function parseRuntimes() {
|
|
49
|
-
const raw = process.env.UBP_ORCH_RUNTIMES || 'claude,opencode,codex
|
|
50
|
-
|
|
50
|
+
const raw = process.env.UBP_ORCH_RUNTIMES || 'claude,opencode,codex';
|
|
51
|
+
const runtimes = [...new Set(raw.split(',').map((s) => s.trim()).filter(Boolean))];
|
|
52
|
+
const invalid = runtimes.filter((runtime) => !isSupportedRuntime(runtime));
|
|
53
|
+
if (invalid.length > 0) {
|
|
54
|
+
throw new Error(`unsupported orchestrator runtime(s): ${invalid.join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
return runtimes;
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
function cmdRun(opts = {}) {
|
|
@@ -61,11 +67,12 @@ function cmdRun(opts = {}) {
|
|
|
61
67
|
}
|
|
62
68
|
const { initStateDb } = require('../mcp-server/lib/state-db.cjs');
|
|
63
69
|
const { runDaemon } = require('../orchestrator/daemon.cjs');
|
|
70
|
+
const runtimes = parseRuntimes();
|
|
64
71
|
const { db } = initStateDb(path.join(REPO_ROOT, '.ultra', 'state.db'));
|
|
65
72
|
const handle = runDaemon({
|
|
66
73
|
db,
|
|
67
74
|
repoRoot: REPO_ROOT,
|
|
68
|
-
runtimes
|
|
75
|
+
runtimes,
|
|
69
76
|
pollMs: Number(process.env.UBP_ORCH_POLL_MS || 1000),
|
|
70
77
|
onError: (err) => process.stderr.write(`orchestrator error: ${err.message}\n`),
|
|
71
78
|
});
|
|
@@ -102,7 +109,7 @@ function cmdRun(opts = {}) {
|
|
|
102
109
|
};
|
|
103
110
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
104
111
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
105
|
-
process.stderr.write(`orchestrator running (pollMs=${Number(process.env.UBP_ORCH_POLL_MS || 1000)}, runtimes=${
|
|
112
|
+
process.stderr.write(`orchestrator running (pollMs=${Number(process.env.UBP_ORCH_POLL_MS || 1000)}, runtimes=${runtimes.join(',')})\n`);
|
|
106
113
|
// Keep process alive while the setInterval is unref'd.
|
|
107
114
|
setInterval(() => {}, 60000);
|
|
108
115
|
}
|
package/docs/AGENT-CONTEXT.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Ultra Builder Pro — Agent Context
|
|
2
2
|
|
|
3
3
|
Current shared runtime contract for the native Claude Code, OpenCode, and Codex
|
|
4
|
-
plugins.
|
|
5
|
-
shape for the three first-class plugins.
|
|
4
|
+
plugins.
|
|
6
5
|
|
|
7
6
|
## 1. Ownership boundary
|
|
8
7
|
|
|
@@ -66,9 +65,9 @@ fixtures. Do not add an ad-hoc server handler first.
|
|
|
66
65
|
|
|
67
66
|
| Host | Plugin form | Workflow entry | Hook form | Collaboration companions |
|
|
68
67
|
|---|---|---|---|---|
|
|
69
|
-
| Claude Code | `.claude-plugin/plugin.json`, native commands/skills/agents, `.mcp.json` | `/ultra-*`, `/learn` | native `hooks/hooks.json` | `codex-collab`, `
|
|
70
|
-
| Codex | personal plugin with `.codex-plugin/plugin.json`, namespaced skills, TOML agents, `.mcp.json` | `$ultra-builder-pro:ultra-*`, `$ultra-builder-pro:learn` | native `hooks/hooks.json` through the Codex wire adapter | `cc-collab`, `
|
|
71
|
-
| OpenCode | config bundle plus native JavaScript plugin | `/ultra-*`, `/learn` | `event`, system transform, compaction, and tool lifecycle handlers | `cc-collab`, `codex-collab`, `
|
|
68
|
+
| Claude Code | `.claude-plugin/plugin.json`, native commands/skills/agents, `.mcp.json` | `/ultra-*`, `/learn` | native `hooks/hooks.json` | `codex-collab`, `ultra-verify` |
|
|
69
|
+
| Codex | personal plugin with `.codex-plugin/plugin.json`, namespaced skills, TOML agents, `.mcp.json` | `$ultra-builder-pro:ultra-*`, `$ultra-builder-pro:learn` | native `hooks/hooks.json` through the Codex wire adapter | `cc-collab`, `ultra-verify` |
|
|
70
|
+
| OpenCode | config bundle plus native JavaScript plugin | `/ultra-*`, `/learn` | `event`, system transform, compaction, and tool lifecycle handlers | `cc-collab`, `codex-collab`, `ultra-verify` |
|
|
72
71
|
|
|
73
72
|
The current host remains primary. Collaboration skills call another runtime
|
|
74
73
|
only when explicitly requested, use it as a read-only advisor, and return the
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
`ultra-builder-pro-cli` is a multi-runtime plugin suite that **distributes** the
|
|
12
12
|
Ultra Builder Pro engineering loop (skills + commands + workflow hooks) as
|
|
13
|
-
native Claude Code, OpenCode, and Codex plugins,
|
|
14
|
-
adapter, and
|
|
13
|
+
native Claude Code, OpenCode, and Codex plugins, and
|
|
15
14
|
**runs** that loop with isolated sessions sharing one authoritative state
|
|
16
15
|
store (`.ultra/state.db`).
|
|
17
16
|
|
|
@@ -24,7 +23,7 @@ the supported hosts share.
|
|
|
24
23
|
┌──────────────────────────┐
|
|
25
24
|
│ runtime CLI │
|
|
26
25
|
│ (claude / opencode / │
|
|
27
|
-
│ codex
|
|
26
|
+
│ codex) │
|
|
28
27
|
└────────────┬─────────────┘
|
|
29
28
|
│
|
|
30
29
|
┌───────────────────┼────────────────────┐
|
|
@@ -53,7 +52,7 @@ the supported hosts share.
|
|
|
53
52
|
|
|
54
53
|
| Layer | Role | Form |
|
|
55
54
|
|--------------|----------------------------------------------|-------------------------------------------------------|
|
|
56
|
-
| **skill** | knowledge carrier; tells the runtime *what to do* | `skills/<name>/SKILL.md` discovered natively by all
|
|
55
|
+
| **skill** | knowledge carrier; tells the runtime *what to do* | `skills/<name>/SKILL.md` discovered natively by all supported runtimes |
|
|
57
56
|
| **MCP** | authoritative workflow-state API | stdio MCP server exposing seven declared tool families in [`spec/mcp-tools.yaml`](../spec/mcp-tools.yaml); 21 tools are live and nine scheduled contracts map to host-native surfaces |
|
|
58
57
|
| **CLI** | the lowest common denominator hooks can call | `ultra-tools <family> <verb>` — same contract, last-line JSON envelope (see [`spec/cli-protocol.md`](../spec/cli-protocol.md)) |
|
|
59
58
|
|
package/docs/LEGACY-HERMES.md
CHANGED
|
@@ -117,8 +117,7 @@ If ANY component is fake/mocked/simulated -> Quality = 0
|
|
|
117
117
|
| Skill | Purpose | User-Invocable |
|
|
118
118
|
|-------|---------|----------------|
|
|
119
119
|
| `ultra-review` | Parallel code review with 6 agents + coordinator | Yes |
|
|
120
|
-
| `ultra-verify` |
|
|
121
|
-
| `gemini-collab` | Gemini CLI as independent sub-agent for review, analysis, opinions | Yes |
|
|
120
|
+
| `ultra-verify` | Independent cross-model verification | Yes |
|
|
122
121
|
| `codex-collab` | OpenAI Codex CLI as independent sub-agent for review, analysis | Yes |
|
|
123
122
|
| `recall` | Cross-session memory search, save summaries, tags | Yes |
|
|
124
123
|
| `agent-browser` | Browser automation CLI for AI agents | Yes |
|
|
@@ -206,54 +205,6 @@ Step 4.5 of `/ultra-dev` runs `/ultra-review all` (forced full coverage) as a ma
|
|
|
206
205
|
|
|
207
206
|
---
|
|
208
207
|
|
|
209
|
-
## Ultra Verify — Three-Way AI Cross-Verification
|
|
210
|
-
|
|
211
|
-
### Overview
|
|
212
|
-
|
|
213
|
-
`/ultra-verify` orchestrates Claude + Gemini + Codex for independent three-way analysis. Each AI works independently, then Claude synthesizes with a confidence score based on consensus.
|
|
214
|
-
|
|
215
|
-
### Prerequisites
|
|
216
|
-
|
|
217
|
-
- Gemini CLI: `npm install -g @google/gemini-cli` + authenticated
|
|
218
|
-
- Codex CLI: `npm install -g @openai/codex` + `codex login`
|
|
219
|
-
|
|
220
|
-
### Usage
|
|
221
|
-
|
|
222
|
-
```
|
|
223
|
-
/ultra-verify decision <question> # Architecture/design decision
|
|
224
|
-
/ultra-verify diagnose <symptoms> # Bug diagnosis — three sets of hypotheses
|
|
225
|
-
/ultra-verify audit <scope> # Code audit — findings ranked by consensus
|
|
226
|
-
/ultra-verify estimate <task> # Effort estimation
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### How It Works
|
|
230
|
-
|
|
231
|
-
1. **Claude answers first** (writes to file before reading external AI output — prevents contamination)
|
|
232
|
-
2. **Gemini + Codex run in parallel** (background tasks, 5 min timeout)
|
|
233
|
-
3. **Claude reads all three outputs** via Read tool
|
|
234
|
-
4. **Confidence scoring**: Consensus (3/3) > Majority (2/3) > No Consensus
|
|
235
|
-
5. **Synthesis** written to `.ultra/collab/<session-id>/synthesis.md`
|
|
236
|
-
|
|
237
|
-
### Degraded Operation
|
|
238
|
-
|
|
239
|
-
- **One AI fails**: Two-way comparison, confidence capped at Majority
|
|
240
|
-
- **Two AIs fail**: Claude-only with explicit warning
|
|
241
|
-
- Never blocks the workflow on external AI failures
|
|
242
|
-
|
|
243
|
-
### Architecture: Shared Base + Thin Skills
|
|
244
|
-
|
|
245
|
-
```
|
|
246
|
-
ai-collab-base/ # Canonical shared files (non-user-invocable)
|
|
247
|
-
├── references/ # collab-protocol.md, collaboration-modes.md, prompt-templates.md
|
|
248
|
-
└── sync.sh # Copies canonical files to consumer skills
|
|
249
|
-
|
|
250
|
-
gemini-collab/ # Thin skill: Gemini-specific CLI reference + shared files
|
|
251
|
-
codex-collab/ # Thin skill: Codex-specific CLI reference + shared files
|
|
252
|
-
ultra-verify/ # Orchestration: parallel execution + confidence scoring
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
208
|
## Cross-Session Memory
|
|
258
209
|
|
|
259
210
|
### Overview
|
|
@@ -479,14 +430,12 @@ Automated enforcement via Python hooks in `hooks/`. **Hooks are deterministic
|
|
|
479
430
|
| | |-- templates/ # Output templates (reserved)
|
|
480
431
|
| |-- ultra-review/ # Parallel review orchestration
|
|
481
432
|
| | |-- scripts/ # review_wait.py, review_verdict_update.py
|
|
482
|
-
| |-- ultra-verify/ #
|
|
433
|
+
| |-- ultra-verify/ # Independent cross-model verification
|
|
483
434
|
| | |-- references/ # cross-verify-modes, confidence-system, orchestration-flow
|
|
484
435
|
| | |-- evals/ # skill-creator eval tests
|
|
485
436
|
| |-- ai-collab-base/ # Shared collab protocol (non-user-invocable)
|
|
486
437
|
| | |-- references/ # collab-protocol, collaboration-modes, prompt-templates
|
|
487
438
|
| | |-- sync.sh # Sync canonical files to consumer skills
|
|
488
|
-
| |-- gemini-collab/ # Gemini CLI as independent sub-agent
|
|
489
|
-
| | |-- references/ # gemini-cli-reference, gemini-prompts, shared files
|
|
490
439
|
| | |-- evals/ # skill-creator eval tests
|
|
491
440
|
| |-- codex-collab/ # OpenAI Codex CLI as independent sub-agent
|
|
492
441
|
| | |-- references/ # codex-cli-reference, codex-prompts, shared files
|
|
@@ -532,7 +481,6 @@ Automated enforcement via Python hooks in `hooks/`. **Hooks are deterministic
|
|
|
532
481
|
| |-- collab/ # AI collaboration sessions (auto-managed)
|
|
533
482
|
| | |-- <session-id>/ # Per-session output
|
|
534
483
|
| | |-- claude-analysis.md
|
|
535
|
-
| | |-- gemini-output.md
|
|
536
484
|
| | |-- codex-output.md
|
|
537
485
|
| | |-- synthesis.md
|
|
538
486
|
| | |-- metadata.json
|
|
@@ -648,7 +596,7 @@ Multi-step tasks use the Task system:
|
|
|
648
596
|
|
|
649
597
|
### v6.3.0 (2026-03-09) - Memory System v2
|
|
650
598
|
|
|
651
|
-
**Structured summaries, real session identity, security hardening**, verified by
|
|
599
|
+
**Structured summaries, real session identity, security hardening**, verified by repeated independent review:
|
|
652
600
|
|
|
653
601
|
**Schema v2 Migration**:
|
|
654
602
|
- New `session_summaries` table: structured JSON fields (`request`, `completed`, `learned`, `next_steps`)
|
|
@@ -681,29 +629,6 @@ Multi-step tasks use the Task system:
|
|
|
681
629
|
- `hooks/user_prompt_capture.py` (New), `hooks/observation_capture.py` (New)
|
|
682
630
|
- `CLAUDE.md`, `README.md`
|
|
683
631
|
|
|
684
|
-
### v6.2.0 (2026-03-08) - Multi-AI Collaboration Refactor
|
|
685
|
-
|
|
686
|
-
**Shared base architecture + three-way AI verification**, verified by 3 rounds of ultra-verify audit (Claude + Gemini + Codex):
|
|
687
|
-
|
|
688
|
-
- New `ai-collab-base` skill: shared collaboration protocol, modes, prompt templates (non-user-invocable)
|
|
689
|
-
- `sync.sh` keeps canonical files in sync across 3 consumer skills
|
|
690
|
-
- Eliminates ~90% structural duplication between gemini-collab and codex-collab
|
|
691
|
-
- New `ultra-verify` skill: three-way AI cross-verification (Claude + Gemini + Codex)
|
|
692
|
-
- 4 modes: `decision`, `diagnose`, `audit`, `estimate`
|
|
693
|
-
- Confidence scoring: Consensus (3/3), Majority (2/3), No Consensus
|
|
694
|
-
- Degraded operation: one AI fails → two-way, two fail → Claude-only with warning
|
|
695
|
-
- Rewritten `gemini-collab`: thin skill pointing to shared base + Gemini-specific CLI reference
|
|
696
|
-
- Rewritten `codex-collab`: thin skill pointing to shared base + Codex-specific CLI reference
|
|
697
|
-
- CLI bug fixes verified against actual `--help` output:
|
|
698
|
-
- `--commit-title` → `--title` (codex review)
|
|
699
|
-
- `--full-auto` + `--sandbox read-only` conflict resolved
|
|
700
|
-
- `$(cat $FILE)` shell injection → stdin pipe pattern
|
|
701
|
-
- `2>/dev/null` → `error.log` (all files, not just orchestration)
|
|
702
|
-
- `-o`/`--output-format` correctly documented for Gemini CLI
|
|
703
|
-
- Hardcoded model names removed (use `-m <model>`)
|
|
704
|
-
- skill-creator compatible `evals/evals.json` for all 3 user-invocable skills
|
|
705
|
-
- Files: `skills/ai-collab-base/`, `skills/ultra-verify/`, `skills/gemini-collab/`, `skills/codex-collab/`
|
|
706
|
-
|
|
707
632
|
### v6.1.0 (2026-03-08) - Product Discovery Round 0
|
|
708
633
|
|
|
709
634
|
**Product Discovery & Strategy phase** — fills the gap between vague ideas and technical specification. Inspired by [phuryn/pm-skills](https://github.com/phuryn/pm-skills) frameworks:
|
|
@@ -723,7 +648,6 @@ Multi-step tasks use the Task system:
|
|
|
723
648
|
|
|
724
649
|
**System consolidation, cleanup, and Multi-AI collaboration**:
|
|
725
650
|
|
|
726
|
-
- New `gemini-collab` skill: Gemini CLI as sub-agent for review, project analysis, second opinions
|
|
727
651
|
- New `codex-collab` skill: OpenAI Codex CLI as sub-agent with built-in `codex review` integration
|
|
728
652
|
- Removed codex skill and all references (CLAUDE.md, README.md, skills/codex/)
|
|
729
653
|
- Stop hook hardening: removed main branch bypass, fixed git status path truncation
|
|
@@ -1048,7 +972,7 @@ Multi-step tasks use the Task system:
|
|
|
1048
972
|
|
|
1049
973
|
**Removed (redundant - Claude handles natively)**:
|
|
1050
974
|
- Agents: build-error-resolver, doc-updater, e2e-runner, frontend-developer, refactor-cleaner
|
|
1051
|
-
- Skills:
|
|
975
|
+
- Skills: promptup, skill-creator
|
|
1052
976
|
- Hooks: user_prompt_agent.py (routing), agent_reminder.py (routing)
|
|
1053
977
|
|
|
1054
978
|
**Improved**:
|
|
@@ -1149,7 +1073,7 @@ Multi-step tasks use the Task system:
|
|
|
1149
1073
|
|
|
1150
1074
|
**Core Changes**:
|
|
1151
1075
|
- Unified Priority Stack in CLAUDE.md
|
|
1152
|
-
- Codex
|
|
1076
|
+
- Codex skill integration
|
|
1153
1077
|
- Anti-Pattern Detection in `/ultra-test`
|
|
1154
1078
|
|
|
1155
1079
|
---
|