@exaudeus/workrail 3.15.0 → 3.16.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 (139) hide show
  1. package/dist/application/services/workflow-service.d.ts +2 -0
  2. package/dist/application/services/workflow-service.js +3 -0
  3. package/dist/console/assets/index-BE5PAgPO.js +28 -0
  4. package/dist/console/assets/index-BZNM03t1.css +1 -0
  5. package/dist/console/index.html +2 -2
  6. package/dist/env-flags.d.ts +1 -0
  7. package/dist/env-flags.js +4 -0
  8. package/dist/infrastructure/session/HttpServer.d.ts +3 -3
  9. package/dist/infrastructure/session/HttpServer.js +68 -74
  10. package/dist/infrastructure/storage/caching-workflow-storage.d.ts +2 -0
  11. package/dist/infrastructure/storage/caching-workflow-storage.js +15 -6
  12. package/dist/infrastructure/storage/file-workflow-storage.js +3 -4
  13. package/dist/infrastructure/storage/schema-validating-workflow-storage.js +9 -8
  14. package/dist/manifest.json +257 -193
  15. package/dist/mcp/assert-output.d.ts +37 -0
  16. package/dist/mcp/assert-output.js +52 -0
  17. package/dist/mcp/boundary-coercion.d.ts +1 -0
  18. package/dist/mcp/boundary-coercion.js +44 -0
  19. package/dist/mcp/dev-mode.d.ts +1 -0
  20. package/dist/mcp/dev-mode.js +4 -0
  21. package/dist/mcp/handler-factory.js +12 -9
  22. package/dist/mcp/handlers/session.js +8 -9
  23. package/dist/mcp/handlers/v2-advance-core/event-builders.d.ts +2 -0
  24. package/dist/mcp/handlers/v2-advance-core/event-builders.js +6 -6
  25. package/dist/mcp/handlers/v2-advance-core/index.d.ts +2 -0
  26. package/dist/mcp/handlers/v2-advance-core/index.js +4 -3
  27. package/dist/mcp/handlers/v2-advance-core/input-validation.d.ts +2 -0
  28. package/dist/mcp/handlers/v2-advance-core/input-validation.js +32 -9
  29. package/dist/mcp/handlers/v2-advance-core/outcome-blocked.d.ts +2 -0
  30. package/dist/mcp/handlers/v2-advance-core/outcome-blocked.js +1 -1
  31. package/dist/mcp/handlers/v2-advance-core/outcome-success.d.ts +2 -0
  32. package/dist/mcp/handlers/v2-advance-core/outcome-success.js +1 -1
  33. package/dist/mcp/handlers/v2-checkpoint.d.ts +1 -1
  34. package/dist/mcp/handlers/v2-checkpoint.js +5 -6
  35. package/dist/mcp/handlers/v2-execution/advance.d.ts +4 -2
  36. package/dist/mcp/handlers/v2-execution/advance.js +5 -7
  37. package/dist/mcp/handlers/v2-execution/continue-advance.js +56 -26
  38. package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +1 -1
  39. package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +9 -9
  40. package/dist/mcp/handlers/v2-execution/replay.d.ts +6 -4
  41. package/dist/mcp/handlers/v2-execution/replay.js +47 -30
  42. package/dist/mcp/handlers/v2-execution/start.d.ts +2 -3
  43. package/dist/mcp/handlers/v2-execution/start.js +11 -11
  44. package/dist/mcp/handlers/v2-execution/workflow-object-cache.d.ts +5 -0
  45. package/dist/mcp/handlers/v2-execution/workflow-object-cache.js +19 -0
  46. package/dist/mcp/handlers/v2-execution-helpers.d.ts +1 -0
  47. package/dist/mcp/handlers/v2-execution-helpers.js +23 -7
  48. package/dist/mcp/handlers/v2-resume.d.ts +1 -1
  49. package/dist/mcp/handlers/v2-resume.js +3 -4
  50. package/dist/mcp/handlers/v2-state-conversion.js +5 -1
  51. package/dist/mcp/handlers/v2-workflow.d.ts +80 -0
  52. package/dist/mcp/handlers/v2-workflow.js +36 -21
  53. package/dist/mcp/handlers/workflow.d.ts +2 -5
  54. package/dist/mcp/handlers/workflow.js +15 -12
  55. package/dist/mcp/output-schemas.d.ts +20 -27
  56. package/dist/mcp/output-schemas.js +5 -7
  57. package/dist/mcp/server.js +22 -4
  58. package/dist/mcp/tool-call-timing.d.ts +24 -0
  59. package/dist/mcp/tool-call-timing.js +85 -0
  60. package/dist/mcp/transports/http-entry.js +3 -2
  61. package/dist/mcp/transports/http-listener.d.ts +1 -0
  62. package/dist/mcp/transports/http-listener.js +25 -0
  63. package/dist/mcp/transports/shutdown-hooks.d.ts +4 -1
  64. package/dist/mcp/transports/shutdown-hooks.js +3 -2
  65. package/dist/mcp/transports/stdio-entry.js +6 -28
  66. package/dist/mcp/v2-response-formatter.js +2 -4
  67. package/dist/mcp/validation/schema-introspection.d.ts +1 -0
  68. package/dist/mcp/validation/schema-introspection.js +15 -5
  69. package/dist/mcp/validation/suggestion-generator.js +2 -2
  70. package/dist/runtime/adapters/node-process-signals.d.ts +1 -0
  71. package/dist/runtime/adapters/node-process-signals.js +5 -0
  72. package/dist/runtime/adapters/noop-process-signals.d.ts +1 -0
  73. package/dist/runtime/adapters/noop-process-signals.js +2 -0
  74. package/dist/runtime/ports/process-signals.d.ts +1 -0
  75. package/dist/types/workflow-definition.d.ts +2 -0
  76. package/dist/types/workflow.d.ts +3 -0
  77. package/dist/types/workflow.js +35 -26
  78. package/dist/v2/durable-core/domain/context-template-resolver.js +2 -2
  79. package/dist/v2/durable-core/domain/function-definition-expander.js +2 -17
  80. package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
  81. package/dist/v2/durable-core/domain/prompt-renderer.js +23 -18
  82. package/dist/v2/durable-core/domain/recap-recovery.js +23 -16
  83. package/dist/v2/durable-core/domain/retrieval-contract.js +13 -7
  84. package/dist/v2/durable-core/session-index.d.ts +22 -0
  85. package/dist/v2/durable-core/session-index.js +58 -0
  86. package/dist/v2/durable-core/sorted-event-log.d.ts +6 -0
  87. package/dist/v2/durable-core/sorted-event-log.js +15 -0
  88. package/dist/v2/infra/local/fs/index.js +8 -8
  89. package/dist/v2/infra/local/session-store/index.d.ts +1 -1
  90. package/dist/v2/infra/local/session-store/index.js +71 -61
  91. package/dist/v2/infra/local/session-summary-provider/index.js +9 -4
  92. package/dist/v2/infra/local/snapshot-store/index.js +2 -1
  93. package/dist/v2/ports/session-event-log-store.port.d.ts +1 -1
  94. package/dist/v2/projections/assessment-consequences.d.ts +2 -1
  95. package/dist/v2/projections/assessment-consequences.js +0 -5
  96. package/dist/v2/projections/assessments.d.ts +2 -1
  97. package/dist/v2/projections/assessments.js +2 -4
  98. package/dist/v2/projections/gaps.d.ts +2 -1
  99. package/dist/v2/projections/gaps.js +0 -5
  100. package/dist/v2/projections/preferences.d.ts +2 -1
  101. package/dist/v2/projections/preferences.js +0 -5
  102. package/dist/v2/projections/run-context.d.ts +2 -2
  103. package/dist/v2/projections/run-context.js +0 -5
  104. package/dist/v2/projections/run-dag.js +7 -1
  105. package/dist/v2/projections/run-execution-trace.d.ts +8 -0
  106. package/dist/v2/projections/run-execution-trace.js +124 -0
  107. package/dist/v2/projections/run-status-signals.d.ts +2 -2
  108. package/dist/v2/usecases/console-routes.d.ts +3 -1
  109. package/dist/v2/usecases/console-routes.js +123 -25
  110. package/dist/v2/usecases/console-service.d.ts +1 -0
  111. package/dist/v2/usecases/console-service.js +83 -25
  112. package/dist/v2/usecases/console-types.d.ts +53 -0
  113. package/dist/v2/usecases/worktree-service.js +32 -1
  114. package/package.json +6 -5
  115. package/spec/workflow.schema.json +18 -0
  116. package/workflows/adaptive-ticket-creation.json +23 -16
  117. package/workflows/architecture-scalability-audit.json +29 -22
  118. package/workflows/bug-investigation.agentic.v2.json +7 -0
  119. package/workflows/coding-task-workflow-agentic.json +7 -0
  120. package/workflows/coding-task-workflow-agentic.lean.v2.json +16 -8
  121. package/workflows/coding-task-workflow-agentic.v2.json +7 -0
  122. package/workflows/cross-platform-code-conversion.v2.json +7 -0
  123. package/workflows/document-creation-workflow.json +15 -8
  124. package/workflows/documentation-update-workflow.json +15 -8
  125. package/workflows/intelligent-test-case-generation.json +7 -0
  126. package/workflows/learner-centered-course-workflow.json +9 -2
  127. package/workflows/mr-review-workflow.agentic.v2.json +7 -0
  128. package/workflows/personal-learning-materials-creation-branched.json +15 -8
  129. package/workflows/presentation-creation.json +12 -5
  130. package/workflows/production-readiness-audit.json +7 -0
  131. package/workflows/relocation-workflow-us.json +39 -32
  132. package/workflows/scoped-documentation-workflow.json +33 -26
  133. package/workflows/ui-ux-design-workflow.json +7 -0
  134. package/workflows/workflow-diagnose-environment.json +6 -0
  135. package/workflows/workflow-for-workflows.json +7 -0
  136. package/workflows/workflow-for-workflows.v2.json +23 -11
  137. package/workflows/wr.discovery.json +8 -1
  138. package/dist/console/assets/index-BZYIjrzJ.js +0 -28
  139. package/dist/console/assets/index-OLCKbDdm.css +0 -1
