@kontextmind/kxm 0.7.40 → 0.7.43
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +41 -7
- package/docs/README.md +5 -3
- package/docs/agent-skills.md +1 -1
- package/docs/architecture.md +1 -1
- package/docs/configuration.md +28 -5
- package/docs/{vnext → contracts}/README.md +7 -7
- package/docs/{vnext → contracts}/architecture.md +2 -2
- package/docs/{vnext → contracts}/migration.md +25 -25
- package/docs/{vnext → contracts}/routing.md +2 -2
- package/docs/{vnext → contracts}/synchronization.md +1 -1
- package/docs/{vnext → contracts}/validation.md +7 -7
- package/docs/getting-started.md +1 -1
- package/docs/kb/qa-authentik-authentication.md +47 -0
- package/docs/kb/qa-extension-install-and-hub-bootstrap.md +68 -0
- package/docs/kb/qa-hub-on-a-public-host.md +31 -0
- package/docs/kb/qa-sqlite-vs-duckdb.md +18 -0
- package/docs/kb/qa-what-the-hub-stores.md +47 -0
- package/docs/packages.md +91 -0
- package/docs/templates/architecture.md +1 -1
- package/docs/test-matrix.md +6 -6
- package/docs/tui-components.md +131 -0
- package/examples/README.md +2 -2
- package/examples/{vnext → project}/.kxm/agents/critic-3.yaml +1 -1
- package/examples/{vnext → project}/README.md +4 -4
- package/package.json +18 -8
- package/packages/core/tui/CHANGELOG.md +19 -0
- package/packages/core/tui/LICENSE +21 -0
- package/packages/core/tui/README.md +45 -0
- package/packages/core/tui/dist/index.js +1439 -0
- package/packages/core/tui/src/adapters/pi.ts +73 -0
- package/packages/core/tui/src/adapters/terminal.ts +106 -0
- package/packages/core/tui/src/exports/index.ts +30 -0
- package/packages/core/tui/src/services/registry.ts +274 -0
- package/packages/core/tui/src/tui/keys.ts +130 -0
- package/packages/core/tui/src/tui/layout.ts +117 -0
- package/packages/core/tui/src/tui/panel.ts +435 -0
- package/packages/core/tui/src/tui/panelComponent.ts +208 -0
- package/packages/core/tui/src/tui/render.ts +309 -0
- package/packages/core/tui/src/tui/theme.ts +145 -0
- package/packages/core/tui/src/types/surface.ts +407 -0
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +681 -553
- package/plugins/kxm/dist/extension.js +18 -18
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/{vnext-runtime-supervisor.js → runtime-supervisor.js} +553 -553
- package/plugins/kxm/dist/runtime.js +608 -608
- package/plugins/kxm/dist/server.js +13 -13
- package/plugins/kxm/package.json +2 -2
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +2 -2
- package/plugins/kxm/skills/kxm-runs/SKILL.md +3 -3
- package/plugins/kxm/skills/kxm-session/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-workflow/SKILL.md +1 -1
- package/plugins/kxm/src/autocomplete.ts +4 -4
- package/plugins/kxm/src/{vnext-bindings.ts → bindings.ts} +48 -48
- package/plugins/kxm/src/cli/hub.ts +3 -3
- package/plugins/kxm/src/cli/{vnext.ts → project.ts} +106 -106
- package/plugins/kxm/src/cli/roles.ts +9 -9
- package/plugins/kxm/src/cli/system.ts +2 -2
- package/plugins/kxm/src/cli/tasks.ts +8 -8
- package/plugins/kxm/src/cli/workflows.ts +8 -8
- package/plugins/kxm/src/cli.ts +47 -47
- package/plugins/kxm/src/config.ts +69 -14
- package/plugins/kxm/src/database.ts +4 -4
- package/plugins/kxm/src/{vnext-engine-artifacts.ts → engine-artifacts.ts} +7 -7
- package/plugins/kxm/src/{vnext-engine-command.ts → engine-command.ts} +40 -40
- package/plugins/kxm/src/{vnext-engine-compile.ts → engine-compile.ts} +64 -64
- package/plugins/kxm/src/{vnext-engine-evidence.ts → engine-evidence.ts} +26 -26
- package/plugins/kxm/src/{vnext-engine-fold.ts → engine-fold.ts} +99 -99
- package/plugins/kxm/src/{vnext-engine-gate-records.ts → engine-gate-records.ts} +105 -105
- package/plugins/kxm/src/{vnext-engine-plan.ts → engine-plan.ts} +69 -69
- package/plugins/kxm/src/{vnext-engine.ts → engine.ts} +502 -502
- package/plugins/kxm/src/gate-hash.ts +10 -0
- package/plugins/kxm/src/{vnext-harness.ts → harness.ts} +1 -1
- package/plugins/kxm/src/hub.ts +1 -1
- package/plugins/kxm/src/init-guide-setup.ts +3 -3
- package/plugins/kxm/src/{vnext-init.ts → init.ts} +93 -93
- package/plugins/kxm/src/kxm-install-kind.ts +1 -1
- package/plugins/kxm/src/kxm-update-config.ts +2 -2
- package/plugins/kxm/src/local-snapshot.ts +23 -23
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/{vnext-migrate.ts → migrate.ts} +123 -123
- package/plugins/kxm/src/model-inventory.ts +1 -1
- package/plugins/kxm/src/{vnext-oneshot-evidence.ts → oneshot-evidence.ts} +2 -2
- package/plugins/kxm/src/{vnext-oneshot-process.ts → oneshot-process.ts} +4 -4
- package/plugins/kxm/src/{vnext-oneshot-producer.ts → oneshot-producer.ts} +24 -24
- package/plugins/kxm/src/{vnext-permission.ts → permission.ts} +86 -86
- package/plugins/kxm/src/{vnext-pi-producer.ts → pi-producer.ts} +13 -13
- package/plugins/kxm/src/{vnext-config.ts → project-config.ts} +177 -177
- package/plugins/kxm/src/{vnext-repair.ts → repair.ts} +159 -159
- package/plugins/kxm/src/restricted-yaml.d.mts +3 -3
- package/plugins/kxm/src/restricted-yaml.mjs +4 -4
- package/plugins/kxm/src/{vnext-runtime-owner.ts → runtime-owner.ts} +35 -35
- package/plugins/kxm/src/{vnext-runtime.ts → runtime-service.ts} +136 -136
- package/plugins/kxm/src/{vnext-runtime-store.ts → runtime-store.ts} +145 -145
- package/plugins/kxm/src/{vnext-runtime-supervisor.ts → runtime-supervisor.ts} +80 -80
- package/plugins/kxm/src/runtime.ts +6 -6
- package/plugins/kxm/src/session-work.ts +3 -3
- package/plugins/kxm/src/studio-layout.ts +6 -6
- package/plugins/kxm/src/{vnext-template.ts → template.ts} +33 -33
- package/plugins/kxm/src/tui.ts +10 -24
- package/schemas/{vnext/README.md → README.md} +3 -3
- package/schemas/{vnext/agent.schema.json → agent.schema.json} +1 -1
- package/schemas/{vnext/assignment-result.schema.json → assignment-result.schema.json} +1 -1
- package/schemas/{vnext/backup-manifest.schema.json → backup-manifest.schema.json} +1 -1
- package/schemas/{vnext/candidate.schema.json → candidate.schema.json} +1 -1
- package/schemas/{vnext/common.schema.json → common.schema.json} +2 -2
- package/schemas/{vnext/context-candidate.schema.json → context-candidate.schema.json} +1 -1
- package/schemas/{vnext/context-packet.schema.json → context-packet.schema.json} +1 -1
- package/schemas/{vnext/delivery-manifest.schema.json → delivery-manifest.schema.json} +1 -1
- package/schemas/{vnext/drive-receipt.schema.json → drive-receipt.schema.json} +2 -2
- package/schemas/{vnext/environment.schema.json → environment.schema.json} +1 -1
- package/schemas/{vnext/gate-registry.schema.json → gate-registry.schema.json} +1 -1
- package/schemas/{vnext/handoff-manifest.schema.json → handoff-manifest.schema.json} +1 -1
- package/schemas/{vnext/init-operation.schema.json → init-operation.schema.json} +1 -1
- package/schemas/{vnext/local-repository-bindings.schema.json → local-repository-bindings.schema.json} +1 -1
- package/schemas/{vnext/memory-record.schema.json → memory-record.schema.json} +1 -1
- package/schemas/{vnext/migration-decision.schema.json → migration-decision.schema.json} +1 -1
- package/schemas/{vnext/migration-plan.schema.json → migration-plan.schema.json} +1 -1
- package/schemas/{vnext/migration-receipt.schema.json → migration-receipt.schema.json} +1 -1
- package/schemas/{vnext/model.schema.json → model.schema.json} +1 -1
- package/schemas/{vnext/modes.schema.json → modes.schema.json} +1 -1
- package/schemas/{vnext/permission-diff.schema.json → permission-diff.schema.json} +1 -1
- package/schemas/policy-draft/README.md +2 -2
- package/schemas/{vnext/prices.schema.json → prices.schema.json} +1 -1
- package/schemas/{vnext/project.schema.json → project.schema.json} +1 -1
- package/schemas/{vnext/repository.schema.json → repository.schema.json} +1 -1
- package/schemas/{vnext/role.schema.json → role.schema.json} +1 -1
- package/schemas/{vnext/run-event.schema.json → run-event.schema.json} +1 -1
- package/schemas/{vnext/session-brief.schema.json → session-brief.schema.json} +2 -2
- package/schemas/{vnext/sync-event.schema.json → sync-event.schema.json} +1 -1
- package/schemas/{vnext/template-provenance.schema.json → template-provenance.schema.json} +1 -1
- package/schemas/{vnext/workflow.schema.json → workflow.schema.json} +1 -1
- package/scripts/build-package.mjs +59 -0
- package/scripts/build-runtime.mjs +3 -2
- package/scripts/check-generated.mjs +2 -1
- package/scripts/check-versions.mjs +12 -1
- package/scripts/docker-install-smoke.mjs +268 -0
- package/scripts/emit-codex-artifacts.mjs +1 -1
- package/scripts/kxm-bump-version.mjs +53 -3
- package/scripts/kxm-runtime-supervisor.mjs +3 -3
- package/scripts/package-surfaces.mjs +39 -0
- package/plugins/kxm/src/vnext-gate-hash.ts +0 -10
- /package/docs/{vnext → contracts}/effects-and-recovery.md +0 -0
- /package/docs/{vnext → contracts}/lifecycles.md +0 -0
- /package/docs/{vnext → contracts}/terminology.md +0 -0
- /package/examples/{vnext → project}/.kxm/agents/coordinator.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/critic-1.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/critic-2.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/implementer.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/planner.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/reproducer.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/agents/reviewer.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/gates.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/critic-claude.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/critic-gemini.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/critic-grok.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/implementation.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/models/primary.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/prices.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/project/env.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/project.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/repo/repo.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/workflows/default.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/workflows/fix.yaml +0 -0
- /package/examples/{vnext → project}/.kxm/workflows/improve.yaml +0 -0
- /package/examples/{vnext → project}/records/assignment-result-recorded.json +0 -0
- /package/examples/{vnext → project}/records/assignment-result.json +0 -0
- /package/examples/{vnext → project}/records/context-candidate.json +0 -0
- /package/examples/{vnext → project}/records/delivery-manifest.json +0 -0
- /package/examples/{vnext → project}/records/effect-uncertainty-resolved-sync.json +0 -0
- /package/examples/{vnext → project}/records/effect-uncertainty-resolved.json +0 -0
- /package/examples/{vnext → project}/records/run-created.json +0 -0
- /package/examples/{vnext → project}/records/sync-event.json +0 -0
- /package/examples/{vnext → project}/repositories/api/.kxm/repo/env.yaml +0 -0
- /package/examples/{vnext → project}/repositories/api/.kxm/repo/repo.yaml +0 -0
- /package/examples/{vnext → project}/repositories/web/.kxm/repo/repo.yaml +0 -0
|
@@ -7,25 +7,25 @@ import { createBackup, restoreBackup } from "../database.ts";
|
|
|
7
7
|
import { refreshModelInventory } from "../model-inventory.ts";
|
|
8
8
|
import { listInventoryModels, listRoleBindings, loadRoutePolicy, setRouteState, updateRouteState } from "../routes.ts";
|
|
9
9
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
type
|
|
13
|
-
} from "../
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
10
|
+
KxmConfigError,
|
|
11
|
+
discoverKxmProjectRoot,
|
|
12
|
+
type KxmInitializationPlan,
|
|
13
|
+
} from "../project-config.ts";
|
|
14
|
+
import { initializeKxmProject } from "../init.ts";
|
|
15
|
+
import { applyKxmMigration, planKxmMigration, verifyKxmMigration } from "../migrate.ts";
|
|
16
|
+
import { diffKxmProjectAgainstRevision, formatKxmPermissionDiff } from "../permission.ts";
|
|
17
|
+
import { readKxmLocalBindings, kxmUserStateRoot } from "../bindings.ts";
|
|
18
|
+
import { loadKxmProject } from "../project-config.ts";
|
|
19
19
|
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
} from "../
|
|
24
|
-
import {
|
|
20
|
+
ensureKxmSupervisor,
|
|
21
|
+
kxmRuntimeRequest,
|
|
22
|
+
kxmSupervisorStatus,
|
|
23
|
+
} from "../runtime-supervisor.ts";
|
|
24
|
+
import { kxmRuntimePaths } from "../runtime-store.ts";
|
|
25
25
|
import {
|
|
26
26
|
formatHarnessInventory,
|
|
27
27
|
probeHarnessesAsync,
|
|
28
|
-
} from "../
|
|
28
|
+
} from "../harness.ts";
|
|
29
29
|
import {
|
|
30
30
|
fetchLatestKxmVersion,
|
|
31
31
|
kxmReleaseAssetName,
|
|
@@ -42,12 +42,12 @@ import { loadKxmUpdateConfig } from "../kxm-update-config.ts";
|
|
|
42
42
|
import type { InstallKindReport, InstallProbe } from "../kxm-install-kind.ts";
|
|
43
43
|
import { print, type CliIo, type CliSpawnResult, type Runtime } from "./types.ts";
|
|
44
44
|
|
|
45
|
-
export const
|
|
46
|
-
ensureSupervisor?: typeof
|
|
47
|
-
runtimeRequest?: typeof
|
|
45
|
+
export const kxmDriveCliSeams: {
|
|
46
|
+
ensureSupervisor?: typeof ensureKxmSupervisor;
|
|
47
|
+
runtimeRequest?: typeof kxmRuntimeRequest;
|
|
48
48
|
} = {};
|
|
49
49
|
|
|
50
|
-
export function initPlanPayload(plan:
|
|
50
|
+
export function initPlanPayload(plan: KxmInitializationPlan): Record<string, unknown> {
|
|
51
51
|
return {
|
|
52
52
|
mode: plan.mode,
|
|
53
53
|
inspectedFrom: plan.inspectedFrom,
|
|
@@ -67,7 +67,7 @@ export function explicitRepositoryBindings(values: readonly string[]): Readonly<
|
|
|
67
67
|
const repositoryId = separator < 0 ? "" : value.slice(0, separator).trim();
|
|
68
68
|
const path = separator < 0 ? "" : value.slice(separator + 1).trim();
|
|
69
69
|
if (!repositoryId || !path) {
|
|
70
|
-
throw new
|
|
70
|
+
throw new KxmConfigError([{
|
|
71
71
|
phase: "discovery",
|
|
72
72
|
code: "repository_binding_argument_invalid",
|
|
73
73
|
file: "--repository",
|
|
@@ -75,7 +75,7 @@ export function explicitRepositoryBindings(values: readonly string[]): Readonly<
|
|
|
75
75
|
}]);
|
|
76
76
|
}
|
|
77
77
|
if (Object.hasOwn(result, repositoryId)) {
|
|
78
|
-
throw new
|
|
78
|
+
throw new KxmConfigError([{
|
|
79
79
|
phase: "discovery",
|
|
80
80
|
code: "repository_binding_argument_duplicate",
|
|
81
81
|
file: "--repository",
|
|
@@ -87,7 +87,7 @@ export function explicitRepositoryBindings(values: readonly string[]): Readonly<
|
|
|
87
87
|
return result;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export async function
|
|
90
|
+
export async function cmdKxmInit(
|
|
91
91
|
runtime: Runtime,
|
|
92
92
|
options: { name?: string | undefined; projectId?: string | undefined; repository?: string[] | undefined },
|
|
93
93
|
postHooks?: {
|
|
@@ -104,11 +104,11 @@ export async function cmdVnextInit(
|
|
|
104
104
|
return 2;
|
|
105
105
|
}
|
|
106
106
|
try {
|
|
107
|
-
const initialized =
|
|
107
|
+
const initialized = initializeKxmProject(runtime.cwd, {
|
|
108
108
|
...(options.name?.trim() ? { projectName: options.name.trim() } : {}),
|
|
109
109
|
...(options.projectId?.trim() ? { projectId: options.projectId.trim() } : {}),
|
|
110
110
|
repositoryBindings: explicitRepositoryBindings(options.repository ?? []),
|
|
111
|
-
localStateRoot:
|
|
111
|
+
localStateRoot: kxmUserStateRoot({ env: runtime.env }),
|
|
112
112
|
dryRun: runtime.dryRun,
|
|
113
113
|
});
|
|
114
114
|
const payload = {
|
|
@@ -132,21 +132,21 @@ export async function cmdVnextInit(
|
|
|
132
132
|
if (initialized.action === "created") {
|
|
133
133
|
if (postHooks?.maybeOfferCompletionInstall) await postHooks.maybeOfferCompletionInstall(runtime);
|
|
134
134
|
if (postHooks?.maybeOfferGuideSetup) await postHooks.maybeOfferGuideSetup(runtime);
|
|
135
|
-
return finishInit(0, `initialized
|
|
135
|
+
return finishInit(0, `initialized KXM project at ${initialized.projectRoot ?? runtime.cwd}`);
|
|
136
136
|
}
|
|
137
137
|
if (initialized.action === "joined") {
|
|
138
138
|
if (postHooks?.maybeOfferCompletionInstall) await postHooks.maybeOfferCompletionInstall(runtime);
|
|
139
139
|
if (postHooks?.maybeOfferGuideSetup) await postHooks.maybeOfferGuideSetup(runtime);
|
|
140
|
-
return finishInit(0, `joined
|
|
140
|
+
return finishInit(0, `joined KXM project at ${initialized.projectRoot ?? runtime.cwd}`);
|
|
141
141
|
}
|
|
142
142
|
if (initialized.action === "repaired") {
|
|
143
|
-
return finishInit(0, `repaired
|
|
143
|
+
return finishInit(0, `repaired KXM project at ${initialized.projectRoot ?? runtime.cwd}`);
|
|
144
144
|
}
|
|
145
145
|
if (initialized.action === "resumed") {
|
|
146
|
-
return finishInit(0, `resumed
|
|
146
|
+
return finishInit(0, `resumed KXM ${initialized.transactionKind ?? "initialization"} at ${initialized.projectRoot ?? runtime.cwd}`);
|
|
147
147
|
}
|
|
148
148
|
if (initialized.action === "validated") {
|
|
149
|
-
return finishInit(0, `validated
|
|
149
|
+
return finishInit(0, `validated KXM project at ${initialized.projectRoot ?? runtime.cwd}`);
|
|
150
150
|
}
|
|
151
151
|
if (runtime.dryRun) {
|
|
152
152
|
return finishInit(0, `init plan: ${initialized.plan.mode}`);
|
|
@@ -155,28 +155,28 @@ export async function cmdVnextInit(
|
|
|
155
155
|
? "legacy state requires reviewed migration; conversion is not available in this implementation slice"
|
|
156
156
|
: initialized.repairPlan?.issues.length
|
|
157
157
|
? "managed-template repair is blocked by conflicts or authority changes; local files were preserved"
|
|
158
|
-
: "partial or provenance-free
|
|
158
|
+
: "partial or provenance-free KXM state requires explicit repair; no files were overwritten";
|
|
159
159
|
return finishInit(1, next);
|
|
160
160
|
} catch (error) {
|
|
161
|
-
if (error instanceof
|
|
161
|
+
if (error instanceof KxmConfigError) {
|
|
162
162
|
print(runtime.io, runtime.json, {
|
|
163
163
|
ok: false,
|
|
164
164
|
command: "init",
|
|
165
|
-
error: "
|
|
165
|
+
error: "initialization_failed",
|
|
166
166
|
issues: error.issues,
|
|
167
|
-
}, `
|
|
167
|
+
}, `KXM initialization failed: ${error.message}`);
|
|
168
168
|
return 1;
|
|
169
169
|
}
|
|
170
170
|
print(runtime.io, runtime.json, {
|
|
171
171
|
ok: false,
|
|
172
172
|
command: "init",
|
|
173
|
-
error: "
|
|
174
|
-
}, "
|
|
173
|
+
error: "initialization_io_failed",
|
|
174
|
+
}, "KXM initialization failed because a local filesystem operation did not complete");
|
|
175
175
|
return 1;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
export async function
|
|
179
|
+
export async function cmdKxmMigratePlan(runtime: Runtime): Promise<number> {
|
|
180
180
|
if (runtime.workspaceFlag !== undefined) {
|
|
181
181
|
print(runtime.io, runtime.json, {
|
|
182
182
|
ok: false,
|
|
@@ -186,7 +186,7 @@ export async function cmdVnextMigratePlan(runtime: Runtime): Promise<number> {
|
|
|
186
186
|
return 2;
|
|
187
187
|
}
|
|
188
188
|
try {
|
|
189
|
-
const result =
|
|
189
|
+
const result = planKxmMigration(runtime.cwd, {});
|
|
190
190
|
const ambiguities = (result.plan.ambiguities as Array<{ key: string; message: string }> | undefined) ?? [];
|
|
191
191
|
const unmapped = (result.plan.unmapped as unknown[] | undefined) ?? [];
|
|
192
192
|
const payload = {
|
|
@@ -207,7 +207,7 @@ export async function cmdVnextMigratePlan(runtime: Runtime): Promise<number> {
|
|
|
207
207
|
);
|
|
208
208
|
return 1;
|
|
209
209
|
} catch (error) {
|
|
210
|
-
if (error instanceof
|
|
210
|
+
if (error instanceof KxmConfigError) {
|
|
211
211
|
print(runtime.io, runtime.json, { ok: false, command: "migrate plan", error: "migration_plan_failed", issues: error.issues }, `migration plan failed: ${error.message}`);
|
|
212
212
|
return 1;
|
|
213
213
|
}
|
|
@@ -216,7 +216,7 @@ export async function cmdVnextMigratePlan(runtime: Runtime): Promise<number> {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
export async function
|
|
219
|
+
export async function cmdKxmMigrateApply(runtime: Runtime, options: { decisions?: string | undefined; projectId?: string | undefined; name?: string | undefined }): Promise<number> {
|
|
220
220
|
if (runtime.workspaceFlag !== undefined) {
|
|
221
221
|
print(runtime.io, runtime.json, {
|
|
222
222
|
ok: false,
|
|
@@ -226,11 +226,11 @@ export async function cmdVnextMigrateApply(runtime: Runtime, options: { decision
|
|
|
226
226
|
return 2;
|
|
227
227
|
}
|
|
228
228
|
try {
|
|
229
|
-
const result =
|
|
229
|
+
const result = applyKxmMigration(runtime.cwd, {
|
|
230
230
|
...(options.decisions?.trim() ? { decisionsFile: options.decisions.trim() } : {}),
|
|
231
231
|
...(options.projectId?.trim() ? { projectId: options.projectId.trim() } : {}),
|
|
232
232
|
...(options.name?.trim() ? { projectName: options.name.trim() } : {}),
|
|
233
|
-
localStateRoot:
|
|
233
|
+
localStateRoot: kxmUserStateRoot({ env: runtime.env }),
|
|
234
234
|
dryRun: runtime.dryRun,
|
|
235
235
|
});
|
|
236
236
|
const payload = {
|
|
@@ -263,7 +263,7 @@ export async function cmdVnextMigrateApply(runtime: Runtime, options: { decision
|
|
|
263
263
|
);
|
|
264
264
|
return 1;
|
|
265
265
|
} catch (error) {
|
|
266
|
-
if (error instanceof
|
|
266
|
+
if (error instanceof KxmConfigError) {
|
|
267
267
|
print(runtime.io, runtime.json, { ok: false, command: "migrate apply", error: "migration_apply_failed", issues: error.issues }, `migration apply failed: ${error.message}`);
|
|
268
268
|
return 1;
|
|
269
269
|
}
|
|
@@ -272,7 +272,7 @@ export async function cmdVnextMigrateApply(runtime: Runtime, options: { decision
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
export async function
|
|
275
|
+
export async function cmdKxmMigrateVerify(runtime: Runtime): Promise<number> {
|
|
276
276
|
if (runtime.workspaceFlag !== undefined) {
|
|
277
277
|
print(runtime.io, runtime.json, {
|
|
278
278
|
ok: false,
|
|
@@ -281,11 +281,11 @@ export async function cmdVnextMigrateVerify(runtime: Runtime): Promise<number> {
|
|
|
281
281
|
}, "kxm migrate discovers the authoritative Git root from the current directory; --workspace is not supported");
|
|
282
282
|
return 2;
|
|
283
283
|
}
|
|
284
|
-
let result: ReturnType<typeof
|
|
284
|
+
let result: ReturnType<typeof verifyKxmMigration>;
|
|
285
285
|
try {
|
|
286
|
-
result =
|
|
286
|
+
result = verifyKxmMigration(runtime.cwd, {});
|
|
287
287
|
} catch (error) {
|
|
288
|
-
if (error instanceof
|
|
288
|
+
if (error instanceof KxmConfigError) {
|
|
289
289
|
print(runtime.io, runtime.json, { ok: false, command: "migrate verify", error: "migration_verify_failed", issues: error.issues }, `migration verification failed: ${error.message}`);
|
|
290
290
|
return 1;
|
|
291
291
|
}
|
|
@@ -327,7 +327,7 @@ export async function cmdBackup(runtime: Runtime, options: { out?: string | unde
|
|
|
327
327
|
print(runtime.io, runtime.json, payload, summary);
|
|
328
328
|
return 0;
|
|
329
329
|
} catch (error) {
|
|
330
|
-
if (error instanceof
|
|
330
|
+
if (error instanceof KxmConfigError) {
|
|
331
331
|
print(runtime.io, runtime.json, { ok: false, command: "backup", error: "backup_failed", issues: error.issues }, `backup failed: ${error.message}`);
|
|
332
332
|
return 1;
|
|
333
333
|
}
|
|
@@ -355,7 +355,7 @@ export async function cmdRestore(runtime: Runtime, manifestArg: string): Promise
|
|
|
355
355
|
print(runtime.io, runtime.json, payload, summary);
|
|
356
356
|
return 0;
|
|
357
357
|
} catch (error) {
|
|
358
|
-
if (error instanceof
|
|
358
|
+
if (error instanceof KxmConfigError) {
|
|
359
359
|
print(runtime.io, runtime.json, { ok: false, command: "restore", error: "restore_failed", issues: error.issues }, `restore failed: ${error.message}`);
|
|
360
360
|
return 1;
|
|
361
361
|
}
|
|
@@ -364,7 +364,7 @@ export async function cmdRestore(runtime: Runtime, manifestArg: string): Promise
|
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
export async function
|
|
367
|
+
export async function cmdKxmTrust(runtime: Runtime, check: boolean, options: { base?: string | undefined }): Promise<number> {
|
|
368
368
|
if (runtime.workspaceFlag !== undefined) {
|
|
369
369
|
print(runtime.io, runtime.json, {
|
|
370
370
|
ok: false,
|
|
@@ -375,9 +375,9 @@ export async function cmdVnextTrust(runtime: Runtime, check: boolean, options: {
|
|
|
375
375
|
}
|
|
376
376
|
const command = check ? "trust check" : "trust diff";
|
|
377
377
|
try {
|
|
378
|
-
const projectRoot =
|
|
379
|
-
const bindings =
|
|
380
|
-
const diff =
|
|
378
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd) ?? runtime.cwd;
|
|
379
|
+
const bindings = readKxmLocalBindings(projectRoot, { stateRoot: kxmUserStateRoot({ env: runtime.env }) });
|
|
380
|
+
const diff = diffKxmProjectAgainstRevision(projectRoot, options.base?.trim() || "HEAD", {
|
|
381
381
|
repositoryBindings: bindings?.repositories ?? {},
|
|
382
382
|
});
|
|
383
383
|
const payload = {
|
|
@@ -391,7 +391,7 @@ export async function cmdVnextTrust(runtime: Runtime, check: boolean, options: {
|
|
|
391
391
|
neutralChanges: diff.neutralChanges.length,
|
|
392
392
|
changes: diff.changes,
|
|
393
393
|
};
|
|
394
|
-
const text =
|
|
394
|
+
const text = formatKxmPermissionDiff(diff);
|
|
395
395
|
if (check && diff.requiresReview) {
|
|
396
396
|
print(runtime.io, runtime.json, payload, `${text}\ntrust check failed: review every expansion above before merging`);
|
|
397
397
|
return 1;
|
|
@@ -399,7 +399,7 @@ export async function cmdVnextTrust(runtime: Runtime, check: boolean, options: {
|
|
|
399
399
|
print(runtime.io, runtime.json, payload, text);
|
|
400
400
|
return 0;
|
|
401
401
|
} catch (error) {
|
|
402
|
-
if (error instanceof
|
|
402
|
+
if (error instanceof KxmConfigError) {
|
|
403
403
|
print(runtime.io, runtime.json, { ok: false, command, error: "trust_diff_failed", issues: error.issues }, `permission diff failed: ${error.message}`);
|
|
404
404
|
return 1;
|
|
405
405
|
}
|
|
@@ -411,7 +411,7 @@ export async function cmdVnextTrust(runtime: Runtime, check: boolean, options: {
|
|
|
411
411
|
export const RUN_ENGINE_PHASE = "pre-3a";
|
|
412
412
|
export const RUN_ENGINE_NOTICE = "runs remain created until the run engine lands; no steps execute yet";
|
|
413
413
|
|
|
414
|
-
export async function
|
|
414
|
+
export async function cmdKxmRun(runtime: Runtime, workflow: string | undefined, promptParts: string[]): Promise<number> {
|
|
415
415
|
if (runtime.workspaceFlag !== undefined) {
|
|
416
416
|
print(runtime.io, runtime.json, {
|
|
417
417
|
ok: false,
|
|
@@ -425,12 +425,12 @@ export async function cmdVnextRun(runtime: Runtime, workflow: string | undefined
|
|
|
425
425
|
return 2;
|
|
426
426
|
}
|
|
427
427
|
try {
|
|
428
|
-
const projectRoot =
|
|
428
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
429
429
|
if (!projectRoot) {
|
|
430
|
-
print(runtime.io, runtime.json, { ok: false, command: "run", error: "project_required" }, "kxm run requires a
|
|
430
|
+
print(runtime.io, runtime.json, { ok: false, command: "run", error: "project_required" }, "kxm run requires a KXM project (run kxm init first)");
|
|
431
431
|
return 1;
|
|
432
432
|
}
|
|
433
|
-
const bundle =
|
|
433
|
+
const bundle = loadKxmProject(projectRoot, {});
|
|
434
434
|
if (!bundle.workflows.has(workflow)) {
|
|
435
435
|
print(runtime.io, runtime.json, { ok: false, command: "run", error: "run_workflow_unknown", workflow }, `workflow ${workflow} does not exist in this project`);
|
|
436
436
|
return 1;
|
|
@@ -446,9 +446,9 @@ export async function cmdVnextRun(runtime: Runtime, workflow: string | undefined
|
|
|
446
446
|
}, `run plan: workflow ${workflow} at ${bundle.configRevision.slice(0, 19)}… (no run created)`);
|
|
447
447
|
return 0;
|
|
448
448
|
}
|
|
449
|
-
const supervisor = await
|
|
449
|
+
const supervisor = await ensureKxmSupervisor({ env: runtime.env });
|
|
450
450
|
const prompt = promptParts.join(" ").trim();
|
|
451
|
-
const acceptance = await
|
|
451
|
+
const acceptance = await kxmRuntimeRequest(supervisor, "POST", "/v1/runs", {
|
|
452
452
|
projectRoot,
|
|
453
453
|
workflowId: workflow,
|
|
454
454
|
prompt,
|
|
@@ -464,7 +464,7 @@ export async function cmdVnextRun(runtime: Runtime, workflow: string | undefined
|
|
|
464
464
|
}, `run ${run.status}: ${run.runId} (home ${run.homeRuntimeId.slice(0, 12)}…, config ${run.configRevision.slice(0, 19)}…)\n${RUN_ENGINE_NOTICE}`);
|
|
465
465
|
return 0;
|
|
466
466
|
} catch (error) {
|
|
467
|
-
if (error instanceof
|
|
467
|
+
if (error instanceof KxmConfigError) {
|
|
468
468
|
print(runtime.io, runtime.json, { ok: false, command: "run", error: "run_failed", issues: error.issues }, `run failed: ${error.message}`);
|
|
469
469
|
return 1;
|
|
470
470
|
}
|
|
@@ -473,7 +473,7 @@ export async function cmdVnextRun(runtime: Runtime, workflow: string | undefined
|
|
|
473
473
|
}
|
|
474
474
|
}
|
|
475
475
|
|
|
476
|
-
interface
|
|
476
|
+
interface KxmStatusDrive {
|
|
477
477
|
driveId?: string;
|
|
478
478
|
mode?: string;
|
|
479
479
|
openedAt?: string;
|
|
@@ -488,7 +488,7 @@ function formatCancelledStatus(reason: string): string {
|
|
|
488
488
|
return reason.length > 0 ? `cancelled (${reason})` : "cancelled";
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
-
function formatDriveStatusLine(runStatus: string, drive:
|
|
491
|
+
function formatDriveStatusLine(runStatus: string, drive: KxmStatusDrive | undefined): string | undefined {
|
|
492
492
|
if (!drive || typeof drive.driveId !== "string" || drive.driveId.length === 0) return undefined;
|
|
493
493
|
const receipt = drive.receipt ?? null;
|
|
494
494
|
if (receipt === null) {
|
|
@@ -521,24 +521,24 @@ function formatDriveStatusLine(runStatus: string, drive: VnextStatusDrive | unde
|
|
|
521
521
|
|
|
522
522
|
function formatRunStatusLine(
|
|
523
523
|
run: { runId: string; status: string; workflowId: string; updatedAt: string },
|
|
524
|
-
drive:
|
|
524
|
+
drive: KxmStatusDrive | undefined,
|
|
525
525
|
): string {
|
|
526
526
|
const reason = typeof drive?.receipt?.settlement?.reason === "string" ? drive.receipt.settlement.reason : "";
|
|
527
527
|
const statusLabel = run.status === "cancelled" ? formatCancelledStatus(reason) : run.status;
|
|
528
528
|
return `run ${run.runId}: ${statusLabel} (workflow ${run.workflowId}, updated ${run.updatedAt})`;
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
export async function
|
|
531
|
+
export async function cmdKxmRunStatus(runtime: Runtime, runId: string): Promise<number> {
|
|
532
532
|
try {
|
|
533
|
-
const projectRoot =
|
|
533
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
534
534
|
if (!projectRoot) {
|
|
535
|
-
print(runtime.io, runtime.json, { ok: false, command: "runs status", error: "project_required" }, "kxm runs status requires a
|
|
535
|
+
print(runtime.io, runtime.json, { ok: false, command: "runs status", error: "project_required" }, "kxm runs status requires a KXM project (run kxm init first)");
|
|
536
536
|
return 1;
|
|
537
537
|
}
|
|
538
|
-
const supervisor = await (
|
|
539
|
-
const result = await (
|
|
538
|
+
const supervisor = await (kxmDriveCliSeams.ensureSupervisor ?? ensureKxmSupervisor)({ env: runtime.env });
|
|
539
|
+
const result = await (kxmDriveCliSeams.runtimeRequest ?? kxmRuntimeRequest)(supervisor, "GET", `/v1/runs/${encodeURIComponent(runId)}?projectRoot=${encodeURIComponent(projectRoot)}`);
|
|
540
540
|
const run = result.run as { runId: string; status: string; workflowId: string; configRevision: string; updatedAt: string };
|
|
541
|
-
const drive = result.drive as
|
|
541
|
+
const drive = result.drive as KxmStatusDrive | undefined;
|
|
542
542
|
const driveLine = formatDriveStatusLine(run.status, drive);
|
|
543
543
|
print(
|
|
544
544
|
runtime.io,
|
|
@@ -548,7 +548,7 @@ export async function cmdVnextRunStatus(runtime: Runtime, runId: string): Promis
|
|
|
548
548
|
);
|
|
549
549
|
return 0;
|
|
550
550
|
} catch (error) {
|
|
551
|
-
if (error instanceof
|
|
551
|
+
if (error instanceof KxmConfigError) {
|
|
552
552
|
print(runtime.io, runtime.json, { ok: false, command: "runs status", error: "run_status_failed", issues: error.issues }, `run status failed: ${error.message}`);
|
|
553
553
|
return 1;
|
|
554
554
|
}
|
|
@@ -571,22 +571,22 @@ function sleepMs(ms: number): Promise<void> {
|
|
|
571
571
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
-
function driveWaitCompleted(drive:
|
|
574
|
+
function driveWaitCompleted(drive: KxmStatusDrive | undefined): boolean {
|
|
575
575
|
return drive?.verified === true
|
|
576
576
|
&& drive.receipt?.settlement?.kind === "terminal"
|
|
577
577
|
&& drive.receipt.settlement.status === "completed";
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
-
export async function
|
|
580
|
+
export async function cmdKxmRunDrive(
|
|
581
581
|
runtime: Runtime,
|
|
582
582
|
runId: string,
|
|
583
583
|
simulated: boolean,
|
|
584
584
|
options: { wait?: boolean; timeoutMs?: number | string } = {},
|
|
585
585
|
): Promise<number> {
|
|
586
586
|
try {
|
|
587
|
-
const projectRoot =
|
|
587
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
588
588
|
if (!projectRoot) {
|
|
589
|
-
print(runtime.io, runtime.json, { ok: false, command: "runs drive", error: "project_required" }, "kxm runs drive requires a
|
|
589
|
+
print(runtime.io, runtime.json, { ok: false, command: "runs drive", error: "project_required" }, "kxm runs drive requires a KXM project (run kxm init first)");
|
|
590
590
|
return 1;
|
|
591
591
|
}
|
|
592
592
|
const mode = simulated ? "simulated" : "live";
|
|
@@ -604,8 +604,8 @@ export async function cmdVnextRunDrive(
|
|
|
604
604
|
);
|
|
605
605
|
return 1;
|
|
606
606
|
}
|
|
607
|
-
const supervisor = await (
|
|
608
|
-
const request =
|
|
607
|
+
const supervisor = await (kxmDriveCliSeams.ensureSupervisor ?? ensureKxmSupervisor)({ env: runtime.env });
|
|
608
|
+
const request = kxmDriveCliSeams.runtimeRequest ?? kxmRuntimeRequest;
|
|
609
609
|
const result = await request(supervisor, "POST", `/v1/runs/${encodeURIComponent(runId)}/drive?projectRoot=${encodeURIComponent(projectRoot)}`, { mode });
|
|
610
610
|
const driveId = result.driveId;
|
|
611
611
|
const poll = result.poll;
|
|
@@ -629,7 +629,7 @@ export async function cmdVnextRunDrive(
|
|
|
629
629
|
let interval = 25;
|
|
630
630
|
while (true) {
|
|
631
631
|
const stateResult = await request(supervisor, "GET", `/v1/runs/${encodeURIComponent(runId)}?projectRoot=${encodeURIComponent(projectRoot)}`);
|
|
632
|
-
const drive = stateResult.drive as
|
|
632
|
+
const drive = stateResult.drive as KxmStatusDrive | undefined;
|
|
633
633
|
if (drive?.receipt) {
|
|
634
634
|
print(
|
|
635
635
|
runtime.io,
|
|
@@ -648,7 +648,7 @@ export async function cmdVnextRunDrive(
|
|
|
648
648
|
print(runtime.io, runtime.json, { ok: false, command: "runs drive", error: "timeout" }, "drive wait timed out");
|
|
649
649
|
return 1;
|
|
650
650
|
} catch (error) {
|
|
651
|
-
if (error instanceof
|
|
651
|
+
if (error instanceof KxmConfigError) {
|
|
652
652
|
print(runtime.io, runtime.json, { ok: false, command: "runs drive", error: "run_drive_failed", issues: error.issues }, `run drive failed: ${error.message}`);
|
|
653
653
|
return 1;
|
|
654
654
|
}
|
|
@@ -657,19 +657,19 @@ export async function cmdVnextRunDrive(
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
-
export async function
|
|
660
|
+
export async function cmdKxmRunCancel(runtime: Runtime, runId: string): Promise<number> {
|
|
661
661
|
try {
|
|
662
|
-
const projectRoot =
|
|
662
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
663
663
|
if (!projectRoot) {
|
|
664
|
-
print(runtime.io, runtime.json, { ok: false, command: "runs cancel", error: "project_required" }, "kxm runs cancel requires a
|
|
664
|
+
print(runtime.io, runtime.json, { ok: false, command: "runs cancel", error: "project_required" }, "kxm runs cancel requires a KXM project (run kxm init first)");
|
|
665
665
|
return 1;
|
|
666
666
|
}
|
|
667
667
|
if (runtime.dryRun) {
|
|
668
668
|
print(runtime.io, runtime.json, { ok: true, command: "runs cancel", dryRun: true, runId }, `cancel plan: run ${runId} (no events written)`);
|
|
669
669
|
return 0;
|
|
670
670
|
}
|
|
671
|
-
const supervisor = await
|
|
672
|
-
const result = await
|
|
671
|
+
const supervisor = await ensureKxmSupervisor({ env: runtime.env });
|
|
672
|
+
const result = await kxmRuntimeRequest(supervisor, "POST", `/v1/runs/${encodeURIComponent(runId)}/cancel?projectRoot=${encodeURIComponent(projectRoot)}`, {});
|
|
673
673
|
const run = result.run as { runId: string; status: string };
|
|
674
674
|
print(runtime.io, runtime.json, {
|
|
675
675
|
ok: true,
|
|
@@ -679,7 +679,7 @@ export async function cmdVnextRunCancel(runtime: Runtime, runId: string): Promis
|
|
|
679
679
|
}, `run ${run.runId}: ${run.status}`);
|
|
680
680
|
return 0;
|
|
681
681
|
} catch (error) {
|
|
682
|
-
if (error instanceof
|
|
682
|
+
if (error instanceof KxmConfigError) {
|
|
683
683
|
print(runtime.io, runtime.json, { ok: false, command: "runs cancel", error: "run_cancel_failed", issues: error.issues }, `run cancel failed: ${error.message}`);
|
|
684
684
|
return 1;
|
|
685
685
|
}
|
|
@@ -688,17 +688,17 @@ export async function cmdVnextRunCancel(runtime: Runtime, runId: string): Promis
|
|
|
688
688
|
}
|
|
689
689
|
}
|
|
690
690
|
|
|
691
|
-
export async function
|
|
691
|
+
export async function cmdKxmRunList(runtime: Runtime): Promise<number> {
|
|
692
692
|
try {
|
|
693
|
-
const projectRoot =
|
|
693
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
694
694
|
if (!projectRoot) {
|
|
695
|
-
print(runtime.io, runtime.json, { ok: false, command: "runs list", error: "project_required" }, "kxm runs list requires a
|
|
695
|
+
print(runtime.io, runtime.json, { ok: false, command: "runs list", error: "project_required" }, "kxm runs list requires a KXM project (run kxm init first)");
|
|
696
696
|
return 1;
|
|
697
697
|
}
|
|
698
|
-
const bundle =
|
|
698
|
+
const bundle = loadKxmProject(projectRoot, {});
|
|
699
699
|
const projectId = String(bundle.project.value.id);
|
|
700
|
-
const supervisor = await
|
|
701
|
-
const result = await
|
|
700
|
+
const supervisor = await ensureKxmSupervisor({ env: runtime.env });
|
|
701
|
+
const result = await kxmRuntimeRequest(supervisor, "GET", `/v1/projects/${encodeURIComponent(projectId)}/runs?projectRoot=${encodeURIComponent(projectRoot)}`);
|
|
702
702
|
const runs = (result.runs ?? []) as Array<{ runId: string; status: string; workflowId: string; createdAt: string }>;
|
|
703
703
|
print(
|
|
704
704
|
runtime.io,
|
|
@@ -708,7 +708,7 @@ export async function cmdVnextRunList(runtime: Runtime): Promise<number> {
|
|
|
708
708
|
);
|
|
709
709
|
return 0;
|
|
710
710
|
} catch (error) {
|
|
711
|
-
if (error instanceof
|
|
711
|
+
if (error instanceof KxmConfigError) {
|
|
712
712
|
print(runtime.io, runtime.json, { ok: false, command: "runs list", error: "run_list_failed", issues: error.issues }, `run list failed: ${error.message}`);
|
|
713
713
|
return 1;
|
|
714
714
|
}
|
|
@@ -789,15 +789,15 @@ export async function cmdModelInventoryRefresh(runtime: Runtime): Promise<number
|
|
|
789
789
|
return failed ? 1 : 0;
|
|
790
790
|
}
|
|
791
791
|
|
|
792
|
-
export async function
|
|
793
|
-
const paths =
|
|
792
|
+
export async function cmdKxmRuntime(runtime: Runtime, action: string): Promise<number> {
|
|
793
|
+
const paths = kxmRuntimePaths({ env: runtime.env });
|
|
794
794
|
try {
|
|
795
795
|
if (action === "start") {
|
|
796
796
|
if (runtime.dryRun) {
|
|
797
797
|
print(runtime.io, runtime.json, { ok: true, command: "runtime start", dryRun: true }, "runtime supervisor would auto-start");
|
|
798
798
|
return 0;
|
|
799
799
|
}
|
|
800
|
-
const supervisor = await
|
|
800
|
+
const supervisor = await ensureKxmSupervisor({ env: runtime.env });
|
|
801
801
|
print(runtime.io, runtime.json, {
|
|
802
802
|
ok: true,
|
|
803
803
|
command: "runtime start",
|
|
@@ -808,14 +808,14 @@ export async function cmdVnextRuntime(runtime: Runtime, action: string): Promise
|
|
|
808
808
|
return 0;
|
|
809
809
|
}
|
|
810
810
|
if (action === "status") {
|
|
811
|
-
const status =
|
|
811
|
+
const status = kxmSupervisorStatus(paths);
|
|
812
812
|
print(runtime.io, runtime.json, { ok: true, command: "runtime status", ...status }, status.running
|
|
813
813
|
? `runtime supervisor running: ${status.runtimeId} pid ${status.pid} on 127.0.0.1:${status.port}`
|
|
814
814
|
: "runtime supervisor is not running");
|
|
815
815
|
return status.running ? 0 : 1;
|
|
816
816
|
}
|
|
817
817
|
if (action === "stop") {
|
|
818
|
-
const status =
|
|
818
|
+
const status = kxmSupervisorStatus(paths);
|
|
819
819
|
if (!status.running || !status.port) {
|
|
820
820
|
print(runtime.io, runtime.json, { ok: true, command: "runtime stop", stopped: false }, "runtime supervisor is not running");
|
|
821
821
|
return 0;
|
|
@@ -824,15 +824,15 @@ export async function cmdVnextRuntime(runtime: Runtime, action: string): Promise
|
|
|
824
824
|
print(runtime.io, runtime.json, { ok: true, command: "runtime stop", dryRun: true }, `would stop runtime supervisor pid ${status.pid}`);
|
|
825
825
|
return 0;
|
|
826
826
|
}
|
|
827
|
-
const supervisor = await
|
|
828
|
-
await
|
|
827
|
+
const supervisor = await ensureKxmSupervisor({ env: runtime.env });
|
|
828
|
+
await kxmRuntimeRequest(supervisor, "POST", "/v1/shutdown", {});
|
|
829
829
|
print(runtime.io, runtime.json, { ok: true, command: "runtime stop", stopped: true }, `runtime supervisor ${status.runtimeId} stopping`);
|
|
830
830
|
return 0;
|
|
831
831
|
}
|
|
832
832
|
print(runtime.io, runtime.json, { ok: false, command: "runtime", error: "unknown_action" }, `unknown runtime action: ${action}`);
|
|
833
833
|
return 2;
|
|
834
834
|
} catch (error) {
|
|
835
|
-
if (error instanceof
|
|
835
|
+
if (error instanceof KxmConfigError) {
|
|
836
836
|
print(runtime.io, runtime.json, { ok: false, command: "runtime", error: "runtime_failed", issues: error.issues }, `runtime failed: ${error.message}`);
|
|
837
837
|
return 1;
|
|
838
838
|
}
|
|
@@ -841,15 +841,15 @@ export async function cmdVnextRuntime(runtime: Runtime, action: string): Promise
|
|
|
841
841
|
}
|
|
842
842
|
}
|
|
843
843
|
|
|
844
|
-
export async function
|
|
844
|
+
export async function cmdKxmRunReceipt(runtime: Runtime, runId: string, options: { all?: boolean } = {}): Promise<number> {
|
|
845
845
|
try {
|
|
846
|
-
const projectRoot =
|
|
846
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
847
847
|
if (!projectRoot) {
|
|
848
|
-
print(runtime.io, runtime.json, { ok: false, command: "runs receipt", error: "project_required" }, "kxm runs receipt requires a
|
|
848
|
+
print(runtime.io, runtime.json, { ok: false, command: "runs receipt", error: "project_required" }, "kxm runs receipt requires a KXM project (run kxm init first)");
|
|
849
849
|
return 1;
|
|
850
850
|
}
|
|
851
|
-
const supervisor = await (
|
|
852
|
-
const result = await (
|
|
851
|
+
const supervisor = await (kxmDriveCliSeams.ensureSupervisor ?? ensureKxmSupervisor)({ env: runtime.env });
|
|
852
|
+
const result = await (kxmDriveCliSeams.runtimeRequest ?? kxmRuntimeRequest)(
|
|
853
853
|
supervisor,
|
|
854
854
|
"GET",
|
|
855
855
|
`/v1/runs/${encodeURIComponent(runId)}/drive?projectRoot=${encodeURIComponent(projectRoot)}`,
|
|
@@ -874,7 +874,7 @@ export async function cmdVnextRunReceipt(runtime: Runtime, runId: string, option
|
|
|
874
874
|
print(runtime.io, runtime.json, { ok: true, command: "runs receipt", receipt: latest }, JSON.stringify(settlement, null, 2));
|
|
875
875
|
return 0;
|
|
876
876
|
} catch (error) {
|
|
877
|
-
if (error instanceof
|
|
877
|
+
if (error instanceof KxmConfigError) {
|
|
878
878
|
print(runtime.io, runtime.json, { ok: false, command: "runs receipt", error: "run_receipt_failed", issues: error.issues }, `run receipt failed: ${error.message}`);
|
|
879
879
|
return 1;
|
|
880
880
|
}
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
resolveRoleSeat,
|
|
18
18
|
type KxmRoleDefinition,
|
|
19
19
|
} from "../role.ts";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import { discoverKxmProjectRoot } from "../project-config.ts";
|
|
21
|
+
import { ensureKxmSupervisor, kxmRuntimeRequest } from "../runtime-supervisor.ts";
|
|
22
22
|
import { resumeWorkflowFromRuling, type WorkflowRun } from "../workflow.ts";
|
|
23
23
|
import { print, type CliIo, type Runtime } from "./types.ts";
|
|
24
24
|
|
|
@@ -517,16 +517,16 @@ export async function cmdRoleResume(
|
|
|
517
517
|
|
|
518
518
|
const effectiveRuling = ruling?.trim() || "operator_ruling: waived and resumed";
|
|
519
519
|
|
|
520
|
-
// Check if it's a
|
|
521
|
-
const projectRoot =
|
|
520
|
+
// Check if it's a KXM run
|
|
521
|
+
const projectRoot = discoverKxmProjectRoot(runtime.cwd);
|
|
522
522
|
if (projectRoot && /^run_[a-f0-9]{32}$/i.test(runId)) {
|
|
523
523
|
if (runtime.dryRun) {
|
|
524
|
-
print(runtime.io, runtime.json, { ok: true, command: "role resume", runId, ruling: effectiveRuling }, `would resume
|
|
524
|
+
print(runtime.io, runtime.json, { ok: true, command: "role resume", runId, ruling: effectiveRuling }, `would resume KXM run ${runId}`);
|
|
525
525
|
return 0;
|
|
526
526
|
}
|
|
527
527
|
try {
|
|
528
|
-
const supervisor = await
|
|
529
|
-
const posted = await
|
|
528
|
+
const supervisor = await ensureKxmSupervisor({ env: runtime.env });
|
|
529
|
+
const posted = await kxmRuntimeRequest(
|
|
530
530
|
supervisor,
|
|
531
531
|
"POST",
|
|
532
532
|
`/v1/runs/${encodeURIComponent(runId)}/signal?projectRoot=${encodeURIComponent(projectRoot)}`,
|
|
@@ -541,12 +541,12 @@ export async function cmdRoleResume(
|
|
|
541
541
|
runtime.io,
|
|
542
542
|
runtime.json,
|
|
543
543
|
{ ok: true, command: "role resume", runId, ruling: effectiveRuling, unblocked: posted.unblocked === true },
|
|
544
|
-
`Resumed
|
|
544
|
+
`Resumed KXM run ${runId} with ruling: ${effectiveRuling}\n`,
|
|
545
545
|
);
|
|
546
546
|
return 0;
|
|
547
547
|
} catch (error) {
|
|
548
548
|
const msg = error instanceof Error ? error.message : "resume_failed";
|
|
549
|
-
print(runtime.io, runtime.json, { ok: false, command: "role resume", error: "resume_failed", detail: msg }, `resume
|
|
549
|
+
print(runtime.io, runtime.json, { ok: false, command: "role resume", error: "resume_failed", detail: msg }, `resume KXM run failed: ${msg}\n`);
|
|
550
550
|
return 1;
|
|
551
551
|
}
|
|
552
552
|
}
|
|
@@ -83,8 +83,8 @@ import {
|
|
|
83
83
|
probeHarnessesAsync,
|
|
84
84
|
runHarnessUpdate,
|
|
85
85
|
type HarnessUpdateScope,
|
|
86
|
-
} from "../
|
|
87
|
-
import {
|
|
86
|
+
} from "../harness.ts";
|
|
87
|
+
import { kxmUserStateRoot } from "../bindings.ts";
|
|
88
88
|
import {
|
|
89
89
|
print,
|
|
90
90
|
printWorker,
|