ultra-builder-pro-cli 0.16.0 → 0.17.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/.ultra-template/specs/research-distillate.md +4 -3
- package/CHANGELOG.md +86 -0
- package/README.md +54 -24
- package/adapters/_shared/codex-assets.cjs +10 -5
- package/adapters/_shared/handbook.cjs +1 -1
- package/adapters/_shared/interaction-contract.cjs +61 -0
- package/adapters/claude.js +1 -1
- package/adapters/opencode.js +1 -1
- package/bin/orchestrator.js +175 -19
- package/commands/ultra-change.md +1 -1
- package/commands/ultra-deliver.md +3 -3
- package/commands/ultra-init.md +1 -1
- package/commands/ultra-plan.md +1 -1
- package/commands/ultra-research.md +2 -2
- package/commands/ultra-review.md +10 -0
- package/commands/ultra-status.md +1 -1
- package/commands/ultra-test.md +1 -1
- package/docs/AGENT-CONTEXT.md +11 -8
- package/docs/ARCHITECTURE.md +67 -9
- package/docs/LEGACY-CLI-CROSSWALK.md +163 -0
- package/docs/PLAN.zh-CN.md +19 -13
- package/docs/RUNTIME-COMPAT-MATRIX.md +2 -2
- package/docs/WORKFLOW-LIFECYCLE.md +123 -59
- package/hooks/pre_stop_check.py +3 -2
- package/mcp-server/lib/baseline-workflow.cjs +84 -16
- package/mcp-server/lib/change-workflow.cjs +55 -35
- package/mcp-server/lib/context-spine.cjs +171 -105
- package/mcp-server/lib/git-bootstrap.cjs +240 -0
- package/mcp-server/lib/init-project.cjs +178 -41
- package/mcp-server/lib/project-breadcrumb.cjs +14 -14
- package/mcp-server/lib/state-db.cjs +257 -10
- package/mcp-server/lib/state-ops.cjs +64 -1
- package/mcp-server/lib/workflow-state.cjs +300 -205
- package/mcp-server/server.cjs +58 -34
- package/orchestrator/auto-merge.cjs +19 -0
- package/orchestrator/daemon.cjs +104 -0
- package/orchestrator/parallel-orchestrator.cjs +371 -49
- package/orchestrator/session-runner.cjs +354 -25
- package/package.json +2 -1
- package/skills/ultra-change/SKILL.md +69 -94
- package/skills/ultra-deliver/SKILL.md +37 -65
- package/skills/ultra-dev/SKILL.md +50 -52
- package/skills/ultra-doctor/SKILL.md +34 -49
- package/skills/ultra-init/SKILL.md +78 -105
- package/skills/ultra-plan/SKILL.md +78 -99
- package/skills/ultra-research/SKILL.md +99 -113
- package/skills/ultra-review/SKILL.md +38 -53
- package/skills/ultra-review/references/review-modes.md +5 -3
- package/skills/ultra-review/references/unified-schema.md +26 -6
- package/skills/ultra-review/scripts/review_wait.py +12 -0
- package/skills/ultra-status/SKILL.md +34 -44
- package/skills/ultra-test/SKILL.md +61 -54
- package/skills/ultra-think/SKILL.md +37 -51
- package/skills/ultra-think/references/decision-dialogue.md +87 -111
- package/spec/cli-protocol.md +35 -0
- package/spec/mcp-tools.yaml +145 -28
- package/spec/schemas/delivery-report.v1.schema.json +1 -46
- package/spec/schemas/state-db.sql +8 -2
- package/spec/schemas/test-report.v1.schema.json +45 -14
- package/ultra-tools/cli.cjs +1 -1
- package/ultra-tools/commands/session.cjs +10 -3
- package/ultra-tools/commands/status.cjs +19 -14
- package/ultra-tools/commands/system.cjs +2 -2
- package/ultra-tools/commands/task.cjs +3 -0
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
const path = require('node:path');
|
|
10
10
|
const { initStateDb, closeStateDb } = require('../../mcp-server/lib/state-db.cjs');
|
|
11
11
|
const ops = require('../../mcp-server/lib/state-ops.cjs');
|
|
12
|
+
const sessionRunner = require('../../orchestrator/session-runner.cjs');
|
|
12
13
|
|
|
13
14
|
const DEFAULT_DB_PATH = path.join('.ultra', 'state.db');
|
|
14
15
|
|
|
@@ -20,11 +21,12 @@ VERBS:
|
|
|
20
21
|
reap [--grace-seconds <n>] orphan sweeper (Phase 4.5.6)
|
|
21
22
|
get --sid <sid>
|
|
22
23
|
heartbeat --sid <sid>
|
|
23
|
-
close --sid <sid> --status completed|crashed|orphan
|
|
24
|
+
close --sid <sid> --status completed|crashed|orphan [--remove-worktree]
|
|
24
25
|
subscribe --since-id <n> [--sid <sid>] [--limit <n>]
|
|
25
26
|
|
|
26
27
|
GLOBAL FLAGS:
|
|
27
28
|
--db <path> path to state.db (default: .ultra/state.db)
|
|
29
|
+
--repo-root <path> repository root for verified worktree cleanup (default: cwd)
|
|
28
30
|
-h, --help show this message
|
|
29
31
|
`;
|
|
30
32
|
|
|
@@ -44,6 +46,8 @@ function parseFlags(args) {
|
|
|
44
46
|
case '--limit': flags.limit = Number(args[++i]); break;
|
|
45
47
|
case '--since-id': flags.since_id = Number(args[++i]); break;
|
|
46
48
|
case '--grace-seconds': flags.grace_seconds = Number(args[++i]); break;
|
|
49
|
+
case '--repo-root': flags.repo_root = args[++i]; break;
|
|
50
|
+
case '--remove-worktree': flags.remove_worktree = true; break;
|
|
47
51
|
case '-h': case '--help': flags.help = true; break;
|
|
48
52
|
default: flags._.push(a);
|
|
49
53
|
}
|
|
@@ -127,8 +131,11 @@ function cmdClose(flags) {
|
|
|
127
131
|
if (!flags.sid || !flags.status) { emit({ ok: false, error: { code: 'VALIDATION_ERROR', message: 'missing --sid or --status' } }); return 1; }
|
|
128
132
|
return withDb(flags, (db) => {
|
|
129
133
|
try {
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
const result = sessionRunner.closeSession(
|
|
135
|
+
{ db, repoRoot: path.resolve(flags.repo_root || process.cwd()), sid: flags.sid },
|
|
136
|
+
{ status: flags.status, remove_worktree: flags.remove_worktree === true },
|
|
137
|
+
);
|
|
138
|
+
emit({ ok: true, data: result });
|
|
132
139
|
return 0;
|
|
133
140
|
} catch (err) {
|
|
134
141
|
emit({ ok: false, error: { code: err.code || 'STATE_DB_ERROR', message: err.message } });
|
|
@@ -17,7 +17,7 @@ const { readBreadcrumb } = require('../../mcp-server/lib/context-spine.cjs');
|
|
|
17
17
|
|
|
18
18
|
const USAGE = `ultra-tools status [flags]
|
|
19
19
|
|
|
20
|
-
Reads .ultra/state.db and prints baseline, workflow, task, session,
|
|
20
|
+
Reads .ultra/state.db and prints baseline, workflow, task, session, valid transitions, and
|
|
21
21
|
cost-observability status.
|
|
22
22
|
|
|
23
23
|
FLAGS:
|
|
@@ -174,20 +174,19 @@ function buildStatusPanel(db, { since = null, limit = 3, rootDir = process.cwd()
|
|
|
174
174
|
status: 'unavailable', active: 0, awaiting_owner: 0, checkpoint_ready: 0,
|
|
175
175
|
deferred_blocking: 0, stale_artifacts: [], current: null, current_thread_id: null,
|
|
176
176
|
};
|
|
177
|
-
let
|
|
177
|
+
let transitions;
|
|
178
178
|
let breadcrumb = null;
|
|
179
179
|
try {
|
|
180
180
|
if (!tables.has('baselines')) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
recommended_workflow: 'ultra-init', readiness: 'blocked',
|
|
181
|
+
transitions = {
|
|
182
|
+
allowed: ['ultra-init', 'ultra-status'], required: 'ultra-init', readiness: 'blocked',
|
|
184
183
|
blockers: ['BASELINE_SCHEMA_MIGRATION_REQUIRED'], warnings: [],
|
|
185
184
|
};
|
|
186
185
|
} else {
|
|
187
186
|
breadcrumb = readBreadcrumb(db, {}, { rootDir });
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
transitions = {
|
|
188
|
+
allowed: breadcrumb.allowed_transitions,
|
|
189
|
+
required: breadcrumb.required_transition,
|
|
191
190
|
readiness: breadcrumb.readiness,
|
|
192
191
|
blockers: breadcrumb.blockers,
|
|
193
192
|
warnings: breadcrumb.warnings,
|
|
@@ -197,9 +196,8 @@ function buildStatusPanel(db, { since = null, limit = 3, rootDir = process.cwd()
|
|
|
197
196
|
};
|
|
198
197
|
}
|
|
199
198
|
} catch (error) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
recommended_workflow: 'ultra-doctor', readiness: 'blocked',
|
|
199
|
+
transitions = {
|
|
200
|
+
allowed: ['ultra-doctor', 'ultra-status'], required: 'ultra-doctor', readiness: 'blocked',
|
|
203
201
|
blockers: [`STATUS_AUTHORITY_UNAVAILABLE:${error.code || 'unknown'}`], warnings: [],
|
|
204
202
|
};
|
|
205
203
|
}
|
|
@@ -256,7 +254,7 @@ function buildStatusPanel(db, { since = null, limit = 3, rootDir = process.cwd()
|
|
|
256
254
|
changes,
|
|
257
255
|
tasks: taskCounts,
|
|
258
256
|
sessions,
|
|
259
|
-
|
|
257
|
+
transitions,
|
|
260
258
|
by_runtime,
|
|
261
259
|
top_tasks,
|
|
262
260
|
total_cost_usd,
|
|
@@ -315,7 +313,8 @@ function renderHuman(panel) {
|
|
|
315
313
|
lines.push(
|
|
316
314
|
`Sessions: running=${panel.sessions.running} crashed=${panel.sessions.crashed} orphan=${panel.sessions.orphan}`,
|
|
317
315
|
);
|
|
318
|
-
lines.push(`
|
|
316
|
+
lines.push(`Allowed transitions: ${panel.transitions.allowed.join(', ') || 'none'}`);
|
|
317
|
+
if (panel.transitions.required) lines.push(`Required transition: ${panel.transitions.required}`);
|
|
319
318
|
lines.push(
|
|
320
319
|
`Evidence: test=${panel.evidence.test.status} review=${panel.evidence.review.status} delivery=${panel.evidence.delivery.status}`,
|
|
321
320
|
);
|
|
@@ -360,6 +359,11 @@ function resolveDbPath() {
|
|
|
360
359
|
return path.resolve('.ultra', 'state.db');
|
|
361
360
|
}
|
|
362
361
|
|
|
362
|
+
function resolveRootDir(dbPath) {
|
|
363
|
+
if (process.env.UBP_ROOT_DIR) return path.resolve(process.env.UBP_ROOT_DIR);
|
|
364
|
+
return path.dirname(path.dirname(dbPath));
|
|
365
|
+
}
|
|
366
|
+
|
|
363
367
|
function dispatch(args) {
|
|
364
368
|
let flags;
|
|
365
369
|
try { flags = parseFlags(args); } catch (err) { return fail('USAGE_ERROR', err.message); }
|
|
@@ -377,7 +381,7 @@ function dispatch(args) {
|
|
|
377
381
|
const Database = require('better-sqlite3');
|
|
378
382
|
const db = new Database(dbPath, { readonly: true });
|
|
379
383
|
try {
|
|
380
|
-
const rootDir =
|
|
384
|
+
const rootDir = resolveRootDir(dbPath);
|
|
381
385
|
const panel = buildStatusPanel(db, { since, limit: flags.limit, rootDir });
|
|
382
386
|
if (flags.json) {
|
|
383
387
|
emit({ ok: true, data: panel });
|
|
@@ -398,4 +402,5 @@ module.exports = {
|
|
|
398
402
|
renderHuman,
|
|
399
403
|
parseSince,
|
|
400
404
|
parseFlags,
|
|
405
|
+
resolveRootDir,
|
|
401
406
|
};
|
|
@@ -213,7 +213,7 @@ async function dispatchRestore(args) {
|
|
|
213
213
|
quarantined_state_path: path.join(recoveryDir, 'state.db'),
|
|
214
214
|
schema_version: initialized.schema_version,
|
|
215
215
|
schema_migration_backup_path: initialized.backup_path || null,
|
|
216
|
-
|
|
216
|
+
recovery_guidance: 'Run ultra-tools system doctor, then ultra-init to inspect baseline readiness.',
|
|
217
217
|
},
|
|
218
218
|
});
|
|
219
219
|
return 0;
|
|
@@ -284,7 +284,7 @@ async function dispatchRebaseline(args) {
|
|
|
284
284
|
: null,
|
|
285
285
|
baseline: initialized.baseline,
|
|
286
286
|
copied_files: initialized.copied_files,
|
|
287
|
-
|
|
287
|
+
recovery_guidance: 'Inspect the preserved evidence, run explicit adoption research, record the brownfield baseline, and obtain owner approval before convergence.',
|
|
288
288
|
},
|
|
289
289
|
});
|
|
290
290
|
return 0;
|
|
@@ -17,6 +17,7 @@ FLAGS (init-project):
|
|
|
17
17
|
--project-type <type> web | api | cli | fullstack | other
|
|
18
18
|
--stack <stack> tech stack descriptor (comma-separated ok)
|
|
19
19
|
--mode <mode> auto | greenfield | brownfield (default: auto)
|
|
20
|
+
--git-mode <mode> auto | initialize | skip (default: auto)
|
|
20
21
|
--scope <path> baseline scope; repeat for multiple paths (default: .)
|
|
21
22
|
--resume preserve existing .ultra/ and install only missing assets
|
|
22
23
|
--overwrite replace existing .ultra/ (backup created)
|
|
@@ -38,6 +39,7 @@ function parseInitFlags(args) {
|
|
|
38
39
|
case '--project-type': flags.project_type = args[++i]; break;
|
|
39
40
|
case '--stack': flags.stack = args[++i]; break;
|
|
40
41
|
case '--mode': flags.mode = args[++i]; break;
|
|
42
|
+
case '--git-mode': flags.git_mode = args[++i]; break;
|
|
41
43
|
case '--scope': flags.scope.push(args[++i]); break;
|
|
42
44
|
case '--resume': flags.resume = true; break;
|
|
43
45
|
case '--source-template': flags.source_template = args[++i]; break;
|
|
@@ -66,6 +68,7 @@ function dispatchInitProject(rawArgs) {
|
|
|
66
68
|
project_type: flags.project_type,
|
|
67
69
|
stack: flags.stack,
|
|
68
70
|
mode: flags.mode || 'auto',
|
|
71
|
+
git_mode: flags.git_mode || 'auto',
|
|
69
72
|
scope: flags.scope.length > 0 ? flags.scope : undefined,
|
|
70
73
|
resume: !!flags.resume,
|
|
71
74
|
overwrite: !!flags.overwrite,
|