@@ -1,6 +1,10 @@
1
1
  import type { ToolContext, ToolResult } from '../types.js';
2
2
  import type { V2InspectWorkflowInput, V2ListWorkflowsInput } from '../v2/tools.js';
3
3
  import type { StalenessSummary } from '../output-schemas.js';
4
+ import type { RememberedRootRecordV2 } from '../../v2/ports/remembered-roots-store.port.js';
5
+ import type { CryptoPortV2 } from '../../v2/durable-core/canonical/hashing.js';
6
+ import type { PinnedWorkflowStorePortV2 } from '../../v2/ports/pinned-workflow-store.port.js';
7
+ import type { Workflow } from '../../types/workflow.js';
4
8
  export declare function shouldShowStaleness(category: string | undefined, devMode?: boolean): boolean;
5
9
  interface WorkflowTagsFile {
6
10
  readonly tags: ReadonlyArray<{
@@ -22,6 +26,82 @@ export declare function buildTagSummary(tagsFile: WorkflowTagsFile, compiledWork
22
26
  examples: string[];
23
27
  }>;
24
28
  export declare function computeWorkflowStaleness(stamp: number | undefined, currentVersion: number | null): StalenessSummary | undefined;
29
+ interface WorkflowLookupReader {
30
+ readonly getWorkflowById: (id: string) => Promise<Workflow | null>;
31
+ readonly listWorkflowSummaries: () => Promise<readonly {
32
+ readonly id: string;
33
+ readonly name: string;
34
+ readonly description: string;
35
+ readonly version: string;
36
+ }[]>;
37
+ readonly loadAllWorkflows: () => Promise<readonly Workflow[]>;
38
+ }
25
39
  export declare function handleV2ListWorkflows(input: V2ListWorkflowsInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
26
40
  export declare function handleV2InspectWorkflow(input: V2InspectWorkflowInput, ctx: ToolContext): Promise<ToolResult<unknown>>;
41
+ export declare function buildV2WorkflowListItem(options: {
42
+ readonly workflow: Workflow | null;
43
+ readonly summary: {
44
+ readonly id: string;
45
+ readonly name: string;
46
+ readonly description: string;
47
+ readonly version: string;
48
+ };
49
+ readonly workflowReader: WorkflowLookupReader;
50
+ readonly rememberedRootRecords: readonly RememberedRootRecordV2[];
51
+ readonly crypto: CryptoPortV2;
52
+ readonly pinnedStore: PinnedWorkflowStorePortV2;
53
+ }): Promise<{
54
+ workflowId: string;
55
+ name: string;
56
+ description: string;
57
+ version: string;
58
+ workflowHash: null;
59
+ kind: "workflow";
60
+ } | {
61
+ examples: string[];
62
+ workflowId: string;
63
+ name: string;
64
+ description: string;
65
+ version: string;
66
+ workflowHash: null;
67
+ kind: "workflow";
68
+ visibility: import("./shared/workflow-source-visibility.js").WorkflowVisibility;
69
+ } | {
70
+ examples?: undefined;
71
+ workflowId: string;
72
+ name: string;
73
+ description: string;
74
+ version: string;
75
+ workflowHash: null;
76
+ kind: "workflow";
77
+ visibility: import("./shared/workflow-source-visibility.js").WorkflowVisibility;
78
+ } | {
79
+ examples: string[];
80
+ staleness?: {
81
+ level: "none" | "possible" | "likely";
82
+ reason: string;
83
+ specVersionAtLastReview?: number | undefined;
84
+ } | undefined;
85
+ workflowId: string;
86
+ name: string;
87
+ description: string;
88
+ version: string;
89
+ workflowHash: never;
90
+ kind: "workflow";
91
+ visibility: import("./shared/workflow-source-visibility.js").WorkflowVisibility;
92
+ } | {
93
+ examples?: undefined;
94
+ staleness?: {
95
+ level: "none" | "possible" | "likely";
96
+ reason: string;
97
+ specVersionAtLastReview?: number | undefined;
98
+ } | undefined;
99
+ workflowId: string;
100
+ name: string;
101
+ description: string;
102
+ version: string;
103
+ workflowHash: never;
104
+ kind: "workflow";
105
+ visibility: import("./shared/workflow-source-visibility.js").WorkflowVisibility;
106
+ }>;
27
107
  export {};
@@ -8,13 +8,13 @@ exports.buildTagSummary = buildTagSummary;
8
8
  exports.computeWorkflowStaleness = computeWorkflowStaleness;
9
9
  exports.handleV2ListWorkflows = handleV2ListWorkflows;
10
10
  exports.handleV2InspectWorkflow = handleV2InspectWorkflow;
11
+ exports.buildV2WorkflowListItem = buildV2WorkflowListItem;
11
12
  const path_1 = __importDefault(require("path"));
12
13
  const fs_1 = __importDefault(require("fs"));
13
14
  const neverthrow_1 = require("neverthrow");
14
15
  const types_js_1 = require("../types.js");
15
16
  const error_mapper_js_1 = require("../error-mapper.js");
16
17
  const v2_execution_helpers_js_1 = require("./v2-execution-helpers.js");
17
- const output_schemas_js_1 = require("../output-schemas.js");
18
18
  const v1_to_v2_shim_js_1 = require("../../v2/read-only/v1-to-v2-shim.js");
19
19
  const hashing_js_1 = require("../../v2/durable-core/canonical/hashing.js");
20
20
  const TIMEOUT_MS = 30000;
@@ -135,14 +135,24 @@ async function handleV2ListWorkflows(input, ctx) {
135
135
  const warnings = managedStoreError
136
136
  ? [`Managed workflow source store was temporarily unavailable (${managedStoreError}). Managed sources were not loaded.`]
137
137
  : undefined;
138
- return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(workflowReader.listWorkflowSummaries(), TIMEOUT_MS, 'list_workflows'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err))
139
- .andThen((summaries) => neverthrow_1.ResultAsync.combine(summaries.map((s) => neverthrow_1.ResultAsync.fromPromise(buildV2WorkflowListItem({
140
- summary: s,
141
- workflowReader,
142
- rememberedRootRecords,
143
- crypto,
144
- pinnedStore,
145
- }), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err)))))
138
+ return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(workflowReader.loadAllWorkflows(), TIMEOUT_MS, 'list_workflows'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err))
139
+ .andThen((allWorkflows) => {
140
+ const workflowMap = new Map(allWorkflows.map((w) => [w.definition.id, w]));
141
+ const summaries = allWorkflows.map((w) => ({
142
+ id: w.definition.id,
143
+ name: w.definition.name,
144
+ description: w.definition.description,
145
+ version: w.definition.version,
146
+ }));
147
+ return neverthrow_1.ResultAsync.combine(summaries.map((s) => neverthrow_1.ResultAsync.fromPromise(buildV2WorkflowListItem({
148
+ workflow: workflowMap.get(s.id) ?? null,
149
+ summary: s,
150
+ workflowReader,
151
+ rememberedRootRecords,
152
+ crypto,
153
+ pinnedStore,
154
+ }), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err))));
155
+ })
146
156
  .andThen((compiled) => {
147
157
  const sortedIds = compiled.map((w) => w.workflowId).sort((a, b) => a.localeCompare(b));
148
158
  const sortedCompiled = [...compiled].sort((a, b) => a.workflowId.localeCompare(b.workflowId));
@@ -173,35 +183,35 @@ async function handleV2ListWorkflows(input, ctx) {
173
183
  : undefined;
174
184
  if (!input.includeSources) {
175
185
  const includeStaleRoots = !tagSummaryEntry && stalePaths.length > 0;
176
- const payload = output_schemas_js_1.V2WorkflowListOutputSchema.parse({
186
+ const payload = {
177
187
  workflows: tagFilteredCompiled,
178
188
  ...(tagSummaryEntry ? { tagSummary: tagSummaryEntry } : {}),
179
189
  ...(nextStepHint ? { _nextStep: nextStepHint } : {}),
180
190
  ...(includeStaleRoots ? { staleRoots: [...stalePaths] } : {}),
181
191
  ...(warnings ? { warnings } : {}),
182
- });
192
+ };
183
193
  return (0, neverthrow_1.okAsync)((0, types_js_1.success)(payload));
184
194
  }
185
195
  if (!(0, workflow_source_visibility_js_1.isCompositeWorkflowReader)(workflowReader)) {
186
- const payload = output_schemas_js_1.V2WorkflowListOutputSchema.parse({
196
+ const payload = {
187
197
  workflows: tagFilteredCompiled,
188
198
  ...(tagSummaryEntry ? { tagSummary: tagSummaryEntry } : {}),
189
199
  ...(nextStepHint ? { _nextStep: nextStepHint } : {}),
190
200
  ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
191
201
  ...(warnings ? { warnings } : {}),
192
202
  sources: [],
193
- });
203
+ };
194
204
  return (0, neverthrow_1.okAsync)((0, types_js_1.success)(payload));
195
205
  }
196
206
  return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(buildSourceCatalog(workflowReader, rememberedRootRecords, managedSourceRecords, staleManagedRecords), TIMEOUT_MS, 'list_workflow_sources'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err)).map((sources) => {
197
- const payload = output_schemas_js_1.V2WorkflowListOutputSchema.parse({
207
+ const payload = {
198
208
  workflows: tagFilteredCompiled,
199
209
  ...(tagSummaryEntry ? { tagSummary: tagSummaryEntry } : {}),
200
210
  ...(nextStepHint ? { _nextStep: nextStepHint } : {}),
201
211
  ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
202
212
  ...(warnings ? { warnings } : {}),
203
- sources,
204
- });
213
+ sources: [...sources],
214
+ };
205
215
  return (0, types_js_1.success)(payload);
206
216
  });
207
217
  })
