@exaudeus/workrail 1.5.0 → 1.5.2
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/application/services/workflow-compiler.js +14 -2
- package/dist/infrastructure/session/HttpServer.js +7 -2
- package/dist/infrastructure/session/SessionManager.d.ts +12 -4
- package/dist/infrastructure/session/SessionManager.js +30 -15
- package/dist/manifest.json +417 -217
- package/dist/mcp/error-mapper.d.ts +1 -1
- package/dist/mcp/error-mapper.js +12 -8
- package/dist/mcp/handler-factory.js +8 -1
- package/dist/mcp/handlers/session.js +36 -58
- package/dist/mcp/handlers/v2-advance-core/event-builders.d.ts +37 -0
- package/dist/mcp/handlers/v2-advance-core/event-builders.js +114 -0
- package/dist/mcp/handlers/v2-advance-core/index.d.ts +67 -0
- package/dist/mcp/handlers/v2-advance-core/index.js +119 -0
- package/dist/mcp/handlers/v2-advance-core/input-validation.d.ts +44 -0
- package/dist/mcp/handlers/v2-advance-core/input-validation.js +58 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-blocked.d.ts +16 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-blocked.js +64 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-success.d.ts +15 -0
- package/dist/mcp/handlers/v2-advance-core/outcome-success.js +136 -0
- package/dist/mcp/handlers/v2-advance-core.d.ts +3 -45
- package/dist/mcp/handlers/v2-advance-core.js +3 -431
- package/dist/mcp/handlers/v2-advance-events.d.ts +61 -0
- package/dist/mcp/handlers/v2-advance-events.js +126 -0
- package/dist/mcp/handlers/v2-checkpoint.js +11 -14
- package/dist/mcp/handlers/v2-context-budget.js +2 -2
- package/dist/mcp/handlers/v2-error-mapping.d.ts +3 -3
- package/dist/mcp/handlers/v2-error-mapping.js +31 -27
- package/dist/mcp/handlers/v2-execution/advance.d.ts +32 -0
- package/dist/mcp/handlers/v2-execution/advance.js +50 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +29 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.js +167 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +22 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +145 -0
- package/dist/mcp/handlers/v2-execution/index.d.ts +31 -0
- package/dist/mcp/handlers/v2-execution/index.js +102 -0
- package/dist/mcp/handlers/v2-execution/replay.d.ts +55 -0
- package/dist/mcp/handlers/v2-execution/replay.js +225 -0
- package/dist/mcp/handlers/v2-execution/start.d.ts +52 -0
- package/dist/mcp/handlers/v2-execution/start.js +331 -0
- package/dist/mcp/handlers/v2-execution-helpers.d.ts +26 -2
- package/dist/mcp/handlers/v2-execution-helpers.js +76 -60
- package/dist/mcp/handlers/v2-execution.d.ts +1 -23
- package/dist/mcp/handlers/v2-execution.js +5 -898
- package/dist/mcp/handlers/v2-state-conversion.d.ts +0 -5
- package/dist/mcp/handlers/v2-state-conversion.js +2 -21
- package/dist/mcp/handlers/v2-token-ops.d.ts +1 -1
- package/dist/mcp/handlers/v2-workflow.js +85 -78
- package/dist/mcp/output-schemas.d.ts +197 -34
- package/dist/mcp/output-schemas.js +12 -5
- package/dist/mcp/tool-descriptions.js +22 -16
- package/dist/mcp/types.d.ts +10 -0
- package/dist/mcp/types.js +10 -0
- package/dist/mcp/v2/tools.d.ts +45 -7
- package/dist/mcp/v2/tools.js +7 -3
- package/dist/types/workflow-definition.d.ts +3 -2
- package/dist/v2/durable-core/canonical/jcs.js +8 -1
- package/dist/v2/durable-core/constants.d.ts +60 -0
- package/dist/v2/durable-core/constants.js +55 -1
- package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +14 -13
- package/dist/v2/durable-core/domain/ack-advance-append-plan.js +143 -116
- package/dist/v2/durable-core/domain/blocked-node-builder.js +9 -3
- package/dist/v2/durable-core/domain/blocking-decision.d.ts +2 -0
- package/dist/v2/durable-core/domain/blocking-decision.js +29 -12
- package/dist/v2/durable-core/domain/bundle-builder.d.ts +1 -0
- package/dist/v2/durable-core/domain/bundle-builder.js +1 -1
- package/dist/v2/durable-core/domain/bundle-validator.js +3 -2
- package/dist/v2/durable-core/domain/decision-trace-builder.js +7 -9
- package/dist/v2/durable-core/domain/function-definition-expander.js +1 -3
- package/dist/v2/durable-core/domain/gap-builder.js +2 -1
- package/dist/v2/durable-core/domain/observation-builder.js +2 -1
- package/dist/v2/durable-core/domain/outputs.d.ts +2 -1
- package/dist/v2/durable-core/domain/outputs.js +3 -2
- package/dist/v2/durable-core/domain/reason-model.d.ts +1 -1
- package/dist/v2/durable-core/domain/reason-model.js +4 -9
- package/dist/v2/durable-core/domain/validation-criteria-validator.js +2 -2
- package/dist/v2/durable-core/domain/validation-event-builder.js +4 -6
- package/dist/v2/durable-core/domain/validation-loader.js +2 -1
- package/dist/v2/durable-core/domain/validation-requirements-extractor.js +12 -18
- package/dist/v2/durable-core/encoding/base32-lower.d.ts +13 -1
- package/dist/v2/durable-core/encoding/base32-lower.js +13 -3
- package/dist/v2/durable-core/encoding/hex-to-bytes.d.ts +6 -0
- package/dist/v2/durable-core/encoding/hex-to-bytes.js +19 -0
- package/dist/v2/durable-core/ids/attempt-id-derivation.d.ts +6 -1
- package/dist/v2/durable-core/ids/attempt-id-derivation.js +9 -19
- package/dist/v2/durable-core/ids/event-ids.d.ts +9 -0
- package/dist/v2/durable-core/ids/event-ids.js +18 -0
- package/dist/v2/durable-core/ids/index.d.ts +13 -33
- package/dist/v2/durable-core/ids/index.js +22 -63
- package/dist/v2/durable-core/ids/session-ids.d.ts +9 -0
- package/dist/v2/durable-core/ids/session-ids.js +18 -0
- package/dist/v2/durable-core/ids/snapshot-ids.d.ts +6 -0
- package/dist/v2/durable-core/ids/snapshot-ids.js +10 -0
- package/dist/v2/durable-core/ids/token-ids.d.ts +3 -0
- package/dist/v2/durable-core/ids/token-ids.js +6 -0
- package/dist/v2/durable-core/ids/workflow-hash-ref.d.ts +3 -0
- package/dist/v2/durable-core/ids/workflow-hash-ref.js +5 -4
- package/dist/v2/durable-core/ids/workflow-ids.d.ts +11 -0
- package/dist/v2/durable-core/ids/workflow-ids.js +21 -0
- package/dist/v2/durable-core/lib/utf8-byte-length.d.ts +1 -0
- package/dist/v2/durable-core/lib/utf8-byte-length.js +6 -0
- package/dist/v2/durable-core/schemas/artifacts/loop-control.d.ts +6 -6
- package/dist/v2/durable-core/schemas/artifacts/loop-control.js +2 -1
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +28 -28
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.js +5 -7
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +296 -296
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +466 -471
- package/dist/v2/durable-core/schemas/export-bundle/index.js +0 -8
- package/dist/v2/durable-core/schemas/lib/dedupe-key.d.ts +9 -1
- package/dist/v2/durable-core/schemas/lib/dedupe-key.js +4 -3
- package/dist/v2/durable-core/schemas/lib/utf8-byte-length.d.ts +1 -0
- package/dist/v2/durable-core/schemas/lib/utf8-byte-length.js +6 -0
- package/dist/v2/durable-core/schemas/session/blockers.d.ts +305 -0
- package/dist/v2/durable-core/schemas/session/blockers.js +80 -0
- package/dist/v2/durable-core/schemas/session/dag-topology.d.ts +77 -0
- package/dist/v2/durable-core/schemas/session/dag-topology.js +45 -0
- package/dist/v2/durable-core/schemas/session/events.d.ts +56 -56
- package/dist/v2/durable-core/schemas/session/events.js +11 -182
- package/dist/v2/durable-core/schemas/session/gaps.d.ts +211 -0
- package/dist/v2/durable-core/schemas/session/gaps.js +37 -0
- package/dist/v2/durable-core/schemas/session/outputs.d.ts +148 -0
- package/dist/v2/durable-core/schemas/session/outputs.js +44 -0
- package/dist/v2/durable-core/schemas/session/validation-event.js +5 -7
- package/dist/v2/durable-core/tokens/token-codec.d.ts +1 -18
- package/dist/v2/durable-core/tokens/token-codec.js +0 -67
- package/dist/v2/durable-core/tokens/token-signer.d.ts +1 -8
- package/dist/v2/durable-core/tokens/token-signer.js +0 -43
- package/dist/v2/infra/local/base32/index.js +1 -23
- package/dist/v2/infra/local/bech32m/index.js +1 -1
- package/dist/v2/infra/local/data-dir/index.d.ts +7 -6
- package/dist/v2/infra/local/data-dir/index.js +3 -3
- package/dist/v2/infra/local/directory-listing/index.d.ts +2 -2
- package/dist/v2/infra/local/session-store/index.js +198 -182
- package/dist/v2/infra/local/session-summary-provider/index.js +5 -2
- package/dist/v2/infra/local/snapshot-store/index.js +2 -2
- package/dist/v2/ports/data-dir.port.d.ts +7 -6
- package/dist/v2/ports/fs.port.d.ts +18 -7
- package/dist/v2/ports/session-event-log-store.port.d.ts +5 -2
- package/dist/v2/projections/advance-outcomes.d.ts +1 -7
- package/dist/v2/projections/advance-outcomes.js +2 -1
- package/dist/v2/projections/artifacts.js +3 -2
- package/dist/v2/projections/capabilities.d.ts +1 -7
- package/dist/v2/projections/capabilities.js +2 -1
- package/dist/v2/projections/gaps.d.ts +1 -7
- package/dist/v2/projections/gaps.js +2 -1
- package/dist/v2/projections/node-outputs.d.ts +1 -7
- package/dist/v2/projections/node-outputs.js +4 -3
- package/dist/v2/projections/preferences.d.ts +1 -7
- package/dist/v2/projections/preferences.js +2 -1
- package/dist/v2/projections/projection-error.d.ts +7 -0
- package/dist/v2/projections/projection-error.js +2 -0
- package/dist/v2/projections/resume-ranking.js +3 -3
- package/dist/v2/projections/run-context.d.ts +1 -7
- package/dist/v2/projections/run-context.js +4 -2
- package/dist/v2/projections/run-dag.d.ts +9 -9
- package/dist/v2/projections/run-dag.js +88 -65
- package/dist/v2/projections/run-status-signals.d.ts +1 -7
- package/dist/v2/projections/run-status-signals.js +3 -2
- package/dist/v2/usecases/execution-session-gate.js +2 -5
- package/dist/v2/usecases/export-session.js +4 -2
- package/dist/v2/usecases/import-session.d.ts +3 -3
- package/package.json +1 -1
- package/workflows/coding-task-workflow-agentic.json +0 -9
- package/workflows/workflow-for-workflows.json +18 -5
|
@@ -22,6 +22,13 @@ let WorkflowCompiler = class WorkflowCompiler {
|
|
|
22
22
|
}
|
|
23
23
|
stepById.set(step.id, step);
|
|
24
24
|
}
|
|
25
|
+
for (const step of steps) {
|
|
26
|
+
const contractRef = step.outputContract?.contractRef;
|
|
27
|
+
if (contractRef && !(0, index_1.isValidContractRef)(contractRef)) {
|
|
28
|
+
return (0, neverthrow_1.err)(error_1.Err.invalidState(`Step '${step.id}' declares unknown outputContract.contractRef '${contractRef}'. ` +
|
|
29
|
+
`Known contracts: ${index_1.LOOP_CONTROL_CONTRACT_REF}`));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
25
32
|
const compiledLoops = new Map();
|
|
26
33
|
const loopBodyStepIds = new Set();
|
|
27
34
|
for (const step of steps) {
|
|
@@ -33,6 +40,11 @@ let WorkflowCompiler = class WorkflowCompiler {
|
|
|
33
40
|
return (0, neverthrow_1.err)(bodyResolved.error);
|
|
34
41
|
for (const bodyStep of bodyResolved.value) {
|
|
35
42
|
loopBodyStepIds.add(bodyStep.id);
|
|
43
|
+
const ref = bodyStep.outputContract?.contractRef;
|
|
44
|
+
if (ref && !(0, index_1.isValidContractRef)(ref)) {
|
|
45
|
+
return (0, neverthrow_1.err)(error_1.Err.invalidState(`Loop body step '${bodyStep.id}' in loop '${loop.id}' declares unknown outputContract.contractRef '${ref}'. ` +
|
|
46
|
+
`Known contracts: ${index_1.LOOP_CONTROL_CONTRACT_REF}`));
|
|
47
|
+
}
|
|
36
48
|
}
|
|
37
49
|
const conditionSource = this.deriveConditionSource(loop, bodyResolved.value);
|
|
38
50
|
compiledLoops.set(loop.id, {
|
|
@@ -56,8 +68,8 @@ let WorkflowCompiler = class WorkflowCompiler {
|
|
|
56
68
|
if (loop.loop.conditionSource) {
|
|
57
69
|
return loop.loop.conditionSource;
|
|
58
70
|
}
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
71
|
+
const loopControlStep = bodySteps.find((s) => s.outputContract?.contractRef === index_1.LOOP_CONTROL_CONTRACT_REF);
|
|
72
|
+
if (loopControlStep) {
|
|
61
73
|
return {
|
|
62
74
|
kind: 'artifact_contract',
|
|
63
75
|
contractRef: index_1.LOOP_CONTROL_CONTRACT_REF,
|
|
@@ -283,7 +283,12 @@ let HttpServer = class HttpServer {
|
|
|
283
283
|
this.app.delete('/api/sessions/:workflow/:id', async (req, res) => {
|
|
284
284
|
try {
|
|
285
285
|
const { workflow, id } = req.params;
|
|
286
|
-
await this.sessionManager.deleteSession(workflow, id);
|
|
286
|
+
const result = await this.sessionManager.deleteSession(workflow, id);
|
|
287
|
+
if (result.isErr()) {
|
|
288
|
+
const status = result.error.code === 'SESSION_NOT_FOUND' ? 404 : 500;
|
|
289
|
+
res.status(status).json({ success: false, error: result.error.message });
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
287
292
|
res.json({
|
|
288
293
|
success: true,
|
|
289
294
|
message: `Session ${workflow}/${id} deleted successfully`
|
|
@@ -291,7 +296,7 @@ let HttpServer = class HttpServer {
|
|
|
291
296
|
}
|
|
292
297
|
catch (error) {
|
|
293
298
|
console.error('[HttpServer] Delete session error:', error);
|
|
294
|
-
res.status(
|
|
299
|
+
res.status(500).json({
|
|
295
300
|
success: false,
|
|
296
301
|
error: error.message || 'Failed to delete session'
|
|
297
302
|
});
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
import { type Result } from 'neverthrow';
|
|
2
3
|
import { SessionDataNormalizer } from './SessionDataNormalizer';
|
|
3
4
|
import { SessionDataValidator } from './SessionDataValidator';
|
|
5
|
+
export type SessionManagerError = {
|
|
6
|
+
readonly code: 'SESSION_NOT_FOUND';
|
|
7
|
+
readonly message: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly code: 'IO_ERROR';
|
|
10
|
+
readonly message: string;
|
|
11
|
+
};
|
|
4
12
|
export interface Session {
|
|
5
13
|
id: string;
|
|
6
14
|
workflowId: string;
|
|
@@ -30,10 +38,10 @@ export declare class SessionManager extends EventEmitter {
|
|
|
30
38
|
private findGitRepoRoot;
|
|
31
39
|
private getProjectRoot;
|
|
32
40
|
getSessionPath(workflowId: string, sessionId: string): string;
|
|
33
|
-
createSession(workflowId: string, sessionId: string, initialData?: Record<string, any>): Promise<Session
|
|
34
|
-
updateSession(workflowId: string, sessionId: string, updates: Record<string, any>): Promise<Session
|
|
35
|
-
readSession(workflowId: string, sessionId: string, queryPath?: string): Promise<
|
|
36
|
-
deleteSession(workflowId: string, sessionId: string): Promise<void
|
|
41
|
+
createSession(workflowId: string, sessionId: string, initialData?: Record<string, any>): Promise<Result<Session, SessionManagerError>>;
|
|
42
|
+
updateSession(workflowId: string, sessionId: string, updates: Record<string, any>): Promise<Result<Session, SessionManagerError>>;
|
|
43
|
+
readSession(workflowId: string, sessionId: string, queryPath?: string): Promise<Result<unknown, SessionManagerError>>;
|
|
44
|
+
deleteSession(workflowId: string, sessionId: string): Promise<Result<void, SessionManagerError>>;
|
|
37
45
|
deleteSessions(sessions: Array<{
|
|
38
46
|
workflowId: string;
|
|
39
47
|
sessionId: string;
|
|
@@ -24,6 +24,7 @@ const child_process_1 = require("child_process");
|
|
|
24
24
|
const os_1 = __importDefault(require("os"));
|
|
25
25
|
const events_1 = require("events");
|
|
26
26
|
const tsyringe_1 = require("tsyringe");
|
|
27
|
+
const neverthrow_1 = require("neverthrow");
|
|
27
28
|
const tokens_js_1 = require("../../di/tokens.js");
|
|
28
29
|
const SessionDataNormalizer_1 = require("./SessionDataNormalizer");
|
|
29
30
|
const SessionDataValidator_1 = require("./SessionDataValidator");
|
|
@@ -76,7 +77,12 @@ let SessionManager = class SessionManager extends events_1.EventEmitter {
|
|
|
76
77
|
}
|
|
77
78
|
async createSession(workflowId, sessionId, initialData = {}) {
|
|
78
79
|
const sessionPath = this.getSessionPath(workflowId, sessionId);
|
|
79
|
-
|
|
80
|
+
try {
|
|
81
|
+
await promises_1.default.mkdir(path_1.default.dirname(sessionPath), { recursive: true });
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
return (0, neverthrow_1.err)({ code: 'IO_ERROR', message: `Failed to create session directory: ${e instanceof Error ? e.message : String(e)}` });
|
|
85
|
+
}
|
|
80
86
|
const session = {
|
|
81
87
|
id: sessionId,
|
|
82
88
|
workflowId,
|
|
@@ -86,15 +92,20 @@ let SessionManager = class SessionManager extends events_1.EventEmitter {
|
|
|
86
92
|
updatedAt: new Date().toISOString(),
|
|
87
93
|
data: initialData
|
|
88
94
|
};
|
|
89
|
-
|
|
95
|
+
try {
|
|
96
|
+
await this.atomicWrite(sessionPath, session);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
return (0, neverthrow_1.err)({ code: 'IO_ERROR', message: `Failed to write session: ${e instanceof Error ? e.message : String(e)}` });
|
|
100
|
+
}
|
|
90
101
|
await this.updateProjectMetadata();
|
|
91
|
-
return session;
|
|
102
|
+
return (0, neverthrow_1.ok)(session);
|
|
92
103
|
}
|
|
93
104
|
async updateSession(workflowId, sessionId, updates) {
|
|
94
105
|
const sessionPath = this.getSessionPath(workflowId, sessionId);
|
|
95
106
|
const session = await this.getSession(workflowId, sessionId);
|
|
96
107
|
if (!session) {
|
|
97
|
-
|
|
108
|
+
return (0, neverthrow_1.err)({ code: 'SESSION_NOT_FOUND', message: `Session not found: ${workflowId}/${sessionId}` });
|
|
98
109
|
}
|
|
99
110
|
const mergedData = this.deepMerge(session.data, updates);
|
|
100
111
|
const normalizedData = this.normalizer.normalize(workflowId, mergedData);
|
|
@@ -104,36 +115,40 @@ let SessionManager = class SessionManager extends events_1.EventEmitter {
|
|
|
104
115
|
}
|
|
105
116
|
session.data = normalizedData;
|
|
106
117
|
session.updatedAt = new Date().toISOString();
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
try {
|
|
119
|
+
await this.atomicWrite(sessionPath, session);
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
return (0, neverthrow_1.err)({ code: 'IO_ERROR', message: `Failed to write session: ${e instanceof Error ? e.message : String(e)}` });
|
|
123
|
+
}
|
|
124
|
+
return (0, neverthrow_1.ok)(session);
|
|
109
125
|
}
|
|
110
126
|
async readSession(workflowId, sessionId, queryPath) {
|
|
111
127
|
const session = await this.getSession(workflowId, sessionId);
|
|
112
128
|
if (!session) {
|
|
113
|
-
|
|
129
|
+
return (0, neverthrow_1.err)({ code: 'SESSION_NOT_FOUND', message: `Session not found: ${workflowId}/${sessionId}` });
|
|
114
130
|
}
|
|
115
131
|
if (!queryPath) {
|
|
116
|
-
return session.data;
|
|
132
|
+
return (0, neverthrow_1.ok)(session.data);
|
|
117
133
|
}
|
|
118
|
-
return this.getPath(session.data, queryPath);
|
|
134
|
+
return (0, neverthrow_1.ok)(this.getPath(session.data, queryPath));
|
|
119
135
|
}
|
|
120
136
|
async deleteSession(workflowId, sessionId) {
|
|
121
137
|
const sessionPath = this.getSessionPath(workflowId, sessionId);
|
|
122
138
|
const exists = await promises_1.default.access(sessionPath).then(() => true).catch(() => false);
|
|
123
139
|
if (!exists) {
|
|
124
|
-
|
|
140
|
+
return (0, neverthrow_1.err)({ code: 'SESSION_NOT_FOUND', message: `Session not found: ${workflowId}/${sessionId}` });
|
|
125
141
|
}
|
|
126
142
|
this.unwatchSession(workflowId, sessionId);
|
|
127
143
|
await promises_1.default.unlink(sessionPath);
|
|
128
144
|
await this.updateProjectMetadata();
|
|
145
|
+
return (0, neverthrow_1.ok)(undefined);
|
|
129
146
|
}
|
|
130
147
|
async deleteSessions(sessions) {
|
|
131
148
|
for (const { workflowId, sessionId } of sessions) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
catch (error) {
|
|
136
|
-
console.error(`Failed to delete ${workflowId}/${sessionId}:`, error);
|
|
149
|
+
const res = await this.deleteSession(workflowId, sessionId);
|
|
150
|
+
if (res.isErr()) {
|
|
151
|
+
console.error(`Failed to delete ${workflowId}/${sessionId}:`, res.error.message);
|
|
137
152
|
}
|
|
138
153
|
}
|
|
139
154
|
}
|