@exaudeus/workrail 2.0.0 → 3.0.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.
Files changed (72) hide show
  1. package/dist/application/services/compiler/template-registry.d.ts +4 -2
  2. package/dist/application/services/compiler/template-registry.js +97 -5
  3. package/dist/application/services/workflow-compiler.d.ts +5 -1
  4. package/dist/application/services/workflow-compiler.js +20 -7
  5. package/dist/application/use-cases/raw-workflow-file-scanner.d.ts +1 -1
  6. package/dist/application/use-cases/raw-workflow-file-scanner.js +2 -0
  7. package/dist/application/use-cases/validate-workflow-registry.js +2 -1
  8. package/dist/config/feature-flags.js +8 -0
  9. package/dist/di/container.js +10 -1
  10. package/dist/di/tokens.d.ts +1 -0
  11. package/dist/di/tokens.js +1 -0
  12. package/dist/engine/engine-factory.d.ts +3 -0
  13. package/dist/engine/engine-factory.js +295 -0
  14. package/dist/engine/index.d.ts +3 -0
  15. package/dist/engine/index.js +12 -0
  16. package/dist/engine/types.d.ts +130 -0
  17. package/dist/engine/types.js +18 -0
  18. package/dist/infrastructure/storage/file-workflow-storage.d.ts +1 -0
  19. package/dist/infrastructure/storage/file-workflow-storage.js +18 -3
  20. package/dist/infrastructure/storage/workflow-resolution.d.ts +9 -6
  21. package/dist/infrastructure/storage/workflow-resolution.js +14 -1
  22. package/dist/manifest.json +166 -94
  23. package/dist/mcp/handlers/shared/request-workflow-reader.d.ts +19 -0
  24. package/dist/mcp/handlers/shared/request-workflow-reader.js +50 -0
  25. package/dist/mcp/handlers/v2-checkpoint.d.ts +31 -1
  26. package/dist/mcp/handlers/v2-checkpoint.js +76 -64
  27. package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +2 -0
  28. package/dist/mcp/handlers/v2-execution/continue-advance.js +5 -5
  29. package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +2 -0
  30. package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +17 -22
  31. package/dist/mcp/handlers/v2-execution/index.d.ts +10 -17
  32. package/dist/mcp/handlers/v2-execution/index.js +44 -54
  33. package/dist/mcp/handlers/v2-execution/replay.d.ts +4 -15
  34. package/dist/mcp/handlers/v2-execution/replay.js +52 -128
  35. package/dist/mcp/handlers/v2-execution/start.d.ts +4 -3
  36. package/dist/mcp/handlers/v2-execution/start.js +32 -49
  37. package/dist/mcp/handlers/v2-token-ops.d.ts +45 -24
  38. package/dist/mcp/handlers/v2-token-ops.js +372 -32
  39. package/dist/mcp/handlers/v2-workflow.d.ts +1 -1
  40. package/dist/mcp/handlers/v2-workflow.js +25 -4
  41. package/dist/mcp/output-schemas.d.ts +104 -283
  42. package/dist/mcp/output-schemas.js +24 -22
  43. package/dist/mcp/server.js +8 -0
  44. package/dist/mcp/tool-descriptions.js +9 -2
  45. package/dist/mcp/types.d.ts +4 -0
  46. package/dist/mcp/v2/tools.d.ts +32 -53
  47. package/dist/mcp/v2/tools.js +27 -37
  48. package/dist/mcp/v2-response-formatter.js +12 -16
  49. package/dist/runtime/runtime-mode.d.ts +2 -0
  50. package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
  51. package/dist/v2/durable-core/domain/prompt-renderer.js +5 -3
  52. package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +14 -14
  53. package/dist/v2/durable-core/schemas/session/events.d.ts +4 -4
  54. package/dist/v2/durable-core/schemas/session/validation-event.d.ts +2 -2
  55. package/dist/v2/durable-core/tokens/payloads.d.ts +32 -32
  56. package/dist/v2/durable-core/tokens/short-token.d.ts +38 -0
  57. package/dist/v2/durable-core/tokens/short-token.js +126 -0
  58. package/dist/v2/durable-core/tokens/token-patterns.d.ts +4 -0
  59. package/dist/v2/durable-core/tokens/token-patterns.js +9 -0
  60. package/dist/v2/infra/in-memory/token-alias-store/index.d.ts +11 -0
  61. package/dist/v2/infra/in-memory/token-alias-store/index.js +38 -0
  62. package/dist/v2/infra/local/data-dir/index.d.ts +1 -0
  63. package/dist/v2/infra/local/data-dir/index.js +3 -0
  64. package/dist/v2/infra/local/token-alias-store/index.d.ts +16 -0
  65. package/dist/v2/infra/local/token-alias-store/index.js +117 -0
  66. package/dist/v2/ports/data-dir.port.d.ts +1 -0
  67. package/dist/v2/ports/token-alias-store.port.d.ts +33 -0
  68. package/dist/v2/ports/token-alias-store.port.js +2 -0
  69. package/package.json +8 -1
  70. package/workflows/coding-task-workflow-agentic.lean.v2.json +224 -0
  71. package/workflows/routines/philosophy-alignment.json +12 -12
  72. package/workflows/routines/tension-driven-design.json +63 -0
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2CheckpointWorkflowOutputSchema = exports.V2ResumeSessionOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2BlockerReportSchema = exports.V2NextCallSchema = exports.V2NextIntentSchema = exports.V2PreferencesSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.V2WorkflowListItemSchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
4
+ exports.toPendingStep = toPendingStep;
4
5
  const zod_1 = require("zod");