@@ -264,7 +274,7 @@ async function handleV2InspectWorkflow(input, ctx) {
264
274
  ? { schemaVersion: compiled.schemaVersion, sourceKind: compiled.sourceKind, workflowId: compiled.workflowId }
265
275
  : compiled;
266
276
  const references = workflow.definition.references;
267
- const payload = output_schemas_js_1.V2WorkflowInspectOutputSchema.parse({
277
+ const payload = {
268
278
  workflowId: input.workflowId,
269
279
  workflowHash,
270
280
  mode: input.mode,
@@ -272,14 +282,14 @@ async function handleV2InspectWorkflow(input, ctx) {
272
282
  ...(visibility ? { visibility } : {}),
273
283
  ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
274
284
  ...(inspectWarnings ? { warnings: inspectWarnings } : {}),
275
- ...(references != null && references.length > 0 ? { references } : {}),
285
+ ...(references != null && references.length > 0 ? { references: [...references] } : {}),
276
286
  ...(() => {
277
287
  const staleness = shouldShowStaleness(visibility?.category)
278
288
  ? computeWorkflowStaleness(workflow.definition.validatedAgainstSpecVersion, CURRENT_SPEC_VERSION)
279
289
  : undefined;
280
290
  return staleness !== undefined ? { staleness } : {};
281
291
  })(),
282
- });
292
+ };
283
293
  return (0, neverthrow_1.okAsync)((0, types_js_1.success)(payload));
284
294
  }));
