@exaudeus/workrail 3.39.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/init.js +0 -3
- package/dist/cli-worktrain.js +58 -26
- package/dist/cli.js +0 -18
- package/dist/config/app-config.d.ts +0 -16
- package/dist/config/app-config.js +0 -14
- package/dist/config/config-file.js +0 -3
- package/dist/console-ui/assets/index-CQt4UhPB.js +28 -0
- package/dist/console-ui/assets/index-DGj8EsFR.css +1 -0
- package/dist/console-ui/index.html +2 -2
- package/dist/coordinators/pr-review.d.ts +23 -1
- package/dist/coordinators/pr-review.js +224 -5
- package/dist/daemon/daemon-events.d.ts +9 -1
- package/dist/daemon/soul-template.d.ts +2 -2
- package/dist/daemon/soul-template.js +11 -1
- package/dist/daemon/workflow-runner.d.ts +17 -3
- package/dist/daemon/workflow-runner.js +401 -28
- package/dist/di/container.js +1 -25
- package/dist/di/tokens.d.ts +0 -3
- package/dist/di/tokens.js +0 -3
- package/dist/engine/engine-factory.js +0 -1
- package/dist/infrastructure/console-defaults.d.ts +1 -0
- package/dist/infrastructure/console-defaults.js +4 -0
- package/dist/infrastructure/session/index.d.ts +0 -1
- package/dist/infrastructure/session/index.js +1 -3
- package/dist/manifest.json +124 -124
- package/dist/mcp/handlers/session.d.ts +1 -0
- package/dist/mcp/handlers/session.js +61 -13
- package/dist/mcp/output-schemas.d.ts +10 -10
- package/dist/mcp/server.js +1 -18
- package/dist/mcp/tools.d.ts +12 -12
- package/dist/mcp/transports/http-entry.js +0 -2
- package/dist/mcp/transports/stdio-entry.js +1 -2
- package/dist/mcp/types.d.ts +0 -2
- package/dist/trigger/daemon-console.d.ts +2 -0
- package/dist/trigger/daemon-console.js +1 -1
- package/dist/trigger/trigger-listener.d.ts +2 -0
- package/dist/trigger/trigger-listener.js +3 -1
- package/dist/trigger/trigger-router.d.ts +4 -3
- package/dist/trigger/trigger-router.js +13 -5
- package/dist/trigger/trigger-store.js +17 -4
- package/dist/types/workflow-source.d.ts +0 -1
- package/dist/types/workflow-source.js +3 -6
- package/dist/types/workflow.d.ts +1 -1
- package/dist/types/workflow.js +1 -2
- package/dist/v2/durable-core/domain/artifact-contract-validator.js +66 -0
- package/dist/v2/durable-core/schemas/artifacts/coordinator-signal.d.ts +25 -0
- package/dist/v2/durable-core/schemas/artifacts/coordinator-signal.js +31 -0
- package/dist/v2/durable-core/schemas/artifacts/index.d.ts +3 -1
- package/dist/v2/durable-core/schemas/artifacts/index.js +14 -1
- package/dist/v2/durable-core/schemas/artifacts/review-verdict.d.ts +41 -0
- package/dist/v2/durable-core/schemas/artifacts/review-verdict.js +30 -0
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +236 -236
- package/dist/v2/durable-core/schemas/session/events.d.ts +50 -50
- package/dist/v2/durable-core/schemas/session/gaps.d.ts +2 -2
- package/dist/v2/durable-core/schemas/session/manifest.d.ts +4 -4
- package/dist/v2/durable-core/schemas/session/outputs.d.ts +8 -8
- package/dist/v2/usecases/console-routes.d.ts +2 -1
- package/dist/v2/usecases/console-routes.js +207 -5
- package/dist/v2/usecases/console-service.js +14 -0
- package/dist/v2/usecases/console-types.d.ts +1 -0
- package/docs/authoring.md +16 -16
- package/docs/design/coordinator-artifact-protocol-design-candidates.md +155 -0
- package/docs/design/coordinator-artifact-protocol-design-review.md +103 -0
- package/docs/design/coordinator-artifact-protocol-implementation-plan.md +259 -0
- package/docs/design/coordinator-message-queue-drain-plan.md +241 -0
- package/docs/design/coordinator-message-queue-drain-review.md +120 -0
- package/docs/design/coordinator-message-queue-drain.md +289 -0
- package/docs/design/shaping-workflow-external-research.md +119 -0
- package/docs/discovery/late-bound-goals-impl-plan.md +147 -0
- package/docs/discovery/late-bound-goals-review.md +82 -0
- package/docs/discovery/late-bound-goals.md +118 -0
- package/docs/discovery/steer-endpoint-design-candidates.md +288 -0
- package/docs/discovery/steer-endpoint-design-review-findings.md +104 -0
- package/docs/discovery/steer-endpoint-implementation-plan.md +284 -0
- package/docs/ideas/backlog.md +447 -97
- package/docs/ideas/design-candidates-console-session-tree-impl.md +64 -0
- package/docs/ideas/design-candidates-session-tree-view.md +196 -0
- package/docs/ideas/design-review-findings-console-session-tree-impl.md +75 -0
- package/docs/ideas/design-review-findings-session-tree-view.md +88 -0
- package/docs/ideas/implementation_plan_session_tree_view.md +238 -0
- package/package.json +2 -1
- package/spec/authoring-spec.json +16 -16
- package/spec/shape.schema.json +178 -0
- package/spec/workflow-tags.json +232 -47
- package/workflows/coding-task-workflow-agentic.json +491 -480
- package/workflows/mr-review-workflow.agentic.v2.json +5 -1
- package/workflows/wr.shaping.json +182 -0
- package/dist/console-ui/assets/index-3oXZ_A9m.js +0 -28
- package/dist/console-ui/assets/index-8dh0Psu-.css +0 -1
- package/dist/infrastructure/session/DashboardHeartbeat.d.ts +0 -8
- package/dist/infrastructure/session/DashboardHeartbeat.js +0 -39
- package/dist/infrastructure/session/DashboardLockRelease.d.ts +0 -2
- package/dist/infrastructure/session/DashboardLockRelease.js +0 -29
- package/dist/infrastructure/session/HttpServer.d.ts +0 -60
- package/dist/infrastructure/session/HttpServer.js +0 -912
- package/workflows/coding-task-workflow-agentic.lean.v2.json +0 -648
- package/workflows/coding-task-workflow-agentic.v2.json +0 -324
|
@@ -54,9 +54,6 @@ const CONFIG_FILE_TEMPLATE = `{
|
|
|
54
54
|
|
|
55
55
|
"CACHE_TTL": "300000",
|
|
56
56
|
"WORKRAIL_WORKFLOWS_DIR": "",
|
|
57
|
-
"WORKRAIL_DISABLE_UNIFIED_DASHBOARD": "0",
|
|
58
|
-
"WORKRAIL_DISABLE_AUTO_OPEN": "0",
|
|
59
|
-
"WORKRAIL_DASHBOARD_PORT": "3456",
|
|
60
57
|
|
|
61
58
|
"WORKRAIL_ENABLE_SESSION_TOOLS": "true",
|
|
62
59
|
"WORKRAIL_ENABLE_EXPERIMENTAL_WORKFLOWS": "false",
|
package/dist/cli-worktrain.js
CHANGED
|
@@ -330,6 +330,7 @@ program
|
|
|
330
330
|
triggerRouter: handle.router,
|
|
331
331
|
serverVersion: pkg.version,
|
|
332
332
|
workflowService,
|
|
333
|
+
steerRegistry: handle.steerRegistry,
|
|
333
334
|
});
|
|
334
335
|
let consoleHandle = null;
|
|
335
336
|
if (consoleResult.kind === 'ok') {
|
|
@@ -810,27 +811,28 @@ runCommand
|
|
|
810
811
|
})), allSucceeded: false };
|
|
811
812
|
},
|
|
812
813
|
getAgentResult: async (sessionHandle) => {
|
|
814
|
+
const emptyResult = { recapMarkdown: null, artifacts: [] };
|
|
813
815
|
try {
|
|
814
816
|
const sessionUrl = `http://127.0.0.1:${port}/api/v2/sessions/${encodeURIComponent(sessionHandle)}`;
|
|
815
817
|
const sessionRes = await globalThis.fetch(sessionUrl, { signal: AbortSignal.timeout(30000) });
|
|
816
818
|
if (!sessionRes.ok) {
|
|
817
819
|
process.stderr.write(`[WARN coord:reason=http_error status=${sessionRes.status} handle=${sessionHandle.slice(0, 16)}] getAgentResult: session fetch returned HTTP ${sessionRes.status}\n`);
|
|
818
|
-
return
|
|
820
|
+
return emptyResult;
|
|
819
821
|
}
|
|
820
822
|
const sessionBody = await sessionRes.json();
|
|
821
823
|
if (sessionBody['success'] !== true) {
|
|
822
824
|
process.stderr.write(`[WARN coord:reason=api_error handle=${sessionHandle.slice(0, 16)}] getAgentResult: session API returned success=false\n`);
|
|
823
|
-
return
|
|
825
|
+
return emptyResult;
|
|
824
826
|
}
|
|
825
827
|
const data = sessionBody['data'];
|
|
826
828
|
if (!data) {
|
|
827
829
|
process.stderr.write(`[WARN coord:reason=no_data handle=${sessionHandle.slice(0, 16)}] getAgentResult: session response missing data field\n`);
|
|
828
|
-
return
|
|
830
|
+
return emptyResult;
|
|
829
831
|
}
|
|
830
832
|
const runs = data['runs'];
|
|
831
833
|
if (!Array.isArray(runs) || runs.length === 0) {
|
|
832
834
|
process.stderr.write(`[WARN coord:reason=no_runs handle=${sessionHandle.slice(0, 16)}] getAgentResult: session has no runs\n`);
|
|
833
|
-
return
|
|
835
|
+
return emptyResult;
|
|
834
836
|
}
|
|
835
837
|
const firstRun = runs[0];
|
|
836
838
|
const tipNodeId = typeof firstRun['preferredTipNodeId'] === 'string'
|
|
@@ -838,34 +840,57 @@ runCommand
|
|
|
838
840
|
: null;
|
|
839
841
|
if (!tipNodeId) {
|
|
840
842
|
process.stderr.write(`[WARN coord:reason=no_tip_node handle=${sessionHandle.slice(0, 16)}] getAgentResult: session run has no preferredTipNodeId\n`);
|
|
841
|
-
return
|
|
843
|
+
return emptyResult;
|
|
842
844
|
}
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
const
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
845
|
+
const allNodes = Array.isArray(firstRun['nodes'])
|
|
846
|
+
? firstRun['nodes']
|
|
847
|
+
: [];
|
|
848
|
+
const allNodeIds = allNodes
|
|
849
|
+
.map((n) => (typeof n['nodeId'] === 'string' ? n['nodeId'] : null))
|
|
850
|
+
.filter((id) => id !== null);
|
|
851
|
+
const nodeIdsToFetch = allNodeIds.length > 0
|
|
852
|
+
? allNodeIds
|
|
853
|
+
: [tipNodeId];
|
|
854
|
+
const baseNodeUrl = `http://127.0.0.1:${port}/api/v2/sessions/${encodeURIComponent(sessionHandle)}/nodes/`;
|
|
855
|
+
let recap = null;
|
|
856
|
+
const collectedArtifacts = [];
|
|
857
|
+
for (const nodeId of nodeIdsToFetch) {
|
|
858
|
+
try {
|
|
859
|
+
const nodeRes = await globalThis.fetch(baseNodeUrl + encodeURIComponent(nodeId), { signal: AbortSignal.timeout(30000) });
|
|
860
|
+
if (!nodeRes.ok) {
|
|
861
|
+
process.stderr.write(`[WARN coord:reason=node_http_error status=${nodeRes.status} handle=${sessionHandle.slice(0, 16)} node=${nodeId.slice(0, 16)}] getAgentResult: node fetch returned HTTP ${nodeRes.status}\n`);
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
const nodeBody = await nodeRes.json();
|
|
865
|
+
if (nodeBody['success'] !== true) {
|
|
866
|
+
process.stderr.write(`[WARN coord:reason=node_api_error handle=${sessionHandle.slice(0, 16)} node=${nodeId.slice(0, 16)}] getAgentResult: node API returned success=false\n`);
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
const nodeData = nodeBody['data'];
|
|
870
|
+
if (!nodeData)
|
|
871
|
+
continue;
|
|
872
|
+
if (nodeId === tipNodeId) {
|
|
873
|
+
recap = typeof nodeData['recapMarkdown'] === 'string' ? nodeData['recapMarkdown'] : null;
|
|
874
|
+
if (recap === null) {
|
|
875
|
+
process.stderr.write(`[WARN coord:reason=no_recap handle=${sessionHandle.slice(0, 16)} node=${nodeId.slice(0, 16)}] getAgentResult: tip node has no recapMarkdown\n`);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
const nodeArtifacts = nodeData['artifacts'];
|
|
879
|
+
if (Array.isArray(nodeArtifacts) && nodeArtifacts.length > 0) {
|
|
880
|
+
collectedArtifacts.push(...nodeArtifacts);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
catch (nodeErr) {
|
|
884
|
+
const msg = nodeErr instanceof Error ? nodeErr.message : String(nodeErr);
|
|
885
|
+
process.stderr.write(`[WARN coord:reason=node_exception handle=${sessionHandle.slice(0, 16)} node=${nodeId.slice(0, 16)}] getAgentResult: ${msg}\n`);
|
|
886
|
+
}
|
|
862
887
|
}
|
|
863
|
-
return recap;
|
|
888
|
+
return { recapMarkdown: recap, artifacts: collectedArtifacts };
|
|
864
889
|
}
|
|
865
890
|
catch (e) {
|
|
866
891
|
const msg = e instanceof Error ? e.message : String(e);
|
|
867
892
|
process.stderr.write(`[WARN coord:reason=exception handle=${sessionHandle.slice(0, 16)}] getAgentResult: ${msg}\n`);
|
|
868
|
-
return
|
|
893
|
+
return emptyResult;
|
|
869
894
|
}
|
|
870
895
|
},
|
|
871
896
|
listOpenPRs: async (workspace) => {
|
|
@@ -897,6 +922,13 @@ runCommand
|
|
|
897
922
|
writeFile: async (filePath, content) => {
|
|
898
923
|
await fs_1.default.promises.writeFile(filePath, content, 'utf-8');
|
|
899
924
|
},
|
|
925
|
+
readFile: (filePath) => fs_1.default.promises.readFile(filePath, 'utf-8'),
|
|
926
|
+
appendFile: (filePath, content) => fs_1.default.promises.appendFile(filePath, content, 'utf-8'),
|
|
927
|
+
mkdir: (dirPath, opts) => fs_1.default.promises.mkdir(dirPath, opts),
|
|
928
|
+
homedir: os_1.default.homedir,
|
|
929
|
+
joinPath: path_1.default.join,
|
|
930
|
+
nowIso: () => new Date().toISOString(),
|
|
931
|
+
generateId: () => (0, crypto_1.randomUUID)(),
|
|
900
932
|
stderr: (line) => process.stderr.write(line + '\n'),
|
|
901
933
|
now: () => Date.now(),
|
|
902
934
|
port,
|
package/dist/cli.js
CHANGED
|
@@ -166,24 +166,6 @@ program
|
|
|
166
166
|
});
|
|
167
167
|
(0, interpret_result_js_1.interpretCliResult)(result, terminator);
|
|
168
168
|
});
|
|
169
|
-
program
|
|
170
|
-
.command('cleanup')
|
|
171
|
-
.description('Clean up orphaned workrail processes and free up ports')
|
|
172
|
-
.option('-f, --force', 'Force cleanup without confirmation')
|
|
173
|
-
.action(async (options) => {
|
|
174
|
-
if (!options.force) {
|
|
175
|
-
console.error('⚠️ This will terminate all workrail dashboard processes');
|
|
176
|
-
console.error(' Press Ctrl+C to cancel, or wait 3 seconds to continue...');
|
|
177
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
178
|
-
}
|
|
179
|
-
await (0, container_js_1.initializeContainer)({ runtimeMode: { kind: 'cli' } });
|
|
180
|
-
const terminator = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessTerminator);
|
|
181
|
-
const httpServer = container_js_1.container.resolve(tokens_js_1.DI.Infra.HttpServer);
|
|
182
|
-
const result = await (0, index_js_1.executeCleanupCommand)({
|
|
183
|
-
fullCleanup: () => httpServer.fullCleanup(),
|
|
184
|
-
});
|
|
185
|
-
(0, interpret_result_js_1.interpretCliResult)(result, terminator);
|
|
186
|
-
});
|
|
187
169
|
program
|
|
188
170
|
.command('daemon')
|
|
189
171
|
.description('Start the autonomous WorkRail daemon (trigger webhook server on port 3200)')
|
|
@@ -5,17 +5,6 @@ import type { ValidatedAppConfig } from '../errors/app-error.js';
|
|
|
5
5
|
export type CacheTtlMs = Brand<number, 'CacheTtlMs'>;
|
|
6
6
|
export type ProjectPath = Brand<string, 'ProjectPath'>;
|
|
7
7
|
export type WorkflowDir = Brand<string, 'WorkflowDir'>;
|
|
8
|
-
export type DashboardPort = Brand<number, 'DashboardPort'>;
|
|
9
|
-
export type DashboardMode = {
|
|
10
|
-
readonly kind: 'unified';
|
|
11
|
-
} | {
|
|
12
|
-
readonly kind: 'legacy';
|
|
13
|
-
};
|
|
14
|
-
export type BrowserBehavior = {
|
|
15
|
-
readonly kind: 'auto_open';
|
|
16
|
-
} | {
|
|
17
|
-
readonly kind: 'manual';
|
|
18
|
-
};
|
|
19
8
|
export interface AppConfig {
|
|
20
9
|
readonly cache: {
|
|
21
10
|
readonly ttlMs: CacheTtlMs;
|
|
@@ -24,11 +13,6 @@ export interface AppConfig {
|
|
|
24
13
|
readonly projectPath: ProjectPath;
|
|
25
14
|
readonly workflowDir: WorkflowDir;
|
|
26
15
|
};
|
|
27
|
-
readonly dashboard: {
|
|
28
|
-
readonly mode: DashboardMode;
|
|
29
|
-
readonly browserBehavior: BrowserBehavior;
|
|
30
|
-
readonly port: DashboardPort;
|
|
31
|
-
};
|
|
32
16
|
}
|
|
33
17
|
export type ValidatedConfig = ValidatedAppConfig<AppConfig>;
|
|
34
18
|
export interface LoadConfigOptions {
|
|
@@ -16,13 +16,6 @@ const EnvSchema = zod_1.z.object({
|
|
|
16
16
|
.max(86400000, 'CACHE_TTL cannot exceed 24 hours (86400000ms)')
|
|
17
17
|
.default(300000)),
|
|
18
18
|
WORKRAIL_WORKFLOWS_DIR: zod_1.z.string().optional(),
|
|
19
|
-
WORKRAIL_DISABLE_UNIFIED_DASHBOARD: zod_1.z.enum(['0', '1']).default('0'),
|
|
20
|
-
WORKRAIL_DISABLE_AUTO_OPEN: zod_1.z.enum(['0', '1']).default('0'),
|
|
21
|
-
WORKRAIL_DASHBOARD_PORT: zod_1.z
|
|
22
|
-
.string()
|
|
23
|
-
.optional()
|
|
24
|
-
.transform((v) => (v === undefined ? undefined : Number(v)))
|
|
25
|
-
.pipe(zod_1.z.number().int().min(1024, 'Port must be >= 1024').max(65535, 'Port must be <= 65535').default(3456)),
|
|
26
19
|
});
|
|
27
20
|
function loadConfig(options) {
|
|
28
21
|
const parsed = EnvSchema.safeParse(options.env);
|
|
@@ -35,19 +28,12 @@ function createValidatedConfig(value) {
|
|
|
35
28
|
return value;
|
|
36
29
|
}
|
|
37
30
|
function buildConfig(env, projectPath) {
|
|
38
|
-
const dashboardMode = env.WORKRAIL_DISABLE_UNIFIED_DASHBOARD === '1' ? { kind: 'legacy' } : { kind: 'unified' };
|
|
39
|
-
const browserBehavior = env.WORKRAIL_DISABLE_AUTO_OPEN === '1' ? { kind: 'manual' } : { kind: 'auto_open' };
|
|
40
31
|
return {
|
|
41
32
|
cache: { ttlMs: env.CACHE_TTL },
|
|
42
33
|
paths: {
|
|
43
34
|
projectPath: projectPath,
|
|
44
35
|
workflowDir: (env.WORKRAIL_WORKFLOWS_DIR ?? projectPath),
|
|
45
36
|
},
|
|
46
|
-
dashboard: {
|
|
47
|
-
mode: dashboardMode,
|
|
48
|
-
browserBehavior,
|
|
49
|
-
port: env.WORKRAIL_DASHBOARD_PORT,
|
|
50
|
-
},
|
|
51
37
|
};
|
|
52
38
|
}
|
|
53
39
|
function toConfigIssues(error) {
|
|
@@ -44,9 +44,6 @@ const result_js_1 = require("../runtime/result.js");
|
|
|
44
44
|
const ALLOWED_CONFIG_FILE_KEYS = new Set([
|
|
45
45
|
'CACHE_TTL',
|
|
46
46
|
'WORKRAIL_WORKFLOWS_DIR',
|
|
47
|
-
'WORKRAIL_DISABLE_UNIFIED_DASHBOARD',
|
|
48
|
-
'WORKRAIL_DISABLE_AUTO_OPEN',
|
|
49
|
-
'WORKRAIL_DASHBOARD_PORT',
|
|
50
47
|
'WORKRAIL_DEV',
|
|
51
48
|
'WORKRAIL_ENABLE_SESSION_TOOLS',
|
|
52
49
|
'WORKRAIL_ENABLE_EXPERIMENTAL_WORKFLOWS',
|