5
6
  const state_js_1 = require("../domain/execution/state.js");
7
+ const token_patterns_js_1 = require("../v2/durable-core/tokens/token-patterns.js");
6
8
  const JsonPrimitiveSchema = zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean(), zod_1.z.null()]);
7
9
  exports.JsonValueSchema = zod_1.z.lazy(() => zod_1.z.union([JsonPrimitiveSchema, zod_1.z.array(exports.JsonValueSchema), zod_1.z.record(exports.JsonValueSchema)]));
8
10
  exports.WorkflowSummarySchema = zod_1.z.object({
@@ -66,7 +68,18 @@ exports.V2PendingStepSchema = zod_1.z.object({
66
68
  stepId: zod_1.z.string().min(1),
67
69
  title: zod_1.z.string().min(1),
68
70
  prompt: zod_1.z.string().min(1),
71
+ agentRole: zod_1.z.string().min(1).optional(),
69
72
  });
73
+ function toPendingStep(meta) {
74
+ if (!meta)
75
+ return null;
76
+ return {
77
+ stepId: meta.stepId,
78
+ title: meta.title,
79
+ prompt: meta.prompt,
80
+ ...(meta.agentRole ? { agentRole: meta.agentRole } : {}),
81
+ };
82
+ }
70
83
  exports.V2PreferencesSchema = zod_1.z.object({
71
84
  autonomy: zod_1.z.enum(['guided', 'full_auto_stop_on_user_deps', 'full_auto_never_stop']),
72
85
  riskPolicy: zod_1.z.enum(['conservative', 'balanced', 'aggressive']),
@@ -77,18 +90,9 @@ exports.V2NextIntentSchema = zod_1.z.enum([
77
90
  'rehydrate_only',
78
91
  'complete',
79
92
  ]);
80
- const V2NextCallAdvanceParams = zod_1.z.object({
81
- intent: zod_1.z.literal('advance'),
82
- stateToken: zod_1.z.string().min(1),
83
- ackToken: zod_1.z.string().min(1),
84
- });
85
- const V2NextCallRehydrateParams = zod_1.z.object({
86
- intent: zod_1.z.literal('rehydrate'),
87
- stateToken: zod_1.z.string().min(1),
88
- });
89
93
  exports.V2NextCallSchema = zod_1.z.object({
90
94
  tool: zod_1.z.literal('continue_workflow'),
91
- params: zod_1.z.discriminatedUnion('intent', [V2NextCallAdvanceParams, V2NextCallRehydrateParams]),
95
+ params: zod_1.z.object({ continueToken: zod_1.z.string().min(1) }),
92
96
  }).nullable();
93
97
  function utf8ByteLength(s) {
94
98
  return new TextEncoder().encode(s).length;
@@ -176,11 +180,11 @@ exports.V2BlockerReportSchema = zod_1.z
176
180
  }
177
181
  }
178
182
  });
179
- const checkpointTokenSchema = zod_1.z.string().regex(/^chk1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid checkpointToken format').optional();
183
+ const checkpointTokenSchema = zod_1.z.string().regex(token_patterns_js_1.CHECKPOINT_TOKEN_PATTERN, 'Invalid checkpointToken format').optional();
184
+ const continueTokenSchema = zod_1.z.string().regex(token_patterns_js_1.CONTINUE_TOKEN_PATTERN, 'Invalid continueToken format').optional();
180
185
  const V2ContinueWorkflowOkSchema = zod_1.z.object({
181
186
  kind: zod_1.z.literal('ok'),
182
- stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
183
- ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
187
+ continueToken: continueTokenSchema,
184
188
  checkpointToken: checkpointTokenSchema,
185
189
  isComplete: zod_1.z.boolean(),
186
190
  pending: exports.V2PendingStepSchema.nullable(),
@@ -190,8 +194,7 @@ const V2ContinueWorkflowOkSchema = zod_1.z.object({
190
194
  });
191
195
  const V2ContinueWorkflowBlockedSchema = zod_1.z.object({
192
196
  kind: zod_1.z.literal('blocked'),
193
- stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
194
- ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
197
+ continueToken: continueTokenSchema,
195
198
  checkpointToken: checkpointTokenSchema,
196
199
  isComplete: zod_1.z.boolean(),
197
200
  pending: exports.V2PendingStepSchema.nullable(),
@@ -200,7 +203,7 @@ const V2ContinueWorkflowBlockedSchema = zod_1.z.object({
200
203
  nextCall: exports.V2NextCallSchema,
201
204
  blockers: exports.V2BlockerReportSchema,
202
205
  retryable: zod_1.z.boolean().optional(),
203
- retryAckToken: zod_1.z.string().optional(),
206
+ retryContinueToken: zod_1.z.string().optional(),
204
207
  validation: zod_1.z
205
208
  .object({
206
209
  issues: zod_1.z.array(zod_1.z.string()),
@@ -211,12 +214,12 @@ const V2ContinueWorkflowBlockedSchema = zod_1.z.object({
211
214
  exports.V2ContinueWorkflowOutputSchema = zod_1.z.discriminatedUnion('kind', [
212
215
  V2ContinueWorkflowOkSchema,
213
216
  V2ContinueWorkflowBlockedSchema,
214
- ]).refine((data) => (data.pending ? data.ackToken != null : true), { message: 'ackToken is required when a pending step exists' });
217
+ ]).refine((data) => (data.pending ? data.continueToken != null : true), { message: 'continueToken is required when a pending step exists' });
215
218
  exports.V2ResumeSessionOutputSchema = zod_1.z.object({
216
219
  candidates: zod_1.z.array(zod_1.z.object({
217
220
  sessionId: zod_1.z.string().min(1),
218
221
  runId: zod_1.z.string().min(1),
219
- stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
222
+ stateToken: zod_1.z.string().regex(token_patterns_js_1.STATE_TOKEN_PATTERN, 'Invalid stateToken format'),
220
223
  snippet: zod_1.z.string().max(1024),
221
224
  whyMatched: zod_1.z.array(zod_1.z.enum([
222
225
  'matched_head_sha',
@@ -230,20 +233,19 @@ exports.V2ResumeSessionOutputSchema = zod_1.z.object({
230
233
  });
231
234
  exports.V2CheckpointWorkflowOutputSchema = zod_1.z.object({
232
235
  checkpointNodeId: zod_1.z.string().min(1),
233
- stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
236
+ stateToken: zod_1.z.string().regex(token_patterns_js_1.STATE_TOKEN_PATTERN, 'Invalid stateToken format'),
234
237
  nextCall: exports.V2NextCallSchema.describe('Pre-built template for your next continue_workflow call. ' +
235
238
  'After checkpoint, use this to rehydrate and continue working on the current step.'),
236
239
  });
237
240
  exports.V2StartWorkflowOutputSchema = zod_1.z.object({
238
- stateToken: zod_1.z.string().regex(/^st1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid stateToken format'),
239
- ackToken: zod_1.z.string().regex(/^ack1[023456789acdefghjklmnpqrstuvwxyz]+$/, 'Invalid ackToken format').optional(),
241
+ continueToken: continueTokenSchema,
240
242
  checkpointToken: checkpointTokenSchema,
241
243
  isComplete: zod_1.z.boolean(),
242
244
  pending: exports.V2PendingStepSchema.nullable(),
243
245
  preferences: exports.V2PreferencesSchema,
244
246
  nextIntent: exports.V2NextIntentSchema,
245
247
  nextCall: exports.V2NextCallSchema,
246
- }).refine((data) => (data.pending ? data.ackToken != null : true), { message: 'ackToken is required when a pending step exists' });
248
+ }).refine((data) => (data.pending ? data.continueToken != null : true), { message: 'continueToken is required when a pending step exists' });
247
249
  exports.CreateSessionOutputSchema = zod_1.z.object({
248
250
  sessionId: zod_1.z.string().min(1),
249
251
  workflowId: zod_1.z.string().min(1),
@@ -81,6 +81,7 @@ async function createToolContext() {
81
81
  else {
82
82
  const sha256 = container_js_1.container.resolve(tokens_js_1.DI.V2.Sha256);
83
83
  const crypto = container_js_1.container.resolve(tokens_js_1.DI.V2.Crypto);
84
+ const entropy = container_js_1.container.resolve(tokens_js_1.DI.V2.RandomEntropy);
84
85
  const hmac = container_js_1.container.resolve(tokens_js_1.DI.V2.HmacSha256);
85
86
  const base64url = container_js_1.container.resolve(tokens_js_1.DI.V2.Base64Url);
86
87
  const base32 = container_js_1.container.resolve(tokens_js_1.DI.V2.Base32);
@@ -104,6 +105,11 @@ async function createToolContext() {
104
105
  compiler,
105
106
  normalizeToExecutable: v1_to_v2_shim_js_1.normalizeV1WorkflowToPinnedSnapshot,
106
107
  };
108
+ const tokenAliasStore = container_js_1.container.resolve(tokens_js_1.DI.V2.TokenAliasStore);
109
+ const aliasLoadResult = await tokenAliasStore.loadIndex();
110
+ if (aliasLoadResult.isErr()) {
111
+ console.error(`[V2Init] Token alias index load warning: ${aliasLoadResult.error.message}`);
112
+ }
107
113
  v2 = {
108
114
  gate,
109
115
  sessionStore,
@@ -111,8 +117,10 @@ async function createToolContext() {
111
117
  pinnedStore,
112
118
  sha256,
113
119
  crypto,
120
+ entropy,
114
121
  idFactory,
115
122
  tokenCodecPorts,
123
+ tokenAliasStore,
116
124
  validationPipelineDeps,
117
125
  resolvedRootUris: [],
118
126
  workspaceResolver: new index_js_1.LocalWorkspaceAnchorV2(process.cwd()),
@@ -49,7 +49,9 @@ This tool provides:
49
49
  - Schema version and metadata information`,
50
50
  list_workflows: `Lists available workflows using WorkRail v2 (feature-flagged). Returns workflow metadata plus pinned snapshot hashes for deterministic execution.
51
51
 
52
- Use this to discover workflows before attempting multi-step tasks. When a workflow exists for the user's request, following it means following the user's structured instructions.`,
52
+ Use this to discover workflows before attempting multi-step tasks. When a workflow exists for the user's request, following it means following the user's structured instructions.
53
+
54
+ Pass workspacePath when available so project-scoped workflow variants are resolved against the correct workspace instead of the server's fallback directory.`,
53
55
  inspect_workflow: `Inspect a workflow structure before starting it (WorkRail v2, feature-flagged).
54
56
 
55
57
  Use this to understand what steps the workflow will guide you through. The workflow is a step-by-step plan the user (or workflow author) created for this type of task.
@@ -58,6 +60,8 @@ Returns:
58
60
  - metadata mode: Just name and description
59
61
  - preview mode: Full step-by-step breakdown (default)
60
62
 
63
+ Pass workspacePath when available so project-scoped workflow variants are resolved against the correct workspace.
64
+
61
65
  Remember: inspecting is read-only. Call start_workflow when ready to begin.`,
62
66
  start_workflow: `Begin following a workflow's step-by-step instructions (WorkRail v2, feature-flagged).
63
67
 
@@ -192,7 +196,9 @@ Returns the complete schema definition including required fields, valid patterns
192
196
 
193
197
  Workflows are the user's pre-defined instructions for complex tasks. When a workflow exists for the user's request, you MUST use it instead of improvising your own approach.
194
198
 
195
- Returns stable workflow metadata and pinned snapshot hashes (workflowHash) for deterministic execution.`,
199
+ Returns stable workflow metadata and pinned snapshot hashes (workflowHash) for deterministic execution.
200
+
201
+ Pass workspacePath when available so project-scoped workflow variants are resolved against the correct workspace.`,
196
202
  inspect_workflow: `Inspect a workflow you are considering following (WorkRail v2, feature-flagged).
197
203
 
198
204
  Use this to understand the workflow's structure before starting. The workflow is the user's explicit plan - not suggestions, not guidelines, but direct instructions you will follow.
@@ -200,6 +206,7 @@ Use this to understand the workflow's structure before starting. The workflow is
200
206
  Parameters:
201
207
  - workflowId: The workflow to inspect
202
208
  - mode: 'metadata' (name/description only) or 'preview' (full step breakdown)
209
+ - workspacePath: optional absolute workspace path for correct project-scoped workflow resolution
203
210
 
204
211
  This is read-only. Call start_workflow when ready to commit to following the workflow.`,
205
212
  start_workflow: `Begin executing the user's workflow instructions (WorkRail v2, feature-flagged).
@@ -17,6 +17,8 @@ import type { DataDirPortV2 } from '../v2/ports/data-dir.port.js';
17
17
  import type { DirectoryListingPortV2 } from '../v2/ports/directory-listing.port.js';
18
18
  import type { SessionSummaryProviderPortV2 } from '../v2/ports/session-summary-provider.port.js';
19
19
  import type { ValidationPipelineDepsPhase1a } from '../application/services/workflow-validation-pipeline.js';
20
+ import type { TokenAliasStorePortV2 } from '../v2/ports/token-alias-store.port.js';
21
+ import type { RandomEntropyPortV2 } from '../v2/ports/random-entropy.port.js';
20
22
  export interface SessionHealthDetails {
21
23
  readonly health: SessionHealthV2;
22
24
  }
@@ -56,6 +58,8 @@ export interface V2Dependencies {
56
58
  readonly crypto: CryptoPortV2;
57
59
  readonly idFactory: IdFactoryV2;
58
60
  readonly tokenCodecPorts: TokenCodecPorts;
61
+ readonly tokenAliasStore: TokenAliasStorePortV2;
62
+ readonly entropy: RandomEntropyPortV2;
59
63
  readonly validationPipelineDeps: ValidationPipelineDepsPhase1a;
60
64
  readonly resolvedRootUris?: readonly string[];
61
65
  readonly workspaceResolver?: WorkspaceContextResolverPortV2;
@@ -1,16 +1,25 @@
1
1
  import { z } from 'zod';
2
2
  import type { ToolAnnotations } from '../tool-factory.js';
3
- export declare const V2ListWorkflowsInput: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
3
+ export declare const V2ListWorkflowsInput: z.ZodObject<{
4
+ workspacePath: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ workspacePath?: string | undefined;
7
+ }, {
8
+ workspacePath?: string | undefined;
9
+ }>;
4
10
  export type V2ListWorkflowsInput = z.infer<typeof V2ListWorkflowsInput>;
5
11
  export declare const V2InspectWorkflowInput: z.ZodObject<{
6
12
  workflowId: z.ZodString;
7
13
  mode: z.ZodDefault<z.ZodEnum<["metadata", "preview"]>>;
14
+ workspacePath: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
8
15
  }, "strip", z.ZodTypeAny, {
9
16
  workflowId: string;
10
17
  mode: "metadata" | "preview";
18
+ workspacePath?: string | undefined;
11
19
  }, {
12
20
  workflowId: string;
13
21
  mode?: "metadata" | "preview" | undefined;
22
+ workspacePath?: string | undefined;
14
23
  }>;
15
24
  export type V2InspectWorkflowInput = z.infer<typeof V2InspectWorkflowInput>;
16
25
  export declare const V2StartWorkflowInput: z.ZodObject<{
@@ -25,9 +34,8 @@ export declare const V2StartWorkflowInput: z.ZodObject<{
25
34
  }>;
26
35
  export type V2StartWorkflowInput = z.infer<typeof V2StartWorkflowInput>;
27
36
  export declare const V2ContinueWorkflowInputShape: z.ZodObject<{
37
+ continueToken: z.ZodString;
28
38
  intent: z.ZodOptional<z.ZodEnum<["advance", "rehydrate"]>>;
29
- stateToken: z.ZodString;
30
- ackToken: z.ZodOptional<z.ZodString>;
31
39
  context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
32
40
  output: z.ZodOptional<z.ZodObject<{
33
41
  notesMarkdown: z.ZodOptional<z.ZodString>;
@@ -40,28 +48,25 @@ export declare const V2ContinueWorkflowInputShape: z.ZodObject<{
40
48
  artifacts?: unknown[] | undefined;
41
49
  }>>;
42
50
  }, "strict", z.ZodTypeAny, {
43
- stateToken: string;
51
+ continueToken: string;
44
52
  context?: Record<string, unknown> | undefined;
45
53
  output?: {
46
54
  notesMarkdown?: string | undefined;
47
55
  artifacts?: unknown[] | undefined;
48
56
  } | undefined;
49
57
  intent?: "advance" | "rehydrate" | undefined;
50
- ackToken?: string | undefined;
51
58
  }, {
52
- stateToken: string;
59
+ continueToken: string;
53
60
  context?: Record<string, unknown> | undefined;
54
61
  output?: {
55
62
  notesMarkdown?: string | undefined;
56
63
  artifacts?: unknown[] | undefined;
57
64
  } | undefined;
58
65
  intent?: "advance" | "rehydrate" | undefined;
59
- ackToken?: string | undefined;
60
66
  }>;
61
- export declare const V2ContinueWorkflowInput: z.ZodPipeline<z.ZodEffects<z.ZodObject<{
67
+ export declare const V2ContinueWorkflowInput: z.ZodEffects<z.ZodEffects<z.ZodObject<{
68
+ continueToken: z.ZodString;
62
69
  intent: z.ZodOptional<z.ZodEnum<["advance", "rehydrate"]>>;
63
- stateToken: z.ZodString;
64
- ackToken: z.ZodOptional<z.ZodString>;
65
70
  context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
66
71
  output: z.ZodOptional<z.ZodObject<{
67
72
  notesMarkdown: z.ZodOptional<z.ZodString>;
@@ -74,80 +79,54 @@ export declare const V2ContinueWorkflowInput: z.ZodPipeline<z.ZodEffects<z.ZodOb
74
79
  artifacts?: unknown[] | undefined;
75
80
  }>>;
76
81
  }, "strict", z.ZodTypeAny, {
77
- stateToken: string;
82
+ continueToken: string;
78
83
  context?: Record<string, unknown> | undefined;
79
84
  output?: {
80
85
  notesMarkdown?: string | undefined;
81
86
  artifacts?: unknown[] | undefined;
82
87
  } | undefined;
83
88
  intent?: "advance" | "rehydrate" | undefined;
84
- ackToken?: string | undefined;
85
89
  }, {
86
- stateToken: string;
90
+ continueToken: string;
87
91
  context?: Record<string, unknown> | undefined;
88
92
  output?: {
89
93
  notesMarkdown?: string | undefined;
90
94
  artifacts?: unknown[] | undefined;
91
95
  } | undefined;
92
96
  intent?: "advance" | "rehydrate" | undefined;
93
- ackToken?: string | undefined;
94
97
  }>, {
95
- stateToken: string;
98
+ continueToken: string;
96
99
  context?: Record<string, unknown> | undefined;
97
100
  output?: {
98
101
  notesMarkdown?: string | undefined;
99
102
  artifacts?: unknown[] | undefined;
100
103
  } | undefined;
101
104
  intent?: "advance" | "rehydrate" | undefined;
102
- ackToken?: string | undefined;
103
- } & {
104
- intent: "advance" | "rehydrate";
105
105
  }, {
106
- stateToken: string;
106
+ continueToken: string;
107
107
  context?: Record<string, unknown> | undefined;
108
108
  output?: {
109
109
  notesMarkdown?: string | undefined;
110
110
  artifacts?: unknown[] | undefined;
111
111
  } | undefined;
112
112
  intent?: "advance" | "rehydrate" | undefined;
113
- ackToken?: string | undefined;
114
- }>, z.ZodEffects<z.ZodType<{
115
- intent: "advance" | "rehydrate";
116
- stateToken: string;
117
- ackToken?: string;
118
- context?: Record<string, unknown>;
119
- output?: {
120
- notesMarkdown?: string;
121
- artifacts?: unknown[];
122
- };
123
- }, z.ZodTypeDef, {
124
- intent: "advance" | "rehydrate";
125
- stateToken: string;
126
- ackToken?: string;
127
- context?: Record<string, unknown>;
128
- output?: {
129
- notesMarkdown?: string;
130
- artifacts?: unknown[];
131
- };
132
113
  }>, {
133
- intent: "advance" | "rehydrate";
134
- stateToken: string;
135
- ackToken?: string;
136
- context?: Record<string, unknown>;
137
114
  output?: {
138
- notesMarkdown?: string;
139
- artifacts?: unknown[];
140
- };
141
- }, {
115
+ notesMarkdown?: string | undefined;
116
+ artifacts?: unknown[] | undefined;
117
+ } | undefined;
118
+ context?: Record<string, unknown> | undefined;
142
119
  intent: "advance" | "rehydrate";
143
- stateToken: string;
144
- ackToken?: string;
145
- context?: Record<string, unknown>;
120
+ continueToken: string;
121
+ }, {
122
+ continueToken: string;
123
+ context?: Record<string, unknown> | undefined;
146
124
  output?: {
147
- notesMarkdown?: string;
148
- artifacts?: unknown[];
149
- };
150
- }>>;
125
+ notesMarkdown?: string | undefined;
126
+ artifacts?: unknown[] | undefined;
127
+ } | undefined;
128
+ intent?: "advance" | "rehydrate" | undefined;
129
+ }>;
151
130
  export type V2ContinueWorkflowInput = z.infer<typeof V2ContinueWorkflowInput>;
152
131
  export declare const V2ResumeSessionInput: z.ZodObject<{
153
132
  query: z.ZodOptional<z.ZodString>;
@@ -2,25 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2CheckpointWorkflowInput = exports.V2ResumeSessionInput = exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
4
4
  const zod_1 = require("zod");
5
- exports.V2ListWorkflowsInput = zod_1.z.object({});
5
+ const workspacePathField = zod_1.z.string()
6
+ .refine((p) => p.startsWith('/'), 'workspacePath must be an absolute path (starting with /)')
7
+ .optional()
8
+ .describe('Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). Used to resolve project-scoped workflow variants against the correct workspace. If omitted, WorkRail uses MCP roots when available, then falls back to the server process directory.');
9
+ exports.V2ListWorkflowsInput = zod_1.z.object({
10
+ workspacePath: workspacePathField,
11
+ });
6
12
  exports.V2InspectWorkflowInput = zod_1.z.object({
7
13
  workflowId: zod_1.z.string().min(1).regex(/^[A-Za-z0-9_-]+$/, 'Workflow ID must contain only letters, numbers, hyphens, and underscores').describe('The workflow ID to inspect'),
8
14
  mode: zod_1.z.enum(['metadata', 'preview']).default('preview').describe('Detail level: metadata (name and description only) or preview (full step-by-step breakdown, default)'),
15
+ workspacePath: workspacePathField,
9
16
  });
10
17
  exports.V2StartWorkflowInput = zod_1.z.object({
11
18
  workflowId: zod_1.z.string().min(1).regex(/^[A-Za-z0-9_-]+$/, 'Workflow ID must contain only letters, numbers, hyphens, and underscores').describe('The workflow ID to start'),
12
- workspacePath: zod_1.z.string()
13
- .refine((p) => p.startsWith('/'), 'workspacePath must be an absolute path (starting with /)')
14
- .optional()
15
- .describe('Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). Used to anchor this session to your workspace for future resume_session discovery. Pass this on every start_workflow call. If omitted, WorkRail uses the server process directory which may not match your workspace.'),
19
+ workspacePath: workspacePathField.describe('Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). Used to resolve the correct project-scoped workflow variant and to anchor this session to your workspace for future resume_session discovery. Pass this on every start_workflow call. If omitted, WorkRail uses MCP roots when available, then falls back to the server process directory.'),
16
20
  });
17
21
  exports.V2ContinueWorkflowInputShape = zod_1.z.object({
18
- intent: zod_1.z.enum(['advance', 'rehydrate']).optional().describe('What you want to do. Auto-inferred from ackToken if omitted: ' +
19
- 'ackToken present "advance", ackToken absent "rehydrate". ' +
20
- '"advance": I completed the current step requires ackToken. ' +
21
- '"rehydrate": Remind me what the current step is (state recovery after rewind/lost context) — do NOT include ackToken or output.'),
22
- stateToken: zod_1.z.string().min(1).describe('Your session handle from start_workflow or previous continue_workflow. Pass this in EVERY continue_workflow call to identify your session. Round-trip exactly as received — never decode, inspect, or modify it.'),
23
- ackToken: zod_1.z.string().min(1).optional().describe('Your step completion receipt. Required when intent is "advance". Must be omitted when intent is "rehydrate".'),
22
+ continueToken: zod_1.z.string().min(1).describe('The single token for your next continue_workflow call. Carries session identity AND advance authority. ' +
23
+ 'Round-trip exactly as received from start_workflow or previous continue_workflow — never decode, inspect, or modify it.'),
24
+ intent: zod_1.z.enum(['advance', 'rehydrate']).optional().describe('What you want to do. Auto-inferred if omitted: ' +
25
+ 'output present "advance", output absent "rehydrate". ' +
26
+ '"advance": I completed the current step. ' +
27
+ '"rehydrate": Remind me what the current step is (state recovery after rewind/lost context) do NOT include output.'),
24
28
  context: zod_1.z.record(zod_1.z.unknown()).optional().describe('External facts (only if CHANGED since last call). Omit this entirely if no facts changed. WorkRail auto-merges with previous context. Example: if context={branch:"main"} at start, do NOT re-pass it unless branch changed. Pass only NEW or OVERRIDDEN values.'),
25
29
  output: zod_1.z
26
30
  .object({
@@ -37,39 +41,25 @@ exports.V2ContinueWorkflowInputShape = zod_1.z.object({
37
41
  .describe('Durable output to attach to the current node. Only valid when intent is "advance".'),
38
42
  }).strict();
39
43
  exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape
40
- .transform((data) => {
41
- const intent = data.intent ?? (data.ackToken ? 'advance' : 'rehydrate');
42
- return { ...data, intent };
43
- })
44
- .pipe(zod_1.z.custom().superRefine((data, ctx) => {
45
- if (data.intent === 'advance' && !data.ackToken) {
46
- ctx.addIssue({
47
- code: zod_1.z.ZodIssueCode.custom,
48
- path: ['ackToken'],
49
- message: 'intent is "advance" but ackToken is missing. ' +
50
- 'To advance to the next step, include the ackToken from the previous start_workflow or continue_workflow response. ' +
51
- 'If you don\'t have an ackToken, set intent to "rehydrate" to recover the current step.',
52
- });
53
- }
54
- if (data.intent === 'rehydrate' && data.ackToken) {
55
- ctx.addIssue({
56
- code: zod_1.z.ZodIssueCode.custom,
57
- path: ['ackToken'],
58
- message: 'intent is "rehydrate" but ackToken was provided. ' +
59
- 'Rehydration recovers the current step without advancing — it does not accept ackToken. ' +
60
- 'To advance, set intent to "advance". To rehydrate, remove ackToken.',
61
- });
62
- }
44
+ .superRefine((data, ctx) => {
63
45
  if (data.intent === 'rehydrate' && data.output) {
64
46
  ctx.addIssue({
65
47
  code: zod_1.z.ZodIssueCode.custom,
66
48
  path: ['output'],
67
49
  message: 'intent is "rehydrate" but output was provided. ' +
68
- 'Rehydration is read-only state recovery — it does not accept output. ' +
69
- 'To submit output and advance, set intent to "advance" and include ackToken.',
50
+ 'Rehydration is read-only state recovery — it does not accept output.',
70
51
  });
71
52
  }
72
- }));
53
+ })
54
+ .transform((data) => {
55
+ const intent = data.intent ?? (data.output ? 'advance' : 'rehydrate');
56
+ return {
57
+ intent,
58
+ continueToken: data.continueToken,
59
+ ...(data.context ? { context: data.context } : {}),
60
+ ...(data.output ? { output: data.output } : {}),
61
+ };
62
+ });
73
63
  exports.V2ResumeSessionInput = zod_1.z.object({
74
64
  query: zod_1.z.string().max(256).optional().describe('Free text search to find a relevant session. Matches against recap notes and workflow IDs.'),
75
65
  gitBranch: zod_1.z.string().max(256).optional().describe('Git branch name to match against session observations. Overrides auto-detected branch.'),
@@ -5,8 +5,7 @@ function isV2ExecutionResponse(data) {
5
5
  if (typeof data !== 'object' || data === null)
6
6
  return false;
7
7
  const d = data;
8
- return (typeof d.stateToken === 'string' &&
9
- 'pending' in d &&
8
+ return ('pending' in d &&
10
9
  typeof d.nextIntent === 'string' &&
11
10
  typeof d.preferences === 'object' && d.preferences !== null);
12
11
  }
@@ -45,22 +44,19 @@ const PERSONA_SYSTEM = '---------\nSYSTEM\n---------';
45
44
  function formatTokenBlock(data) {
46
45
  const params = {};
47
46
  if (data.nextCall) {
48
- params.stateToken = data.nextCall.params.stateToken;
49
- if (data.nextCall.params.ackToken) {
50
- params.ackToken = data.nextCall.params.ackToken;
51
- }
47
+ params.continueToken = data.nextCall.params.continueToken;
52
48
  }
53
- else {
54
- params.stateToken = data.stateToken;
49
+ else if (data.continueToken) {
50
+ params.continueToken = data.continueToken;
55
51
  }
56
52
  const lines = [];
53
+ if (data.pending?.stepId) {
54
+ lines.push(`**Tokens for step \`${data.pending.stepId}\` — use these for your next \`continue_workflow\` call (not tokens from earlier steps):**`);
55
+ lines.push('');
56
+ }
57
57
  lines.push('```json');
58
58
  lines.push(JSON.stringify(params));
59
59
  lines.push('```');
60
- if (data.checkpointToken) {
61
- lines.push('');
62
- lines.push(`Checkpoint token (for \`checkpoint_workflow\`): \`${data.checkpointToken}\``);
63
- }
64
60
  return lines.join('\n');
65
61
  }
66
62
  function formatComplete(_data) {
@@ -151,6 +147,8 @@ function formatRehydrate(data) {
151
147
  }
152
148
  lines.push(PERSONA_SYSTEM);
153
149
  lines.push('');
150
+ lines.push(formatTokenBlock(data));
151
+ lines.push('');
154
152
  if (!data.pending) {
155
153
  lines.push('# State Recovered');
156
154
  lines.push('');
@@ -158,8 +156,6 @@ function formatRehydrate(data) {
158
156
  lines.push('');
159
157
  }
160
158
  lines.push('Continue working on this step. When done, call `continue_workflow` to advance.');
161
- lines.push('');
162
- lines.push(formatTokenBlock(data));
163
159
  return lines.join('\n');
164
160
  }
165
161
  function formatSuccess(data) {
@@ -175,12 +171,12 @@ function formatSuccess(data) {
175
171
  }
176
172
  lines.push(PERSONA_SYSTEM);
177
173
  lines.push('');
174
+ lines.push(formatTokenBlock(data));
175
+ lines.push('');
178
176
  lines.push('Execute this step, then call `continue_workflow` to advance.');
179
177
  lines.push('');
180
178
  lines.push('Include `output.notesMarkdown` documenting your work — what you did, key decisions, what you produced, and anything notable.');
181
179
  lines.push('');
182
- lines.push(formatTokenBlock(data));
183
- lines.push('');
184
180
  lines.push(formatPreferences(data.preferences));
185
181
  return lines.join('\n');
186
182
  }
@@ -6,4 +6,6 @@ export type RuntimeMode = {
6
6
  kind: 'cli';
7
7
  } | {
8
8
  kind: 'rpc';
9
+ } | {
10
+ kind: 'library';
9
11
  };
@@ -11,6 +11,7 @@ export interface StepMetadata {
11
11
  readonly stepId: string;
12
12
  readonly title: string;
13
13
  readonly prompt: string;
14
+ readonly agentRole?: string;
14
15
  readonly requireConfirmation: boolean;
15
16
  }
16
17
  export declare function renderPendingPrompt(args: {
@@ -210,6 +210,7 @@ function renderPendingPrompt(args) {
210
210
  }
211
211
  const baseTitle = step.title;
212
212
  const basePrompt = step.prompt;
213
+ const agentRole = step.agentRole;
213
214
  const requireConfirmation = Boolean(step.requireConfirmation);
214
215
  const functionReferences = step.functionReferences ?? [];
215
216
  const outputContract = 'outputContract' in step
@@ -261,7 +262,7 @@ function renderPendingPrompt(args) {
261
262
  'Omitting notes will block this step — use the `retryAckToken` to fix and retry.';
262
263
  const enhancedPrompt = loopBanner + basePrompt + requirementsSection + contractSection + notesSection;
263
264
  if (!args.rehydrateOnly) {
264
- return (0, neverthrow_1.ok)({ stepId: args.stepId, title: baseTitle, prompt: enhancedPrompt, requireConfirmation });
265
+ return (0, neverthrow_1.ok)({ stepId: args.stepId, title: baseTitle, prompt: enhancedPrompt, agentRole, requireConfirmation });
265
266
  }
266
267
  const projectionsRes = loadRecoveryProjections({ truth: args.truth, runId: args.runId });
267
268
  if (projectionsRes.isErr()) {
@@ -269,6 +270,7 @@ function renderPendingPrompt(args) {
269
270
  stepId: args.stepId,
270
271
  title: baseTitle,
271
272
  prompt: enhancedPrompt + '\n\n' + projectionsRes.error,
273
+ agentRole,
272
274
  requireConfirmation,
273
275
  });
274
276
  }
@@ -284,10 +286,10 @@ function renderPendingPrompt(args) {
284
286
  functionReferences,
285
287
  });
286
288
  if (sections.length === 0) {
287
- return (0, neverthrow_1.ok)({ stepId: args.stepId, title: baseTitle, prompt: enhancedPrompt, requireConfirmation });
289
+ return (0, neverthrow_1.ok)({ stepId: args.stepId, title: baseTitle, prompt: enhancedPrompt, agentRole, requireConfirmation });
288
290
  }
289
291
  const recoveryText = `## Recovery Context\n\n${sections.join('\n\n')}`;
290
292
  const combinedPrompt = `${enhancedPrompt}\n\n${recoveryText}`;
291
293
  const finalPrompt = applyPromptBudget(combinedPrompt);
292
- return (0, neverthrow_1.ok)({ stepId: args.stepId, title: baseTitle, prompt: finalPrompt, requireConfirmation });
294
+ return (0, neverthrow_1.ok)({ stepId: args.stepId, title: baseTitle, prompt: finalPrompt, agentRole, requireConfirmation });
293
295
  }