285
295
  })
@@ -294,8 +304,7 @@ async function buildWorkflowVisibility(workflow, workflowReader, rememberedRootR
294
304
  return (0, workflow_source_visibility_js_1.toWorkflowVisibility)(workflow, rememberedRootRecords, { migration });
295
305
  }
296
306
  async function buildV2WorkflowListItem(options) {
297
- const { summary, workflowReader, rememberedRootRecords, crypto, pinnedStore } = options;
298
- const workflow = await workflowReader.getWorkflowById(summary.id);
307
+ const { workflow, summary, workflowReader, rememberedRootRecords, crypto, pinnedStore } = options;
299
308
  if (!workflow) {
300
309
  return {
301
310
  workflowId: summary.id,
@@ -307,6 +316,9 @@ async function buildV2WorkflowListItem(options) {
307
316
  };
308
317
  }
309
318
  const visibility = await buildWorkflowVisibility(workflow, workflowReader, rememberedRootRecords);
319
+ const examples = workflow.definition.examples?.length
320
+ ? { examples: [...workflow.definition.examples] }
321
+ : {};
310
322
  const snapshot = (0, v1_to_v2_shim_js_1.compileV1WorkflowToV2PreviewSnapshot)(workflow);
311
323
  const hashRes = (0, hashing_js_1.workflowHashForCompiledSnapshot)(snapshot, crypto);
312
324
  if (hashRes.isErr()) {
@@ -318,6 +330,7 @@ async function buildV2WorkflowListItem(options) {
318
330
  workflowHash: null,
319
331
  kind: 'workflow',
320
332
  visibility,
333
+ ...examples,
321
334
  };
322
335
  }
323
336
  const hash = hashRes.value;
@@ -333,6 +346,7 @@ async function buildV2WorkflowListItem(options) {
333
346
  workflowHash: hash,
334
347
  kind: 'workflow',
335
348
  visibility,
349
+ ...examples,
336
350
  };
337
351
  }
338
352
  }
