@revisium/orchestrator 0.1.0-alpha.2 → 0.1.0-alpha.4
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/control-plane/bootstrap.config.json +103 -2
- package/control-plane/default-playbook/catalog/pipelines.json +360 -0
- package/control-plane/default-playbook/catalog/roles.json +56 -0
- package/control-plane/default-playbook/package.json +5 -0
- package/control-plane/default-playbook/playbook.json +13 -0
- package/control-plane/default-playbook/prompts/analyst.md +27 -0
- package/control-plane/default-playbook/prompts/developer.md +26 -0
- package/control-plane/default-playbook/prompts/integrator.md +20 -0
- package/control-plane/default-playbook/prompts/orchestrator.md +23 -0
- package/control-plane/default-playbook/prompts/reviewer.md +28 -0
- package/control-plane/default-playbook/prompts/watcher.md +24 -0
- package/dist/cli/commands/bootstrap.js +68 -7
- package/dist/cli/commands/bootstrap.js.map +1 -1
- package/dist/cli/commands/inbox.js +0 -21
- package/dist/cli/commands/inbox.js.map +1 -1
- package/dist/cli/commands/run.js +76 -49
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/needs-host.js +7 -8
- package/dist/cli/needs-host.js.map +1 -1
- package/dist/cli/program.js +0 -2
- package/dist/cli/program.js.map +1 -1
- package/dist/config.js +18 -1
- package/dist/config.js.map +1 -1
- package/dist/control-plane/client-transport.js +73 -40
- package/dist/control-plane/client-transport.js.map +1 -1
- package/dist/control-plane/data-access.js +3 -2
- package/dist/control-plane/data-access.js.map +1 -1
- package/dist/control-plane/definitions.js +1 -1
- package/dist/control-plane/definitions.js.map +1 -1
- package/dist/control-plane/json-fields.js +2 -0
- package/dist/control-plane/json-fields.js.map +1 -1
- package/dist/control-plane/schema-migration.js +86 -0
- package/dist/control-plane/schema-migration.js.map +1 -0
- package/dist/control-plane/seed-default-playbook.js +71 -0
- package/dist/control-plane/seed-default-playbook.js.map +1 -0
- package/dist/control-plane/tables.js +1 -0
- package/dist/control-plane/tables.js.map +1 -1
- package/dist/e2e/kit/agents.js +113 -0
- package/dist/e2e/kit/agents.js.map +1 -0
- package/dist/e2e/kit/assertions.js +119 -0
- package/dist/e2e/kit/assertions.js.map +1 -0
- package/dist/e2e/kit/crash.js +44 -0
- package/dist/e2e/kit/crash.js.map +1 -0
- package/dist/e2e/kit/drive.js +49 -0
- package/dist/e2e/kit/drive.js.map +1 -0
- package/dist/e2e/kit/env.js +16 -0
- package/dist/e2e/kit/env.js.map +1 -0
- package/dist/e2e/kit/fake-integrator.js +42 -0
- package/dist/e2e/kit/fake-integrator.js.map +1 -0
- package/dist/e2e/kit/gh-emulator.js +49 -0
- package/dist/e2e/kit/gh-emulator.js.map +1 -0
- package/dist/e2e/kit/git-target-repo.js +83 -0
- package/dist/e2e/kit/git-target-repo.js.map +1 -0
- package/dist/e2e/kit/harness.js +59 -0
- package/dist/e2e/kit/harness.js.map +1 -0
- package/dist/e2e/kit/index.js +14 -0
- package/dist/e2e/kit/index.js.map +1 -0
- package/dist/e2e/kit/mcp.js +32 -0
- package/dist/e2e/kit/mcp.js.map +1 -0
- package/dist/e2e/kit/scenarios.js +196 -0
- package/dist/e2e/kit/scenarios.js.map +1 -0
- package/dist/e2e/recovery-crash-child.js +29 -0
- package/dist/e2e/recovery-crash-child.js.map +1 -0
- package/dist/e2e/recovery-dd-crash-child.js +42 -0
- package/dist/e2e/recovery-dd-crash-child.js.map +1 -0
- package/dist/engine/ensure-postgres.js +13 -1
- package/dist/engine/ensure-postgres.js.map +1 -1
- package/dist/mcp/mcp-capabilities.js +1 -0
- package/dist/mcp/mcp-capabilities.js.map +1 -1
- package/dist/mcp/mcp-facade.service.js +24 -3
- package/dist/mcp/mcp-facade.service.js.map +1 -1
- package/dist/mcp/mcp-tools.js +16 -7
- package/dist/mcp/mcp-tools.js.map +1 -1
- package/dist/pipeline/data-driven-task.workflow.js +493 -0
- package/dist/pipeline/data-driven-task.workflow.js.map +1 -0
- package/dist/pipeline/data-driven-template.js +57 -0
- package/dist/pipeline/data-driven-template.js.map +1 -0
- package/dist/pipeline/develop-task.workflow.js +151 -316
- package/dist/pipeline/develop-task.workflow.js.map +1 -1
- package/dist/pipeline/pipeline.module.js +1 -1
- package/dist/pipeline/route-contract.js +82 -0
- package/dist/pipeline/route-contract.js.map +1 -0
- package/dist/pipeline-core/index.js +16 -0
- package/dist/pipeline-core/index.js.map +1 -0
- package/dist/pipeline-core/interpret.js +351 -0
- package/dist/pipeline-core/interpret.js.map +1 -0
- package/dist/pipeline-core/kit/assertions.js +61 -0
- package/dist/pipeline-core/kit/assertions.js.map +1 -0
- package/dist/pipeline-core/kit/builders.js +136 -0
- package/dist/pipeline-core/kit/builders.js.map +1 -0
- package/dist/pipeline-core/kit/drive.js +96 -0
- package/dist/pipeline-core/kit/drive.js.map +1 -0
- package/dist/pipeline-core/kit/fixtures.js +248 -0
- package/dist/pipeline-core/kit/fixtures.js.map +1 -0
- package/dist/pipeline-core/kit/index.js +13 -0
- package/dist/pipeline-core/kit/index.js.map +1 -0
- package/dist/pipeline-core/types.js +132 -0
- package/dist/pipeline-core/types.js.map +1 -0
- package/dist/pipeline-core/validate.js +1192 -0
- package/dist/pipeline-core/validate.js.map +1 -0
- package/dist/playbook/catalog-loader.js +14 -1
- package/dist/playbook/catalog-loader.js.map +1 -1
- package/dist/playbook/import-mapper.js +14 -38
- package/dist/playbook/import-mapper.js.map +1 -1
- package/dist/playbook/manifest.js +1 -1
- package/dist/revisium/playbooks.service.js +95 -17
- package/dist/revisium/playbooks.service.js.map +1 -1
- package/dist/revisium/roles.service.js +1 -1
- package/dist/revisium/roles.service.js.map +1 -1
- package/dist/revisium/run.service.js +16 -0
- package/dist/revisium/run.service.js.map +1 -1
- package/dist/run/append-event.js +24 -1
- package/dist/run/append-event.js.map +1 -1
- package/dist/run/block-run.js +17 -0
- package/dist/run/block-run.js.map +1 -0
- package/dist/run/create-run.js +28 -5
- package/dist/run/create-run.js.map +1 -1
- package/dist/run/inspect-run.js +9 -0
- package/dist/run/inspect-run.js.map +1 -1
- package/dist/run/run-outputs.js +88 -0
- package/dist/run/run-outputs.js.map +1 -0
- package/dist/run/terminal-run-status.js +89 -7
- package/dist/run/terminal-run-status.js.map +1 -1
- package/dist/runners/claude-code.service.js +4 -0
- package/dist/runners/claude-code.service.js.map +1 -1
- package/dist/runners/integrator.js +25 -9
- package/dist/runners/integrator.js.map +1 -1
- package/dist/task-control-plane/task-control-plane-api.service.js +247 -28
- package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -1
- package/dist/worker/artifact-store.js +111 -0
- package/dist/worker/artifact-store.js.map +1 -0
- package/dist/worker/build-context.js +17 -0
- package/dist/worker/build-context.js.map +1 -1
- package/dist/worker/claude-code-runner.js +44 -5
- package/dist/worker/claude-code-runner.js.map +1 -1
- package/dist/worker/process-executor.js +23 -2
- package/dist/worker/process-executor.js.map +1 -1
- package/dist/worker/runner-dispatch.js +1 -0
- package/dist/worker/runner-dispatch.js.map +1 -1
- package/dist/worker/runner.js +11 -1
- package/dist/worker/runner.js.map +1 -1
- package/dist/worker/stub-runner.js +7 -45
- package/dist/worker/stub-runner.js.map +1 -1
- package/package.json +3 -1
- package/dist/cli/commands/work.js +0 -149
- package/dist/cli/commands/work.js.map +0 -1
- package/dist/worker/git-worktree-manager.js +0 -84
- package/dist/worker/git-worktree-manager.js.map +0 -1
- package/dist/worker/loop.js +0 -122
- package/dist/worker/loop.js.map +0 -1
- package/dist/worker/script-runner.js +0 -28
- package/dist/worker/script-runner.js.map +0 -1
- package/dist/worker/worker-id.js +0 -18
- package/dist/worker/worker-id.js.map +0 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { HostLifecycle } from '../../host/host.lifecycle.js';
|
|
3
|
+
import { DbosService } from '../../engine/dbos.service.js';
|
|
4
|
+
import { createClientTransport } from '../../control-plane/client-transport.js';
|
|
5
|
+
import { RolesService } from '../../revisium/roles.service.js';
|
|
6
|
+
import { RunService } from '../../revisium/run.service.js';
|
|
7
|
+
import { InboxService } from '../../revisium/inbox.service.js';
|
|
8
|
+
import { PlaybooksService } from '../../revisium/playbooks.service.js';
|
|
9
|
+
import { PipelineService } from '../../pipeline/develop-task.workflow.js';
|
|
10
|
+
import { TaskControlPlaneApiService } from '../../task-control-plane/task-control-plane-api.service.js';
|
|
11
|
+
import { deterministicAgent } from './agents.js';
|
|
12
|
+
import { createGhEmulator } from './gh-emulator.js';
|
|
13
|
+
import { createFakeIntegrator } from './fake-integrator.js';
|
|
14
|
+
/**
|
|
15
|
+
* Boot the real host (DBOS + Revisium standalone + Postgres) with only the agent and `gh` faked.
|
|
16
|
+
* Mirrors the wiring of the production `AppModule` closely enough that the returned `api` behaves
|
|
17
|
+
* like the live MCP/CLI surface. Always pair with `harness.close()` (or {@link closeHarness}) in a
|
|
18
|
+
* `finally` block.
|
|
19
|
+
*/
|
|
20
|
+
export async function createRunHarness(opts = {}) {
|
|
21
|
+
const dbos = new DbosService();
|
|
22
|
+
const lifecycle = new HostLifecycle(dbos);
|
|
23
|
+
const draft = createClientTransport('draft');
|
|
24
|
+
const head = createClientTransport('head');
|
|
25
|
+
const roles = new RolesService(head);
|
|
26
|
+
const runs = new RunService(draft);
|
|
27
|
+
const inbox = new InboxService(draft);
|
|
28
|
+
const playbooks = new PlaybooksService(head);
|
|
29
|
+
const ghCalls = [];
|
|
30
|
+
const agentCalls = [];
|
|
31
|
+
const developerWrites = new Map();
|
|
32
|
+
const execGh = typeof opts.gh === 'function' ? opts.gh(ghCalls) : createGhEmulator(ghCalls, opts.gh);
|
|
33
|
+
const baseIntegrator = createFakeIntegrator(runs, execGh);
|
|
34
|
+
const integrator = opts.integrator ? opts.integrator(baseIntegrator) : baseIntegrator;
|
|
35
|
+
const agent = opts.agent
|
|
36
|
+
? opts.agent({ agentCalls, developerWrites })
|
|
37
|
+
: deterministicAgent(agentCalls, developerWrites);
|
|
38
|
+
const pipeline = new PipelineService(dbos, roles, runs, inbox, integrator, agent);
|
|
39
|
+
const api = new TaskControlPlaneApiService(runs, inbox, roles, playbooks, pipeline, dbos);
|
|
40
|
+
await lifecycle.onApplicationBootstrap();
|
|
41
|
+
return {
|
|
42
|
+
api,
|
|
43
|
+
dbos,
|
|
44
|
+
lifecycle,
|
|
45
|
+
agentCalls,
|
|
46
|
+
developerWrites,
|
|
47
|
+
ghCalls,
|
|
48
|
+
close: async () => {
|
|
49
|
+
await lifecycle.onApplicationShutdown();
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Null-safe teardown, for symmetry with `try { … } finally { await closeHarness(h); }`. */
|
|
54
|
+
export async function closeHarness(harness) {
|
|
55
|
+
if (!harness)
|
|
56
|
+
return;
|
|
57
|
+
await harness.close();
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../src/e2e/kit/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// reflect-metadata MUST load before any decorated (@Injectable) service module is evaluated.
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
export * from './env.js';
|
|
4
|
+
export * from './agents.js';
|
|
5
|
+
export * from './gh-emulator.js';
|
|
6
|
+
export * from './git-target-repo.js';
|
|
7
|
+
export * from './fake-integrator.js';
|
|
8
|
+
export * from './harness.js';
|
|
9
|
+
export * from './drive.js';
|
|
10
|
+
export * from './scenarios.js';
|
|
11
|
+
export * from './assertions.js';
|
|
12
|
+
export * from './crash.js';
|
|
13
|
+
export * from './mcp.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/e2e/kit/index.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,kBAAkB,CAAC;AAE1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { McpFacadeService } from '../../mcp/mcp-facade.service.js';
|
|
3
|
+
import { registerRevoMcpTools } from '../../mcp/mcp-tools.js';
|
|
4
|
+
/**
|
|
5
|
+
* Build the REAL MCP surface over the test API: the `McpFacadeService` + the tool handlers from
|
|
6
|
+
* `registerRevoMcpTools`, captured via a recording server so a test can invoke a tool by name
|
|
7
|
+
* in-process. This exercises the same schema validation, dispatch, and `{content:[{text}]}` result
|
|
8
|
+
* shape the live stdio server uses — i.e. the MCP layer itself, not just the underlying API.
|
|
9
|
+
*/
|
|
10
|
+
export function createMcpInvoker(api) {
|
|
11
|
+
const facade = new McpFacadeService(api);
|
|
12
|
+
const tools = new Map();
|
|
13
|
+
const recordingServer = {
|
|
14
|
+
registerTool(name, config, handler) {
|
|
15
|
+
tools.set(name, { inputSchema: config.inputSchema ?? {}, handler });
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
registerRevoMcpTools(recordingServer, facade);
|
|
19
|
+
return {
|
|
20
|
+
toolNames: [...tools.keys()],
|
|
21
|
+
async invoke(name, args = {}) {
|
|
22
|
+
const tool = tools.get(name);
|
|
23
|
+
if (!tool)
|
|
24
|
+
throw new Error(`unknown MCP tool: ${name}`);
|
|
25
|
+
const parsed = z.object(tool.inputSchema).parse(args); // SDK-equivalent validation (defaults + reject)
|
|
26
|
+
const result = (await tool.handler(parsed));
|
|
27
|
+
const text = result?.content?.[0]?.text;
|
|
28
|
+
return text === undefined ? result : JSON.parse(text);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/e2e/kit/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAgB9D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAA+B;IAC9D,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACzC,MAAM,eAAe,GAAG;QACtB,YAAY,CACV,IAAY,EACZ,MAAsD,EACtD,OAAmC;YAEnC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;KACsB,CAAC;IAC1B,oBAAoB,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAE9C,OAAO;QACL,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC5B,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;YACxD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,gDAAgD;YACvG,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAA2C,CAAC;YACtF,MAAM,IAAI,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;YACxC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { PLAYBOOK_SOURCE } from './env.js';
|
|
3
|
+
import { waitForGate } from './drive.js';
|
|
4
|
+
/** Playbook id installed by {@link givenInstalledPlaybook}. */
|
|
5
|
+
export const PLAYBOOK_ID = 'revisium-agent-playbook';
|
|
6
|
+
/**
|
|
7
|
+
* Playbook id of the BUILT-IN DEFAULT playbook (slice 5) that `revo bootstrap` seeds out-of-the-box.
|
|
8
|
+
* Distinct from {@link PLAYBOOK_ID} (the e2e fixture) — Group M targets THIS to prove the shipped default.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_PLAYBOOK_ID = 'revisium-default';
|
|
11
|
+
const STUB_OVERRIDE = { runnerOverrides: { 'claude-code': 'stub-agent' } };
|
|
12
|
+
/** Stub BOTH the agent and the (script) integrator — a self-contained run with no real git/gh. */
|
|
13
|
+
const STUB_OVERRIDE_FULL = { runnerOverrides: { 'claude-code': 'stub-agent', 'revo-integrator': 'stub-agent' } };
|
|
14
|
+
/**
|
|
15
|
+
* Create + start a run on the SEEDED DEFAULT playbook's `feature-development` pipeline (slice 5). Both
|
|
16
|
+
* the agent and the integrator are stubbed so the run reaches the plan + merge gates without real
|
|
17
|
+
* claude/git/gh; the default `feature-development` routes a PASS verdict (→ `approved`) past both the
|
|
18
|
+
* code-review and post-integrator-watcher routers, so the deterministic agent drives it to completion.
|
|
19
|
+
*/
|
|
20
|
+
export async function startDefaultFeatureRun(h, repo = process.cwd()) {
|
|
21
|
+
const created = await h.api.createRun({
|
|
22
|
+
repo,
|
|
23
|
+
title: 'E2E seeded default feature-development run',
|
|
24
|
+
description: 'Group M — the bootstrap-SEEDED default pipeline on real DBOS/Revisium.',
|
|
25
|
+
scope: 'seeded-default e2e',
|
|
26
|
+
playbookId: DEFAULT_PLAYBOOK_ID,
|
|
27
|
+
pipelineId: 'feature-development',
|
|
28
|
+
executionProfile: STUB_OVERRIDE_FULL,
|
|
29
|
+
start: true,
|
|
30
|
+
});
|
|
31
|
+
if (!('workflow' in created))
|
|
32
|
+
throw new Error('start:true must return workflow metadata');
|
|
33
|
+
return created;
|
|
34
|
+
}
|
|
35
|
+
/** Create + start a run on the SEEDED DEFAULT playbook's `local-change` pipeline (developer-only, no gate). */
|
|
36
|
+
export async function startDefaultLocalChangeRun(h, repo = process.cwd()) {
|
|
37
|
+
const created = await h.api.createRun({
|
|
38
|
+
repo,
|
|
39
|
+
title: 'E2E seeded default local-change run',
|
|
40
|
+
description: 'Group M — the bootstrap-SEEDED local-change pipeline on real DBOS/Revisium.',
|
|
41
|
+
scope: 'seeded-default e2e',
|
|
42
|
+
playbookId: DEFAULT_PLAYBOOK_ID,
|
|
43
|
+
pipelineId: 'local-change',
|
|
44
|
+
executionProfile: STUB_OVERRIDE,
|
|
45
|
+
start: true,
|
|
46
|
+
});
|
|
47
|
+
if (!('workflow' in created))
|
|
48
|
+
throw new Error('start:true must return workflow metadata');
|
|
49
|
+
return created;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Install the agent playbook into the control-plane (roles + pipelines).
|
|
53
|
+
*
|
|
54
|
+
* The control-plane is shared across e2e files (and persists between local runs). On a fresh
|
|
55
|
+
* control-plane the first caller installs + commits it; a later caller re-committing the same
|
|
56
|
+
* playbook fails with "revision is not a draft" (a benign no-op), which we swallow. Any other
|
|
57
|
+
* failure is re-thrown. NB: a seeded pipeline is NOT proof the playbook is installed (bootstrap
|
|
58
|
+
* seeds pipeline rows), so we must not gate on getPipeline — we install and tolerate re-install.
|
|
59
|
+
*/
|
|
60
|
+
export async function givenInstalledPlaybook(h) {
|
|
61
|
+
// `listPlaybooks` is the accurate presence signal: bootstrap seeds pipeline/role rows but NOT a
|
|
62
|
+
// playbook record, so this is empty until installed. Shared control-plane + sequential files →
|
|
63
|
+
// the first run installs once, the rest skip (no redundant commit, no race).
|
|
64
|
+
const installed = await h.api.listPlaybooks();
|
|
65
|
+
if (installed.some((p) => p.id === PLAYBOOK_ID))
|
|
66
|
+
return;
|
|
67
|
+
try {
|
|
68
|
+
const install = await h.api.installPlaybook({ source: PLAYBOOK_SOURCE, name: PLAYBOOK_ID, commit: true });
|
|
69
|
+
assert.equal(install.playbookId, PLAYBOOK_ID);
|
|
70
|
+
assert.ok(install.roles > 0, 'playbook install must load roles');
|
|
71
|
+
assert.ok(install.pipelines > 0, 'playbook install must load pipelines');
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
// Belt-and-suspenders: tolerate a concurrent/duplicate commit ("revision is not a draft");
|
|
75
|
+
// re-throw anything that is not an already-installed signal.
|
|
76
|
+
if (!/not a draft|already|nothing to commit|ROW_CONFLICT/i.test(String(err)))
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Ensure the BUILT-IN DEFAULT playbook (slice 5) is installed. `revo bootstrap` seeds it
|
|
82
|
+
* out-of-the-box (so a fresh e2e control-plane already has it), but a REUSED test home that predates
|
|
83
|
+
* this slice may not — so this self-heals by installing from the committed source if absent. It does
|
|
84
|
+
* NOT install the e2e fixture: Group M tests the SHIPPED default, distinct from {@link PLAYBOOK_ID}.
|
|
85
|
+
*/
|
|
86
|
+
export async function givenSeededDefaultPlaybook(h) {
|
|
87
|
+
const installed = await h.api.listPlaybooks();
|
|
88
|
+
if (installed.some((p) => p.id === DEFAULT_PLAYBOOK_ID))
|
|
89
|
+
return;
|
|
90
|
+
const { repoRoot } = await import('../../config.js');
|
|
91
|
+
const { join } = await import('node:path');
|
|
92
|
+
const source = join(repoRoot, 'control-plane', 'default-playbook');
|
|
93
|
+
try {
|
|
94
|
+
const install = await h.api.installPlaybook({ source, name: DEFAULT_PLAYBOOK_ID, commit: true });
|
|
95
|
+
assert.equal(install.playbookId, DEFAULT_PLAYBOOK_ID);
|
|
96
|
+
assert.ok(install.pipelines >= 2, 'default playbook install must load the seeded pipelines');
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
if (!/not a draft|already|nothing to commit|ROW_CONFLICT/i.test(String(err)))
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Create + start a `local-change` run (developer-only, stub agent). Returns the started run. */
|
|
104
|
+
export async function startLocalChangeRun(h, repo = process.cwd()) {
|
|
105
|
+
const created = await h.api.createRun({
|
|
106
|
+
repo,
|
|
107
|
+
title: 'E2E local-change deterministic agent',
|
|
108
|
+
description: 'Real DBOS/Revisium run; deterministic test agent replaces claude-code only.',
|
|
109
|
+
scope: 'No source changes.',
|
|
110
|
+
playbookId: PLAYBOOK_ID,
|
|
111
|
+
pipelineId: 'local-change',
|
|
112
|
+
executionProfile: STUB_OVERRIDE,
|
|
113
|
+
start: true,
|
|
114
|
+
});
|
|
115
|
+
if (!('workflow' in created))
|
|
116
|
+
throw new Error('start:true must return workflow metadata');
|
|
117
|
+
return created;
|
|
118
|
+
}
|
|
119
|
+
/** Create + start a `feature-development` run against `target`, registering the developer write. */
|
|
120
|
+
export async function startFeatureRun(h, target) {
|
|
121
|
+
const created = await h.api.createRun({
|
|
122
|
+
repo: target.worktree,
|
|
123
|
+
title: 'E2E feature-development deterministic agent',
|
|
124
|
+
description: 'Real DBOS/Revisium gates, real git integrator, deterministic agent and fake GitHub.',
|
|
125
|
+
scope: 'Only mutate the temporary e2e target repository.',
|
|
126
|
+
playbookId: PLAYBOOK_ID,
|
|
127
|
+
pipelineId: 'feature-development',
|
|
128
|
+
executionProfile: STUB_OVERRIDE,
|
|
129
|
+
start: true,
|
|
130
|
+
});
|
|
131
|
+
if (!('workflow' in created))
|
|
132
|
+
throw new Error('start:true must return workflow metadata');
|
|
133
|
+
h.developerWrites.set(created.runId, target.worktree);
|
|
134
|
+
return created;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Create + start a feature run with BOTH the agent and the integrator stubbed (script mode — no git
|
|
138
|
+
* or gh). Used by the durability/recovery suite where integration is irrelevant and the run must
|
|
139
|
+
* reach plan + merge gates and complete without external effects. `target` is only a valid repo path
|
|
140
|
+
* (the stub integrator never touches it). Does NOT register a developer write (stub integrate ignores it).
|
|
141
|
+
*/
|
|
142
|
+
export async function startStubbedFeatureRun(h, target) {
|
|
143
|
+
const created = await h.api.createRun({
|
|
144
|
+
repo: target.worktree,
|
|
145
|
+
title: 'E2E recovery feature run',
|
|
146
|
+
description: 'Group F — durability/crash-recovery (stubbed agent + integrator).',
|
|
147
|
+
scope: 'recovery e2e',
|
|
148
|
+
playbookId: PLAYBOOK_ID,
|
|
149
|
+
pipelineId: 'feature-development',
|
|
150
|
+
executionProfile: { runnerOverrides: { 'claude-code': 'stub-agent', 'revo-integrator': 'stub-agent' } },
|
|
151
|
+
start: true,
|
|
152
|
+
});
|
|
153
|
+
if (!('workflow' in created))
|
|
154
|
+
throw new Error('start:true must return workflow metadata');
|
|
155
|
+
return { runId: created.runId, taskId: created.taskId };
|
|
156
|
+
}
|
|
157
|
+
/** Pipeline id of the DATA-DRIVEN feature pipeline (0015 slice 2) — embeds a state-machine template. */
|
|
158
|
+
export const DATA_DRIVEN_PIPELINE = 'feature-development-dd';
|
|
159
|
+
/**
|
|
160
|
+
* Create + start a DATA-DRIVEN feature run (0015 slice 2) against `target`. Routes to the
|
|
161
|
+
* data-driven DBOS adapter (the pipeline carries a template_json), with the agent + integrator stubbed
|
|
162
|
+
* so the run reaches the plan + merge gates without real git/gh. `spec` is registered (when provided)
|
|
163
|
+
* BEFORE start so the scripted agent reads this run's per-node verdicts (needs a routedScriptedAgent
|
|
164
|
+
* harness). The data-driven watcher node routes on a `clean` DOMAIN verdict — the caller scripts it.
|
|
165
|
+
*/
|
|
166
|
+
export async function startDataDrivenRun(h, target, specs, spec) {
|
|
167
|
+
const created = await h.api.createRun({
|
|
168
|
+
repo: target.worktree,
|
|
169
|
+
title: 'E2E data-driven feature run',
|
|
170
|
+
description: 'Group L — data-driven pipeline (pipeline-core graph) on real DBOS.',
|
|
171
|
+
scope: 'data-driven e2e',
|
|
172
|
+
playbookId: PLAYBOOK_ID,
|
|
173
|
+
pipelineId: DATA_DRIVEN_PIPELINE,
|
|
174
|
+
executionProfile: { runnerOverrides: { 'claude-code': 'stub-agent', 'revo-integrator': 'stub-agent' } },
|
|
175
|
+
start: false,
|
|
176
|
+
});
|
|
177
|
+
if (specs && spec)
|
|
178
|
+
specs.set(created.runId, spec);
|
|
179
|
+
const started = await h.api.startRun({ runId: created.runId });
|
|
180
|
+
return { runId: created.runId, taskId: created.taskId, started };
|
|
181
|
+
}
|
|
182
|
+
/** Feature run driven to the `plan` gate (parked, awaiting decision). */
|
|
183
|
+
export async function givenFeatureRunAtPlanGate(h, target) {
|
|
184
|
+
const run = await startFeatureRun(h, target);
|
|
185
|
+
const gate = await waitForGate(h.api, run.runId, 'plan');
|
|
186
|
+
return { runId: run.runId, taskId: run.taskId, inboxId: gate.inboxId };
|
|
187
|
+
}
|
|
188
|
+
/** Feature run with `plan` approved, driven to the `merge` gate (parked, awaiting decision). */
|
|
189
|
+
export async function givenFeatureRunAtMergeGate(h, target) {
|
|
190
|
+
const run = await startFeatureRun(h, target);
|
|
191
|
+
const plan = await waitForGate(h.api, run.runId, 'plan');
|
|
192
|
+
await h.api.approveGate({ inboxId: plan.inboxId, resolvedBy: 'e2e' });
|
|
193
|
+
const merge = await waitForGate(h.api, run.runId, 'merge');
|
|
194
|
+
return { runId: run.runId, taskId: run.taskId, inboxId: merge.inboxId };
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=scenarios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../../src/e2e/kit/scenarios.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// recovery-crash-child.ts — Group F crash simulator.
|
|
2
|
+
//
|
|
3
|
+
// Boots a host, starts a stubbed feature run, drives it to a durable stop point (plan or merge gate),
|
|
4
|
+
// prints `RUNID=<id>`, then exits ABRUPTLY without draining DBOS — exactly as if the host process
|
|
5
|
+
// were killed. The in-flight workflow is left PENDING in Postgres; the parent test then boots a fresh
|
|
6
|
+
// host whose DBOS.launch() recovers + replays it. A separate process is required: DBOS is a
|
|
7
|
+
// process-global singleton, so true crash-recovery cannot be simulated in-process.
|
|
8
|
+
//
|
|
9
|
+
// Spawned by `crashRunAt` (kit/crash.ts) via tsx, inheriting the REVO_DATA_DIR/REVO_PORT env so it
|
|
10
|
+
// targets the isolated test daemon. argv[2] = stop point: 'plan-gate' (default) | 'merge-gate'.
|
|
11
|
+
import 'reflect-metadata';
|
|
12
|
+
import { createRunHarness, givenInstalledPlaybook, createTargetRepo, startStubbedFeatureRun, waitForGate, } from './kit/index.js';
|
|
13
|
+
const stopAt = process.argv[2] ?? 'plan-gate';
|
|
14
|
+
const h = await createRunHarness();
|
|
15
|
+
await givenInstalledPlaybook(h);
|
|
16
|
+
// A clean throwaway repo path; the stub integrator never touches it. Intentionally NOT cleaned up —
|
|
17
|
+
// the process is about to "crash", and the OS reaps the temp dir. Leaking one /tmp dir per crash is
|
|
18
|
+
// cheaper than wiring a teardown that a crash would skip anyway.
|
|
19
|
+
const target = createTargetRepo();
|
|
20
|
+
const run = await startStubbedFeatureRun(h, target);
|
|
21
|
+
const plan = await waitForGate(h.api, run.runId, 'plan');
|
|
22
|
+
if (stopAt === 'merge-gate') {
|
|
23
|
+
await h.api.approveGate({ inboxId: plan.inboxId, resolvedBy: 'crash-child' });
|
|
24
|
+
await waitForGate(h.api, run.runId, 'merge');
|
|
25
|
+
}
|
|
26
|
+
// Flush the run id, then exit WITHOUT h.close() — no DBOS drain → the workflow stays PENDING in
|
|
27
|
+
// Postgres (the crash). exit(0) inside the write callback guarantees the parent reads RUNID first.
|
|
28
|
+
process.stdout.write(`RUNID=${run.runId}\n`, () => process.exit(0));
|
|
29
|
+
//# sourceMappingURL=recovery-crash-child.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-crash-child.js","sourceRoot":"","sources":["../../src/e2e/recovery-crash-child.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,sGAAsG;AACtG,kGAAkG;AAClG,sGAAsG;AACtG,4FAA4F;AAC5F,mFAAmF;AACnF,EAAE;AACF,mGAAmG;AACnG,gGAAgG;AAChG,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC;AAE9C,MAAM,CAAC,GAAG,MAAM,gBAAgB,EAAE,CAAC;AACnC,MAAM,sBAAsB,CAAC,CAAC,CAAC,CAAC;AAChC,oGAAoG;AACpG,oGAAoG;AACpG,iEAAiE;AACjE,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;AAClC,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAEpD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACzD,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;IAC5B,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;IAC9E,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,gGAAgG;AAChG,mGAAmG;AACnG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// recovery-dd-crash-child.ts — Group L crash simulator for the DATA-DRIVEN pipeline (0015 slice 2).
|
|
2
|
+
//
|
|
3
|
+
// Mirrors recovery-crash-child.ts but starts a run on the data-driven `feature-development-dd` pipeline
|
|
4
|
+
// (the pipeline-core graph executed by the DBOS effect-adapter). Boots a host, drives the run to a
|
|
5
|
+
// durable stop point (plan or merge gate), prints `RUNID=<id>`, then exits ABRUPTLY without draining
|
|
6
|
+
// DBOS — exactly as if the host were killed. The in-flight DATA-DRIVEN workflow is left PENDING in
|
|
7
|
+
// Postgres; the parent test boots a fresh host whose DBOS.launch() recovers + replays it. A separate
|
|
8
|
+
// process is mandatory: DBOS is a process-global singleton, so a true crash cannot be faked in-process.
|
|
9
|
+
//
|
|
10
|
+
// Spawned by `crashDataDrivenRunAt` (kit/crash.ts) via tsx, inheriting REVO_DATA_DIR/REVO_PORT.
|
|
11
|
+
// argv[2] = stop point: 'plan-gate' (default) | 'merge-gate'.
|
|
12
|
+
//
|
|
13
|
+
// Uses a SINGLE scriptedAgent (not per-run routed) so the data-driven watcher node always emits the
|
|
14
|
+
// `clean` DOMAIN verdict it needs to reach the merge gate — independent of runId and process. The
|
|
15
|
+
// default all-PASS agent would route the watcher to `failedEnd`; a per-run spec map cannot cross the
|
|
16
|
+
// crash→recovery process boundary, so a constant spec is the deterministic choice here.
|
|
17
|
+
import 'reflect-metadata';
|
|
18
|
+
import { createRunHarness, givenInstalledPlaybook, createTargetRepo, DATA_DRIVEN_PIPELINE, waitForGate, scriptedAgent, } from './kit/index.js';
|
|
19
|
+
const stopAt = process.argv[2] ?? 'plan-gate';
|
|
20
|
+
const CLEAN_WATCHER = { byRole: { watcher: { kind: 'domainVerdict', verdict: 'clean' } } };
|
|
21
|
+
const h = await createRunHarness({ agent: (sink) => scriptedAgent(CLEAN_WATCHER, sink) });
|
|
22
|
+
await givenInstalledPlaybook(h);
|
|
23
|
+
const target = createTargetRepo(); // clean throwaway repo; the stub integrator never touches it
|
|
24
|
+
const created = await h.api.createRun({
|
|
25
|
+
repo: target.worktree,
|
|
26
|
+
title: 'E2E data-driven recovery run',
|
|
27
|
+
description: 'Group L — data-driven crash-recovery (stubbed agent + integrator).',
|
|
28
|
+
scope: 'data-driven recovery e2e',
|
|
29
|
+
playbookId: 'revisium-agent-playbook',
|
|
30
|
+
pipelineId: DATA_DRIVEN_PIPELINE,
|
|
31
|
+
executionProfile: { runnerOverrides: { 'claude-code': 'stub-agent', 'revo-integrator': 'stub-agent' } },
|
|
32
|
+
start: true,
|
|
33
|
+
});
|
|
34
|
+
const runId = created.runId;
|
|
35
|
+
const plan = await waitForGate(h.api, runId, 'plan');
|
|
36
|
+
if (stopAt === 'merge-gate') {
|
|
37
|
+
await h.api.approveGate({ inboxId: plan.inboxId, resolvedBy: 'crash-child' });
|
|
38
|
+
await waitForGate(h.api, runId, 'merge');
|
|
39
|
+
}
|
|
40
|
+
// Flush the run id, then exit WITHOUT h.close() — no DBOS drain → the workflow stays PENDING (the crash).
|
|
41
|
+
process.stdout.write(`RUNID=${runId}\n`, () => process.exit(0));
|
|
42
|
+
//# sourceMappingURL=recovery-dd-crash-child.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-dd-crash-child.js","sourceRoot":"","sources":["../../src/e2e/recovery-dd-crash-child.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,EAAE;AACF,wGAAwG;AACxG,mGAAmG;AACnG,qGAAqG;AACrG,mGAAmG;AACnG,qGAAqG;AACrG,wGAAwG;AACxG,EAAE;AACF,gGAAgG;AAChG,8DAA8D;AAC9D,EAAE;AACF,oGAAoG;AACpG,kGAAkG;AAClG,qGAAqG;AACrG,wFAAwF;AACxF,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,aAAa,GAEd,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC;AAE9C,MAAM,aAAa,GAAc,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAEtG,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1F,MAAM,sBAAsB,CAAC,CAAC,CAAC,CAAC;AAChC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC,CAAC,6DAA6D;AAEhG,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC,QAAQ;IACrB,KAAK,EAAE,8BAA8B;IACrC,WAAW,EAAE,oEAAoE;IACjF,KAAK,EAAE,0BAA0B;IACjC,UAAU,EAAE,yBAAyB;IACrC,UAAU,EAAE,oBAAoB;IAChC,gBAAgB,EAAE,EAAE,eAAe,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,EAAE;IACvG,KAAK,EAAE,IAAI;CACZ,CAAC,CAAC;AACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AAE5B,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AACrD,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;IAC5B,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;IAC9E,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,0GAA0G;AAC1G,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -17,7 +17,19 @@
|
|
|
17
17
|
* live Postgres. The production default constructs a real `pg.Client`.
|
|
18
18
|
*/
|
|
19
19
|
import pg from 'pg';
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* DBOS system-database name. Overridable via `REVO_DBOS_DB` so the e2e/CI daemon keeps its DBOS
|
|
22
|
+
* progress fully separate from the dev one. Validated to a safe identifier because the name is
|
|
23
|
+
* interpolated into a non-parameterizable `CREATE DATABASE` (CREATE DATABASE cannot bind params).
|
|
24
|
+
*/
|
|
25
|
+
function resolveDbosDbName() {
|
|
26
|
+
const name = process.env['REVO_DBOS_DB'] ?? 'dbos';
|
|
27
|
+
if (!/^[a-z_][a-z0-9_]*$/i.test(name)) {
|
|
28
|
+
throw new Error(`Invalid REVO_DBOS_DB '${name}': must be a SQL identifier (/^[a-z_][a-z0-9_]*$/i)`);
|
|
29
|
+
}
|
|
30
|
+
return name;
|
|
31
|
+
}
|
|
32
|
+
const DBOS_DB_NAME = resolveDbosDbName();
|
|
21
33
|
const MAINTENANCE_DB = 'postgres';
|
|
22
34
|
/** PostgreSQL SQLSTATE for "database already exists" (duplicate_database). */
|
|
23
35
|
const PG_SQLSTATE_DUPLICATE_DATABASE = '42P04';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensure-postgres.js","sourceRoot":"","sources":["../../src/engine/ensure-postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,
|
|
1
|
+
{"version":3,"file":"ensure-postgres.js","sourceRoot":"","sources":["../../src/engine/ensure-postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;;;GAIG;AACH,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC;IACnD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,qDAAqD,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAC;AACzC,MAAM,cAAc,GAAG,UAAU,CAAC;AAElC,8EAA8E;AAC9E,MAAM,8BAA8B,GAAG,OAAO,CAAC;AAQ/C,MAAM,aAAa,GAAwB;IACzC,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,cAAc;CACxB,CAAC;AAkBF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAc,EACd,OAAqC,EAAE,EACvC,OAA2B,EAAE;IAE7B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,IAAI,EAAE,CAAC;IAClE,iFAAiF;IACjF,mFAAmF;IACnF,yFAAyF;IACzF,MAAM,eAAe,GAAG,GAAe,EAAE,CACvC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAA0B,CAAC;IACjH,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,eAAe,CAAC;IAE1D,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAC/B,oEAAoE,EACpE,CAAC,YAAY,CAAC,CACf,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,GAAG,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,gGAAgG;YAChG,0FAA0F;YAC1F,kFAAkF;YAClF,oEAAoE;YACpE,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAK,GAAyB,CAAC,IAAI,KAAK,8BAA8B,EAAE,CAAC;oBACvE,6DAA6D;oBAC7D,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,IAAI,GAAG,UAAU,EACjB,QAAQ,GAAG,UAAU;IAErB,OAAO,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,cAAc,MAAM,IAAI,YAAY,EAAE,CAAC;AACxH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-capabilities.js","sourceRoot":"","sources":["../../src/mcp/mcp-capabilities.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,YAAY;IACZ,QAAQ;IACR,kBAAkB;IAClB,qBAAqB;IACrB,wBAAwB;IACxB,aAAa;IACb,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,SAAS;IACT,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,uBAAuB;IACvB,cAAc;IACd,aAAa;IACb,iBAAiB;IACjB,oBAAoB;IACpB,qBAAqB;IACrB,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,UAAU;IACV,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;CACV,CAAC;AAIX,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;qDAWqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"mcp-capabilities.js","sourceRoot":"","sources":["../../src/mcp/mcp-capabilities.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,YAAY;IACZ,QAAQ;IACR,kBAAkB;IAClB,qBAAqB;IACrB,wBAAwB;IACxB,aAAa;IACb,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,SAAS;IACT,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,cAAc;IACd,YAAY;IACZ,gBAAgB;IAChB,uBAAuB;IACvB,cAAc;IACd,aAAa;IACb,iBAAiB;IACjB,oBAAoB;IACpB,qBAAqB;IACrB,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,UAAU;IACV,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;CACV,CAAC;AAIX,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;qDAWqB,CAAC"}
|
|
@@ -9,7 +9,18 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
import { Injectable } from '@nestjs/common';
|
|
11
11
|
import { TaskControlPlaneApiService, } from '../task-control-plane/task-control-plane-api.service.js';
|
|
12
|
+
import { ControlPlaneError } from '../control-plane/errors.js';
|
|
13
|
+
import { CreateRunWorkflowError } from '../run/create-run.js';
|
|
12
14
|
import { MCP_TOOL_NAMES } from './mcp-capabilities.js';
|
|
15
|
+
function formatCause(error) {
|
|
16
|
+
if (error instanceof ControlPlaneError) {
|
|
17
|
+
const status = error.status === undefined ? '' : ` status=${error.status}`;
|
|
18
|
+
return `${error.code}${status}: ${error.message}`;
|
|
19
|
+
}
|
|
20
|
+
if (error instanceof Error)
|
|
21
|
+
return error.message;
|
|
22
|
+
return String(error);
|
|
23
|
+
}
|
|
13
24
|
let McpFacadeService = class McpFacadeService {
|
|
14
25
|
api;
|
|
15
26
|
constructor(api) {
|
|
@@ -20,11 +31,10 @@ let McpFacadeService = class McpFacadeService {
|
|
|
20
31
|
transport: 'stdio',
|
|
21
32
|
auth: 'none',
|
|
22
33
|
tools: [...MCP_TOOL_NAMES],
|
|
23
|
-
runnerModes: ['script', 'live'],
|
|
24
34
|
notes: [
|
|
25
35
|
'Local stdio MCP server; no remote HTTP listener.',
|
|
26
36
|
'Tools expose product operations, not generic Revisium row CRUD.',
|
|
27
|
-
'
|
|
37
|
+
'Runs are driven by installed playbooks, pipeline catalogs, and execution profiles.',
|
|
28
38
|
],
|
|
29
39
|
};
|
|
30
40
|
}
|
|
@@ -44,7 +54,15 @@ let McpFacadeService = class McpFacadeService {
|
|
|
44
54
|
return this.api.getRepositoryContext(input);
|
|
45
55
|
}
|
|
46
56
|
createRun(input) {
|
|
47
|
-
return this.api.createRun(input)
|
|
57
|
+
return this.api.createRun(input).catch((error) => {
|
|
58
|
+
if (error instanceof CreateRunWorkflowError) {
|
|
59
|
+
const created = Object.keys(error.createdIds).length > 0
|
|
60
|
+
? `; createdBeforeFailure=${JSON.stringify(error.createdIds)}`
|
|
61
|
+
: '';
|
|
62
|
+
throw new Error(`${error.message}: ${formatCause(error.cause)}${created}`);
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
});
|
|
48
66
|
}
|
|
49
67
|
startRun(input) {
|
|
50
68
|
return this.api.startRun(input);
|
|
@@ -70,6 +88,9 @@ let McpFacadeService = class McpFacadeService {
|
|
|
70
88
|
getRunDigest(runId) {
|
|
71
89
|
return this.api.getRunDigest(runId);
|
|
72
90
|
}
|
|
91
|
+
waitForRun(input) {
|
|
92
|
+
return this.api.waitForRun(input);
|
|
93
|
+
}
|
|
73
94
|
listInbox(filter) {
|
|
74
95
|
return this.api.listInbox(filter);
|
|
75
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-facade.service.js","sourceRoot":"","sources":["../../src/mcp/mcp-facade.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EACL,0BAA0B,
|
|
1
|
+
{"version":3,"file":"mcp-facade.service.js","sourceRoot":"","sources":["../../src/mcp/mcp-facade.service.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/mcp-tools.js
CHANGED
|
@@ -9,10 +9,10 @@ function json(value) {
|
|
|
9
9
|
],
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
const runnerModeSchema = z.enum(['script', 'live']).optional().describe('script = zero-cost stub path; live = real Claude + git/GitHub effects');
|
|
13
12
|
const runIdSchema = z.string().min(1).describe('Run ID');
|
|
14
13
|
const inboxIdSchema = z.string().min(1).describe('Inbox item ID');
|
|
15
14
|
const limitSchema = z.number().int().positive().max(500).optional();
|
|
15
|
+
const paramsSchema = z.record(z.string(), z.unknown()).optional();
|
|
16
16
|
const prReadinessInputSchema = {
|
|
17
17
|
repo: z.string().min(1).describe('GitHub repository in owner/name form, for example revisium/agent-orchestrator'),
|
|
18
18
|
prNumber: z.number().int().positive().optional(),
|
|
@@ -64,10 +64,11 @@ export function registerRevoMcpTools(server, facade) {
|
|
|
64
64
|
repo: z.string().min(1),
|
|
65
65
|
description: z.string().optional(),
|
|
66
66
|
scope: z.string().optional(),
|
|
67
|
+
playbookId: z.string().min(1).optional(),
|
|
68
|
+
pipelineId: z.string().min(1).optional(),
|
|
69
|
+
params: paramsSchema,
|
|
67
70
|
priority: z.number().int().optional(),
|
|
68
|
-
role: z.string().optional().describe('Initial role hint; defaults to architect'),
|
|
69
71
|
start: z.boolean().optional().describe('Start the workflow immediately after creating the run'),
|
|
70
|
-
runnerMode: runnerModeSchema,
|
|
71
72
|
},
|
|
72
73
|
annotations: { readOnlyHint: false },
|
|
73
74
|
}, async (input) => json(await facade.createRun(input)));
|
|
@@ -75,7 +76,6 @@ export function registerRevoMcpTools(server, facade) {
|
|
|
75
76
|
description: 'Start or reattach the durable pipeline workflow for an existing run.',
|
|
76
77
|
inputSchema: {
|
|
77
78
|
runId: runIdSchema,
|
|
78
|
-
runnerMode: runnerModeSchema,
|
|
79
79
|
},
|
|
80
80
|
annotations: { readOnlyHint: false },
|
|
81
81
|
}, async (input) => json(await facade.startRun(input)));
|
|
@@ -83,10 +83,18 @@ export function registerRevoMcpTools(server, facade) {
|
|
|
83
83
|
description: 'Alias for start_run; reattaches a durable workflow by run ID.',
|
|
84
84
|
inputSchema: {
|
|
85
85
|
runId: runIdSchema,
|
|
86
|
-
runnerMode: runnerModeSchema,
|
|
87
86
|
},
|
|
88
87
|
annotations: { readOnlyHint: false },
|
|
89
88
|
}, async (input) => json(await facade.resumeRun(input)));
|
|
89
|
+
server.registerTool('wait_for_run', {
|
|
90
|
+
description: 'Resolve current run state and next action: pending_gate, question, running, blocked, failed, completed.',
|
|
91
|
+
inputSchema: {
|
|
92
|
+
runId: runIdSchema,
|
|
93
|
+
timeoutMs: z.number().int().nonnegative().max(120000).optional(),
|
|
94
|
+
intervalMs: z.number().int().positive().max(10000).optional(),
|
|
95
|
+
},
|
|
96
|
+
annotations: { readOnlyHint: true },
|
|
97
|
+
}, async (input) => json(await facade.waitForRun(input)));
|
|
90
98
|
server.registerTool('cancel_run', {
|
|
91
99
|
description: 'Cancel a run and append a run_cancelled event.',
|
|
92
100
|
inputSchema: {
|
|
@@ -246,10 +254,11 @@ export function registerRevoMcpTools(server, facade) {
|
|
|
246
254
|
title: z.string().min(1),
|
|
247
255
|
repo: z.string().optional(),
|
|
248
256
|
pipeline: z.string().optional(),
|
|
249
|
-
|
|
257
|
+
playbookId: z.string().optional(),
|
|
258
|
+
params: paramsSchema,
|
|
250
259
|
},
|
|
251
260
|
annotations: { readOnlyHint: true },
|
|
252
|
-
}, (input) => json(facade.simulateRoute(input)));
|
|
261
|
+
}, async (input) => json(await facade.simulateRoute(input)));
|
|
253
262
|
server.registerTool('get_pr_readiness', {
|
|
254
263
|
description: 'Return normalized read-only PR readiness from GitHub checks, reviews, review threads, provider comments, and optional Sonar data.',
|
|
255
264
|
inputSchema: prReadinessInputSchema,
|