@@ -348,6 +362,7 @@ async function buildV2WorkflowListItem(options) {
348
362
  kind: 'workflow',
349
363
  visibility,
350
364
  ...(staleness !== undefined ? { staleness } : {}),
365
+ ...examples,
351
366
  };
352
367
  }
353
368
  async function buildSourceCatalog(workflowReader, rememberedRootRecords, managedSourceRecords, staleManagedRecords) {
@@ -19,11 +19,8 @@ export interface WorkflowNextOutput {
19
19
  }
20
20
  export interface WorkflowValidateJsonOutput {
21
21
  valid: boolean;
22
- errors?: Array<{
23
- message: string;
24
- path?: string;
25
- }>;
26
- suggestions?: string[];
22
+ issues: string[];
23
+ suggestions: string[];
27
24
  }
28
25
  export interface WorkflowGetSchemaOutput {
29
26
  schema: unknown;
@@ -32,21 +32,29 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  exports.handleWorkflowList = handleWorkflowList;
37
40
  exports.handleWorkflowGet = handleWorkflowGet;
38
41
  exports.handleWorkflowNext = handleWorkflowNext;
39
42
  exports.handleWorkflowValidateJson = handleWorkflowValidateJson;
40
43
  exports.handleWorkflowGetSchema = handleWorkflowGetSchema;
44
+ const fs_1 = __importDefault(require("fs"));
45
+ const path_1 = __importDefault(require("path"));
41
46
  const types_js_1 = require("../types.js");
42
- const output_schemas_js_1 = require("../output-schemas.js");
43
47
  const error_mapper_js_1 = require("../error-mapper.js");
44
48
  const TIMEOUT_MS = 30000;
49
+ const WORKFLOW_SCHEMA = (() => {
50
+ const schemaPath = path_1.default.resolve(__dirname, '../../../spec/workflow.schema.json');
51
+ return JSON.parse(fs_1.default.readFileSync(schemaPath, 'utf-8'));
52
+ })();
45
53
  const with_timeout_js_1 = require("./shared/with-timeout.js");
46
54
  async function handleWorkflowList(_input, ctx) {
47
55
  try {
48
56
  const workflows = await (0, with_timeout_js_1.withTimeout)(ctx.workflowService.listWorkflowSummaries(), TIMEOUT_MS, 'workflow_list');
49
- const payload = output_schemas_js_1.WorkflowListOutputSchema.parse({ workflows });
57
+ const payload = { workflows };
50
58
  return (0, types_js_1.success)(payload);
51
59
  }
52
60
  catch (err) {
@@ -63,7 +71,7 @@ async function handleWorkflowGet(input, ctx) {
63
71
  const mapped = (0, error_mapper_js_1.mapDomainErrorToToolError)(result.error);
64
72
  return mapped;
65
73
  }
66
- const payload = output_schemas_js_1.WorkflowGetOutputSchema.parse({ workflow: result.value });
74
+ const payload = { workflow: result.value };
67
75
  return (0, types_js_1.success)(payload);
68
76
  }
69
77
  catch (err) {
@@ -93,7 +101,7 @@ async function handleWorkflowNext(input, ctx) {
93
101
  const mapped = (0, error_mapper_js_1.mapDomainErrorToToolError)(result.error);
94
102
  return mapped;
95
103
  }
96
- const payload = output_schemas_js_1.WorkflowNextOutputSchema.parse(result.value);
104
+ const payload = result.value;
97
105
  return (0, types_js_1.success)(payload);
98
106
  }
99
107
  catch (err) {
@@ -118,7 +126,7 @@ async function handleWorkflowValidateJson(input, ctx) {
118
126
  const { createValidateWorkflowJson } = await Promise.resolve().then(() => __importStar(require('../../application/use-cases/validate-workflow-json.js')));
119
127
  const validateWorkflowJsonUseCase = createValidateWorkflowJson();
120
128
  const result = await validateWorkflowJsonUseCase(input.workflowJson);
121
- const payload = output_schemas_js_1.WorkflowValidateJsonOutputSchema.parse(result);
129
+ const payload = result;
122
130
  return (0, types_js_1.success)(payload);
123
131
  }
124
132
  catch (err) {
@@ -129,11 +137,7 @@ async function handleWorkflowValidateJson(input, ctx) {
129
137
  async function handleWorkflowGetSchema(_input, ctx) {
130
138
  void ctx;
131
139
  try {
132
- const fs = await Promise.resolve().then(() => __importStar(require('fs')));
133
- const path = await Promise.resolve().then(() => __importStar(require('path')));
134
- const schemaPath = path.resolve(__dirname, '../../../spec/workflow.schema.json');
135
- const schemaContent = fs.readFileSync(schemaPath, 'utf-8');
136
- const schema = JSON.parse(schemaContent);
140
+ const schema = WORKFLOW_SCHEMA;
137
141
  const result = {
138
142
  schema,
139
143
  metadata: {
@@ -160,8 +164,7 @@ async function handleWorkflowGetSchema(_input, ctx) {
160
164
  },
161
165
  },
162
166
  };
163
- const payload = output_schemas_js_1.WorkflowGetSchemaOutputSchema.parse(result);
164
- return (0, types_js_1.success)(payload);
167
+ return (0, types_js_1.success)(result);
165
168
  }
166
169
  catch (err) {
167
170
  const message = err instanceof Error ? err.message : String(err);
@@ -73,31 +73,16 @@ export declare const WorkflowNextOutputSchema: z.ZodObject<{
73
73
  }>;
74
74
  export declare const WorkflowValidateJsonOutputSchema: z.ZodObject<{
75
75
  valid: z.ZodBoolean;
76
- errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
77
- message: z.ZodString;
78
- path: z.ZodOptional<z.ZodString>;
79
- }, "strip", z.ZodTypeAny, {
80
- message: string;
81
- path?: string | undefined;
82
- }, {
83
- message: string;
84
- path?: string | undefined;
85
- }>, "many">>;
86
- suggestions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
76
+ issues: z.ZodArray<z.ZodString, "many">;
77
+ suggestions: z.ZodArray<z.ZodString, "many">;
87
78
  }, "strip", z.ZodTypeAny, {
79
+ issues: string[];
88
80
  valid: boolean;
89
- suggestions?: string[] | undefined;
90
- errors?: {
91
- message: string;
92
- path?: string | undefined;
93
- }[] | undefined;
81
+ suggestions: string[];
94
82
  }, {
83
+ issues: string[];
95
84
  valid: boolean;
96
- suggestions?: string[] | undefined;
97
- errors?: {
98
- message: string;
99
- path?: string | undefined;
100
- }[] | undefined;
85
+ suggestions: string[];
101
86
  }>;
102
87
  export declare const WorkflowGetSchemaOutputSchema: z.ZodObject<{
103
88
  schema: z.ZodType<JsonValue, z.ZodTypeDef, JsonValue>;
@@ -262,6 +247,7 @@ export declare const V2WorkflowListItemSchema: z.ZodObject<{
262
247
  reason: string;
263
248
  specVersionAtLastReview?: number | undefined;
264
249
  }>>;
250
+ examples: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
265
251
  }, "strip", z.ZodTypeAny, {
266
252
  kind: "workflow";
267
253
  name: string;
@@ -269,6 +255,7 @@ export declare const V2WorkflowListItemSchema: z.ZodObject<{
269
255
  version: string;
270
256
  workflowId: string;
271
257
  workflowHash: string | null;
258
+ examples?: string[] | undefined;
272
259
  visibility?: {
273
260
  source: {
274
261
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -299,6 +286,7 @@ export declare const V2WorkflowListItemSchema: z.ZodObject<{
299
286
  version: string;
300
287
  workflowId: string;
301
288
  workflowHash: string | null;
289
+ examples?: string[] | undefined;
302
290
  visibility?: {
303
291
  source: {
304
292
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -439,14 +427,14 @@ export declare const TagSummaryItemSchema: z.ZodObject<{
439
427
  }, "strip", z.ZodTypeAny, {
440
428
  id: string;
441
429
  when: string[];
442
- displayName: string;
443
430
  examples: string[];
431
+ displayName: string;
444
432
  count: number;
445
433
  }, {
446
434
  id: string;
447
435
  when: string[];
448
- displayName: string;
449
436
  examples: string[];
437
+ displayName: string;
450
438
  count: number;
451
439
  }>;
452
440
  export declare const V2WorkflowListOutputSchema: z.ZodObject<{
@@ -546,6 +534,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
546
534
  reason: string;
547
535
  specVersionAtLastReview?: number | undefined;
548
536
  }>>;
537
+ examples: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
549
538
  }, "strip", z.ZodTypeAny, {
550
539
  kind: "workflow";
551
540
  name: string;
@@ -553,6 +542,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
553
542
  version: string;
554
543
  workflowId: string;
555
544
  workflowHash: string | null;
545
+ examples?: string[] | undefined;
556
546
  visibility?: {
557
547
  source: {
558
548
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -583,6 +573,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
583
573
  version: string;
584
574
  workflowId: string;
585
575
  workflowHash: string | null;
576
+ examples?: string[] | undefined;
586
577
  visibility?: {
587
578
  source: {
588
579
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -616,14 +607,14 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
616
607
  }, "strip", z.ZodTypeAny, {
617
608
  id: string;
618
609
  when: string[];
619
- displayName: string;
620
610
  examples: string[];
611
+ displayName: string;
621
612
  count: number;
622
613
  }, {
623
614
  id: string;
624
615
  when: string[];
625
- displayName: string;
626
616
  examples: string[];
617
+ displayName: string;
627
618
  count: number;
628
619
  }>, "many">>;
629
620
  _nextStep: z.ZodOptional<z.ZodString>;
@@ -744,6 +735,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
744
735
  version: string;
745
736
  workflowId: string;
746
737
  workflowHash: string | null;
738
+ examples?: string[] | undefined;
747
739
  visibility?: {
748
740
  source: {
749
741
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -799,8 +791,8 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
799
791
  tagSummary?: {
800
792
  id: string;
801
793
  when: string[];
802
- displayName: string;
803
794
  examples: string[];
795
+ displayName: string;
804
796
  count: number;
805
797
  }[] | undefined;
806
798
  _nextStep?: string | undefined;
@@ -813,6 +805,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
813
805
  version: string;
814
806
  workflowId: string;
815
807
  workflowHash: string | null;
808
+ examples?: string[] | undefined;
816
809
  visibility?: {
817
810
  source: {
818
811
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -868,8 +861,8 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
868
861
  tagSummary?: {
869
862
  id: string;
870
863
  when: string[];
871
- displayName: string;
872
864
  examples: string[];
865
+ displayName: string;
873
866
  count: number;
874
867
  }[] | undefined;
875
868
  _nextStep?: string | undefined;
@@ -27,13 +27,8 @@ exports.WorkflowNextOutputSchema = zod_1.z.object({
27
27
  });
28
28
  exports.WorkflowValidateJsonOutputSchema = zod_1.z.object({
29
29
  valid: zod_1.z.boolean(),
30
- errors: zod_1.z
31
- .array(zod_1.z.object({
32
- message: zod_1.z.string(),
33
- path: zod_1.z.string().optional(),
34
- }))
35
- .optional(),
36
- suggestions: zod_1.z.array(zod_1.z.string()).optional(),
30
+ issues: zod_1.z.array(zod_1.z.string()),
31
+ suggestions: zod_1.z.array(zod_1.z.string()),
37
32
  });
38
33
  exports.WorkflowGetSchemaOutputSchema = zod_1.z.object({
39
34
  schema: exports.JsonValueSchema,
@@ -79,6 +74,9 @@ exports.V2WorkflowListItemSchema = zod_1.z.object({
79
74
  }).optional(),
80
75
  }).optional(),
81
76
  staleness: exports.StalenessSummarySchema.optional(),
77
+ examples: zod_1.z.array(zod_1.z.string().min(10).max(120)).min(1).max(6).optional().describe('Short illustrative goal strings showing what this workflow is used for. ' +
78
+ 'Present when the workflow author has provided examples. ' +
79
+ 'Use these to help users understand what goals to provide when starting this workflow.'),
82
80
  });
83
81
  exports.V2WorkflowSourceCatalogEntrySchema = zod_1.z.object({
84
82
  sourceKey: zod_1.z.string().min(1).describe('Stable identifier for this source. Format: "{kind}:{absolutePath}" for filesystem sources (e.g. "project:/path/to/workflows", "custom:/path/to/.workrail/workflows"), or "built_in" for bundled sources.'),
@@ -47,6 +47,8 @@ const workspace_roots_manager_js_1 = require("./workspace-roots-manager.js");
47
47
  const index_js_2 = require("../v2/infra/local/directory-listing/index.js");
48
48
  const index_js_3 = require("../v2/infra/local/session-summary-provider/index.js");
49
49
  const tool_factory_js_1 = require("./tool-factory.js");
50
+ const dev_mode_js_1 = require("./dev-mode.js");
51
+ const tool_call_timing_js_1 = require("./tool-call-timing.js");
50
52
  const handler_factory_js_1 = require("./handler-factory.js");
51
53
  const workflow_tool_edition_selector_js_1 = require("./workflow-tool-edition-selector.js");
52
54
  const tools_js_1 = require("./tools.js");
@@ -159,8 +161,9 @@ function toMcpTool(tool) {
159
161
  };
160
162
  }
161
163
  async function composeServer() {
162
- await (0, container_js_1.bootstrap)({ runtimeMode: { kind: 'production' } });
164
+ await (0, container_js_1.bootstrap)();
163
165
  const ctx = await createToolContext();
166
+ const timingRingBuffer = new tool_call_timing_js_1.ToolCallTimingRingBuffer(tool_call_timing_js_1.DEFAULT_RING_BUFFER_CAPACITY);
164
167
  if (ctx.v2 && ctx.httpServer && ctx.v2.dataDir && ctx.v2.directoryListing) {
165
168
  const { ConsoleService } = await Promise.resolve().then(() => __importStar(require('../v2/usecases/console-service.js')));
166
169
  const { mountConsoleRoutes } = await Promise.resolve().then(() => __importStar(require('../v2/usecases/console-routes.js')));
@@ -171,7 +174,7 @@ async function composeServer() {
171
174
  snapshotStore: ctx.v2.snapshotStore,
172
175
  pinnedWorkflowStore: ctx.v2.pinnedStore,
173
176
  });
174
- ctx.httpServer.mountRoutes((app) => mountConsoleRoutes(app, consoleService));
177
+ ctx.httpServer.mountRoutes((app) => mountConsoleRoutes(app, consoleService, ctx.workflowService, timingRingBuffer));
175
178
  console.error('[Console] v2 Console API routes mounted at /api/v2/');
176
179
  }
177
180
  ctx.httpServer?.finalize();
@@ -214,19 +217,34 @@ async function composeServer() {
214
217
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
215
218
  tools,
216
219
  }));
220
+ const timingSink = dev_mode_js_1.DEV_MODE
221
+ ? (0, tool_call_timing_js_1.composeSinks)((0, tool_call_timing_js_1.createRingBufferSink)(timingRingBuffer), (0, tool_call_timing_js_1.createDevPerfSink)())
222
+ : (0, tool_call_timing_js_1.createRingBufferSink)(timingRingBuffer);
223
+ if (dev_mode_js_1.DEV_MODE) {
224
+ console.error('[PerfTrace] WORKRAIL_DEV=1 -- tool call timing active');
225
+ }
217
226
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
218
227
  const { name, arguments: args } = request.params;
228
+ const handlerStartMs = Date.now();
229
+ const handlerStartHr = performance.now();
219
230
  const handler = handlers[name];
220
231
  if (!handler) {
221
- return {
232
+ const unknownResult = {
222
233
  content: [{ type: 'text', text: `Unknown tool: ${name}` }],
223
234
  isError: true,
224
235
  };
236
+ const durationMs = Math.round((performance.now() - handlerStartHr) * 100) / 100;
237
+ try {
238
+ timingSink({ toolName: name ?? '(unknown)', startedAtMs: handlerStartMs, durationMs, outcome: 'unknown_tool' });
239
+ }
240
+ catch {
241
+ }
242
+ return unknownResult;
225
243
  }
226
244
  const requestCtx = ctx.v2
227
245
  ? { ...ctx, v2: { ...ctx.v2, resolvedRootUris: rootsManager.getCurrentRootUris() } }
228
246
  : ctx;
229
- return handler(args ?? {}, requestCtx);
247
+ return (0, tool_call_timing_js_1.withToolCallTiming)(name, () => handler(args ?? {}, requestCtx), timingSink);
230
248
  });
231
249
  server.setRequestHandler(ListResourcesRequestSchema, async () => ({
232
250
  resources: [
@@ -0,0 +1,24 @@
1
+ export type ToolCallOutcome = 'success' | 'error' | 'unknown_tool';
2
+ export interface ToolCallTiming {
3
+ readonly toolName: string;
4
+ readonly startedAtMs: number;
5
+ readonly durationMs: number;
6
+ readonly outcome: ToolCallOutcome;
7
+ }
8
+ export type ToolCallTimingSink = (timing: ToolCallTiming) => void;
9
+ export declare const noopToolCallTimingSink: ToolCallTimingSink;
10
+ export declare class ToolCallTimingRingBuffer {
11
+ private readonly capacity;
12
+ private readonly buffer;
13
+ private head;
14
+ private count;
15
+ constructor(capacity: number);
16
+ push(timing: ToolCallTiming): void;
17
+ recent(limit?: number): readonly ToolCallTiming[];
18
+ get size(): number;
19
+ }
20
+ export declare const DEFAULT_RING_BUFFER_CAPACITY = 100;
21
+ export declare function createRingBufferSink(buffer: ToolCallTimingRingBuffer): ToolCallTimingSink;
22
+ export declare function createDevPerfSink(): ToolCallTimingSink;
23
+ export declare function composeSinks(...sinks: ToolCallTimingSink[]): ToolCallTimingSink;
24
+ export declare function withToolCallTiming<T>(toolName: string, handler: () => Promise<T>, sink: ToolCallTimingSink): Promise<T>;