@exaudeus/workrail 3.14.0 → 3.15.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 (62) hide show
  1. package/dist/application/services/validation-engine.js +4 -9
  2. package/dist/application/services/workflow-compiler.js +4 -6
  3. package/dist/console/assets/index-BZYIjrzJ.js +28 -0
  4. package/dist/console/assets/index-OLCKbDdm.css +1 -0
  5. package/dist/console/index.html +2 -2
  6. package/dist/engine/engine-factory.js +2 -2
  7. package/dist/engine/types.d.ts +1 -1
  8. package/dist/manifest.json +63 -63
  9. package/dist/mcp/handlers/shared/request-workflow-reader.d.ts +5 -0
  10. package/dist/mcp/handlers/shared/request-workflow-reader.js +47 -2
  11. package/dist/mcp/handlers/v2-advance-core/assessment-consequences.d.ts +1 -1
  12. package/dist/mcp/handlers/v2-advance-core/assessment-consequences.js +4 -5
  13. package/dist/mcp/handlers/v2-advance-core/index.js +1 -1
  14. package/dist/mcp/handlers/v2-advance-core/outcome-blocked.js +1 -1
  15. package/dist/mcp/handlers/v2-execution/start.d.ts +1 -0
  16. package/dist/mcp/handlers/v2-execution/start.js +20 -1
  17. package/dist/mcp/handlers/v2-workflow.d.ts +20 -0
  18. package/dist/mcp/handlers/v2-workflow.js +119 -10
  19. package/dist/mcp/output-schemas.d.ts +109 -8
  20. package/dist/mcp/output-schemas.js +31 -11
  21. package/dist/mcp/server.js +48 -1
  22. package/dist/mcp/tool-descriptions.js +17 -9
  23. package/dist/mcp/v2/tools.d.ts +6 -0
  24. package/dist/mcp/v2/tools.js +2 -0
  25. package/dist/mcp/workflow-protocol-contracts.js +5 -1
  26. package/dist/types/workflow-definition.d.ts +1 -2
  27. package/dist/v2/infra/local/workspace-anchor/index.js +4 -1
  28. package/dist/v2/usecases/console-routes.js +49 -1
  29. package/dist/v2/usecases/console-service.d.ts +1 -0
  30. package/dist/v2/usecases/console-service.js +4 -1
  31. package/dist/v2/usecases/console-types.d.ts +12 -0
  32. package/dist/v2/usecases/worktree-service.js +55 -7
  33. package/package.json +2 -2
  34. package/spec/authoring-spec.json +82 -1
  35. package/spec/workflow-tags.json +132 -0
  36. package/spec/workflow.schema.json +3 -11
  37. package/workflows/adaptive-ticket-creation.json +40 -22
  38. package/workflows/architecture-scalability-audit.json +65 -31
  39. package/workflows/bug-investigation.agentic.v2.json +36 -14
  40. package/workflows/coding-task-workflow-agentic.json +50 -38
  41. package/workflows/coding-task-workflow-agentic.lean.v2.json +124 -37
  42. package/workflows/coding-task-workflow-agentic.v2.json +90 -30
  43. package/workflows/cross-platform-code-conversion.v2.json +168 -48
  44. package/workflows/document-creation-workflow.json +47 -17
  45. package/workflows/documentation-update-workflow.json +8 -8
  46. package/workflows/intelligent-test-case-generation.json +2 -2
  47. package/workflows/learner-centered-course-workflow.json +267 -267
  48. package/workflows/mr-review-workflow.agentic.v2.json +81 -14
  49. package/workflows/personal-learning-materials-creation-branched.json +175 -175
  50. package/workflows/presentation-creation.json +159 -159
  51. package/workflows/production-readiness-audit.json +54 -15
  52. package/workflows/relocation-workflow-us.json +44 -35
  53. package/workflows/routines/tension-driven-design.json +1 -1
  54. package/workflows/scoped-documentation-workflow.json +25 -25
  55. package/workflows/test-artifact-loop-control.json +1 -2
  56. package/workflows/ui-ux-design-workflow.json +327 -0
  57. package/workflows/workflow-diagnose-environment.json +1 -1
  58. package/workflows/workflow-for-workflows.json +507 -484
  59. package/workflows/workflow-for-workflows.v2.json +43 -11
  60. package/workflows/wr.discovery.json +112 -30
  61. package/dist/console/assets/index-DW78t31j.css +0 -1
  62. package/dist/console/assets/index-EsSXrC_a.js +0 -28
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.shouldShowStaleness = shouldShowStaleness;
7
+ exports.buildTagSummary = buildTagSummary;
7
8
  exports.computeWorkflowStaleness = computeWorkflowStaleness;
8
9
  exports.handleV2ListWorkflows = handleV2ListWorkflows;
9
10
  exports.handleV2InspectWorkflow = handleV2InspectWorkflow;
@@ -40,6 +41,39 @@ function shouldShowStaleness(category, devMode = DEV_STALENESS) {
40
41
  return true;
41
42
  return category === 'personal' || category === 'rooted_sharing' || category === 'external';
42
43
  }
44
+ function readWorkflowTags() {
45
+ try {
46
+ const tagsPath = path_1.default.resolve(__dirname, '../../../spec/workflow-tags.json');
47
+ const raw = fs_1.default.readFileSync(tagsPath, 'utf-8');
48
+ return JSON.parse(raw);
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ const WORKFLOW_TAGS = readWorkflowTags();
55
+ function buildTagSummary(tagsFile, compiledWorkflowIds) {
56
+ const idSet = new Set(compiledWorkflowIds);
57
+ return tagsFile.tags.map((tag) => {
58
+ const count = Object.entries(tagsFile.workflows)
59
+ .filter(([wid, meta]) => !meta.hidden && idSet.has(wid) && meta.tags.includes(tag.id))
60
+ .length;
61
+ return {
62
+ id: tag.id,
63
+ displayName: tag.displayName,
64
+ count,
65
+ when: [...tag.when],
66
+ examples: [...tag.examples],
67
+ };
68
+ });
69
+ }
70
+ function filterByTags(tagsFile, compiledWorkflowIds, requestedTags) {
71
+ const tagSet = new Set(requestedTags);
72
+ const matching = new Set(Object.entries(tagsFile.workflows)
73
+ .filter(([, meta]) => !meta.hidden && meta.tags.some((t) => tagSet.has(t)))
74
+ .map(([wid]) => wid));
75
+ return compiledWorkflowIds.filter((id) => matching.has(id));
76
+ }
43
77
  function computeWorkflowStaleness(stamp, currentVersion) {
44
78
  if (currentVersion === null)
45
79
  return undefined;
@@ -90,10 +124,17 @@ async function handleV2ListWorkflows(input, ctx) {
90
124
  workspacePath: input.workspacePath,
91
125
  resolvedRootUris: guard.ctx.v2.resolvedRootUris,
92
126
  rememberedRootsStore: guard.ctx.v2.rememberedRootsStore,
127
+ managedSourceStore: guard.ctx.v2.managedSourceStore,
93
128
  })
94
- : { reader: ctx.workflowService, stalePaths: [] };
129
+ : { reader: ctx.workflowService, stalePaths: [], managedSourceRecords: [], staleManagedRecords: [], managedStoreError: undefined };
95
130
  const workflowReader = readerResult.reader;
96
131
  const stalePaths = readerResult.stalePaths;
132
+ const managedSourceRecords = readerResult.managedSourceRecords;
133
+ const staleManagedRecords = readerResult.staleManagedRecords;
134
+ const managedStoreError = readerResult.managedStoreError;
135
+ const warnings = managedStoreError
136
+ ? [`Managed workflow source store was temporarily unavailable (${managedStoreError}). Managed sources were not loaded.`]
137
+ : undefined;
97
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))
98
139
  .andThen((summaries) => neverthrow_1.ResultAsync.combine(summaries.map((s) => neverthrow_1.ResultAsync.fromPromise(buildV2WorkflowListItem({
99
140
  summary: s,
@@ -103,25 +144,62 @@ async function handleV2ListWorkflows(input, ctx) {
103
144
  pinnedStore,
104
145
  }), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err)))))
105
146
  .andThen((compiled) => {
147
+ const sortedIds = compiled.map((w) => w.workflowId).sort((a, b) => a.localeCompare(b));
148
+ const sortedCompiled = [...compiled].sort((a, b) => a.workflowId.localeCompare(b.workflowId));
149
+ const tagFilteredCompiled = (() => {
150
+ if (input.includeSources)
151
+ return sortedCompiled;
152
+ if (!WORKFLOW_TAGS)
153
+ return sortedCompiled;
154
+ if (input.tags && input.tags.length > 0) {
155
+ const filteredIds = new Set(filterByTags(WORKFLOW_TAGS, sortedIds, input.tags));
156
+ return sortedCompiled.filter((w) => filteredIds.has(w.workflowId));
157
+ }
158
+ return [];
159
+ })();
160
+ const tagSummaryEntry = (() => {
161
+ if (input.includeSources)
162
+ return undefined;
163
+ if (!WORKFLOW_TAGS)
164
+ return undefined;
165
+ if (input.tags && input.tags.length > 0)
166
+ return undefined;
167
+ return buildTagSummary(WORKFLOW_TAGS, sortedIds);
168
+ })();
169
+ const nextStepHint = tagSummaryEntry
170
+ ? 'Pick a tag from tagSummary that fits the user\'s goal, then call list_workflows with tags=["<tagId>"]. ' +
171
+ 'If a workflow ID in examples[] already matches, call start_workflow directly — no second list call needed. ' +
172
+ 'If multiple tags could apply, pick the most specific one.'
173
+ : undefined;
106
174
  if (!input.includeSources) {
175
+ const includeStaleRoots = !tagSummaryEntry && stalePaths.length > 0;
107
176
  const payload = output_schemas_js_1.V2WorkflowListOutputSchema.parse({
108
- workflows: compiled.sort((a, b) => a.workflowId.localeCompare(b.workflowId)),
109
- ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
177
+ workflows: tagFilteredCompiled,
178
+ ...(tagSummaryEntry ? { tagSummary: tagSummaryEntry } : {}),
179
+ ...(nextStepHint ? { _nextStep: nextStepHint } : {}),
180
+ ...(includeStaleRoots ? { staleRoots: [...stalePaths] } : {}),
181
+ ...(warnings ? { warnings } : {}),
110
182
  });
111
183
  return (0, neverthrow_1.okAsync)((0, types_js_1.success)(payload));
112
184
  }
113
185
  if (!(0, workflow_source_visibility_js_1.isCompositeWorkflowReader)(workflowReader)) {
114
186
  const payload = output_schemas_js_1.V2WorkflowListOutputSchema.parse({
115
- workflows: compiled.sort((a, b) => a.workflowId.localeCompare(b.workflowId)),
187
+ workflows: tagFilteredCompiled,
188
+ ...(tagSummaryEntry ? { tagSummary: tagSummaryEntry } : {}),
189
+ ...(nextStepHint ? { _nextStep: nextStepHint } : {}),
116
190
  ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
191
+ ...(warnings ? { warnings } : {}),
117
192
  sources: [],
118
193
  });
119
194
  return (0, neverthrow_1.okAsync)((0, types_js_1.success)(payload));
120
195
  }
121
- return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(buildSourceCatalog(workflowReader, rememberedRootRecords), TIMEOUT_MS, 'list_workflow_sources'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err)).map((sources) => {
196
+ 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) => {
122
197
  const payload = output_schemas_js_1.V2WorkflowListOutputSchema.parse({
123
- workflows: compiled.sort((a, b) => a.workflowId.localeCompare(b.workflowId)),
198
+ workflows: tagFilteredCompiled,
199
+ ...(tagSummaryEntry ? { tagSummary: tagSummaryEntry } : {}),
200
+ ...(nextStepHint ? { _nextStep: nextStepHint } : {}),
124
201
  ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
202
+ ...(warnings ? { warnings } : {}),
125
203
  sources,
126
204
  });
127
205
  return (0, types_js_1.success)(payload);
@@ -150,10 +228,14 @@ async function handleV2InspectWorkflow(input, ctx) {
150
228
  workspacePath: input.workspacePath,
151
229
  resolvedRootUris: guard.ctx.v2.resolvedRootUris,
152
230
  rememberedRootsStore: guard.ctx.v2.rememberedRootsStore,
231
+ managedSourceStore: guard.ctx.v2.managedSourceStore,
153
232
  })
154
- : { reader: ctx.workflowService, stalePaths: [] };
233
+ : { reader: ctx.workflowService, stalePaths: [], managedSourceRecords: [], staleManagedRecords: [], managedStoreError: undefined };
155
234
  const workflowReader = readerResult.reader;
156
235
  const stalePaths = readerResult.stalePaths;
236
+ const inspectWarnings = readerResult.managedStoreError
237
+ ? [`Managed workflow source store was temporarily unavailable (${readerResult.managedStoreError}). Managed sources were not loaded.`]
238
+ : undefined;
157
239
  return neverthrow_1.ResultAsync.fromPromise((0, with_timeout_js_1.withTimeout)(workflowReader.getWorkflowById(input.workflowId), TIMEOUT_MS, 'inspect_workflow'), (err) => (0, error_mapper_js_1.mapUnknownErrorToToolError)(err))
158
240
  .andThen((workflow) => {
159
241
  if (!workflow) {
@@ -189,6 +271,7 @@ async function handleV2InspectWorkflow(input, ctx) {
189
271
  compiled: body,
190
272
  ...(visibility ? { visibility } : {}),
191
273
  ...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
274
+ ...(inspectWarnings ? { warnings: inspectWarnings } : {}),
192
275
  ...(references != null && references.length > 0 ? { references } : {}),
193
276
  ...(() => {
194
277
  const staleness = shouldShowStaleness(visibility?.category)
@@ -267,7 +350,7 @@ async function buildV2WorkflowListItem(options) {
267
350
  ...(staleness !== undefined ? { staleness } : {}),
268
351
  };
269
352
  }
270
- async function buildSourceCatalog(workflowReader, rememberedRootRecords) {
353
+ async function buildSourceCatalog(workflowReader, rememberedRootRecords, managedSourceRecords, staleManagedRecords) {
271
354
  const instances = workflowReader.getStorageInstances();
272
355
  const seenIds = new Set();
273
356
  const sourceEntryDataReversed = [];
@@ -281,10 +364,22 @@ async function buildSourceCatalog(workflowReader, rememberedRootRecords) {
281
364
  sourceEntryDataReversed.push({ source: instance.source, allIds, effectiveIds });
282
365
  }
283
366
  const sourceEntryData = sourceEntryDataReversed.reverse();
284
- return sourceEntryData.map((data) => deriveSourceCatalogEntry({ ...data, rememberedRootRecords, sourceEntryData }));
367
+ const activeEntries = sourceEntryData.map((data) => deriveSourceCatalogEntry({ ...data, rememberedRootRecords, managedSourceRecords, sourceEntryData }));
368
+ const staleEntries = staleManagedRecords.map((record) => ({
369
+ sourceKey: `custom:${record.path}`,
370
+ category: 'managed',
371
+ source: { kind: 'custom', displayName: path_1.default.basename(record.path) },
372
+ sourceMode: 'live_directory',
373
+ effectiveWorkflowCount: 0,
374
+ totalWorkflowCount: 0,
375
+ shadowedWorkflowCount: 0,
376
+ managed: { addedAtMs: record.addedAtMs },
377
+ stale: true,
378
+ }));
379
+ return [...activeEntries, ...staleEntries];
285
380
  }
286
381
  function deriveSourceCatalogEntry(options) {
287
- const { source, allIds, effectiveIds, rememberedRootRecords, sourceEntryData } = options;
382
+ const { source, allIds, effectiveIds, rememberedRootRecords, managedSourceRecords, sourceEntryData } = options;
288
383
  const total = allIds.length;
289
384
  const effective = effectiveIds.length;
290
385
  const shadowed = total - effective;
@@ -310,6 +405,20 @@ function deriveSourceCatalogEntry(options) {
310
405
  }
311
406
  case 'custom': {
312
407
  const rootedSharing = deriveRootedSharingForPath(source.directoryPath, rememberedRootRecords);
408
+ const managedRecord = managedSourceRecords.find((r) => path_1.default.resolve(r.path) === path_1.default.resolve(source.directoryPath));
409
+ if (managedRecord) {
410
+ return {
411
+ sourceKey,
412
+ category: 'managed',
413
+ source: { kind: source.kind, displayName },
414
+ sourceMode: 'live_directory',
415
+ effectiveWorkflowCount: effective,
416
+ totalWorkflowCount: total,
417
+ shadowedWorkflowCount: shadowed,
418
+ managed: { addedAtMs: managedRecord.addedAtMs },
419
+ ...(rootedSharing ? { rootedSharing } : {}),
420
+ };
421
+ }
313
422
  const category = rootedSharing ? 'rooted_sharing' : 'external';
314
423
  const sourceMode = rootedSharing ? 'rooted_sharing' : 'live_directory';
315
424
  return { sourceKey, category, source: { kind: source.kind, displayName }, sourceMode, effectiveWorkflowCount: effective, totalWorkflowCount: total, shadowedWorkflowCount: shadowed, ...(rootedSharing ? { rootedSharing } : {}) };
@@ -325,7 +325,7 @@ export declare const V2WorkflowListItemSchema: z.ZodObject<{
325
325
  }>;
326
326
  export declare const V2WorkflowSourceCatalogEntrySchema: z.ZodObject<{
327
327
  sourceKey: z.ZodString;
328
- category: z.ZodEnum<["built_in", "personal", "legacy_project", "rooted_sharing", "external"]>;
328
+ category: z.ZodEnum<["built_in", "personal", "legacy_project", "rooted_sharing", "external", "managed"]>;
329
329
  source: z.ZodObject<{
330
330
  kind: z.ZodEnum<["bundled", "user", "project", "custom", "git", "remote", "plugin"]>;
331
331
  displayName: z.ZodString;
@@ -353,6 +353,14 @@ export declare const V2WorkflowSourceCatalogEntrySchema: z.ZodObject<{
353
353
  rootPath: string;
354
354
  groupLabel: string;
355
355
  }>>;
356
+ managed: z.ZodOptional<z.ZodObject<{
357
+ addedAtMs: z.ZodNumber;
358
+ }, "strip", z.ZodTypeAny, {
359
+ addedAtMs: number;
360
+ }, {
361
+ addedAtMs: number;
362
+ }>>;
363
+ stale: z.ZodOptional<z.ZodLiteral<true>>;
356
364
  migration: z.ZodOptional<z.ZodObject<{
357
365
  preferredSource: z.ZodLiteral<"rooted_sharing">;
358
366
  currentSource: z.ZodLiteral<"legacy_project">;
@@ -374,7 +382,7 @@ export declare const V2WorkflowSourceCatalogEntrySchema: z.ZodObject<{
374
382
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
375
383
  displayName: string;
376
384
  };
377
- category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external";
385
+ category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external" | "managed";
378
386
  sourceKey: string;
379
387
  sourceMode: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "live_directory";
380
388
  effectiveWorkflowCount: number;
@@ -391,12 +399,16 @@ export declare const V2WorkflowSourceCatalogEntrySchema: z.ZodObject<{
391
399
  preferredSource: "rooted_sharing";
392
400
  currentSource: "legacy_project";
393
401
  } | undefined;
402
+ managed?: {
403
+ addedAtMs: number;
404
+ } | undefined;
405
+ stale?: true | undefined;
394
406
  }, {
395
407
  source: {
396
408
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
397
409
  displayName: string;
398
410
  };
399
- category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external";
411
+ category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external" | "managed";
400
412
  sourceKey: string;
401
413
  sourceMode: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "live_directory";
402
414
  effectiveWorkflowCount: number;
@@ -413,6 +425,29 @@ export declare const V2WorkflowSourceCatalogEntrySchema: z.ZodObject<{
413
425
  preferredSource: "rooted_sharing";
414
426
  currentSource: "legacy_project";
415
427
  } | undefined;
428
+ managed?: {
429
+ addedAtMs: number;
430
+ } | undefined;
431
+ stale?: true | undefined;
432
+ }>;
433
+ export declare const TagSummaryItemSchema: z.ZodObject<{
434
+ id: z.ZodString;
435
+ displayName: z.ZodString;
436
+ count: z.ZodNumber;
437
+ when: z.ZodArray<z.ZodString, "many">;
438
+ examples: z.ZodArray<z.ZodString, "many">;
439
+ }, "strip", z.ZodTypeAny, {
440
+ id: string;
441
+ when: string[];
442
+ displayName: string;
443
+ examples: string[];
444
+ count: number;
445
+ }, {
446
+ id: string;
447
+ when: string[];
448
+ displayName: string;
449
+ examples: string[];
450
+ count: number;
416
451
  }>;
417
452
  export declare const V2WorkflowListOutputSchema: z.ZodObject<{
418
453
  workflows: z.ZodArray<z.ZodObject<{
@@ -572,10 +607,31 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
572
607
  specVersionAtLastReview?: number | undefined;
573
608
  } | undefined;
574
609
  }>, "many">;
610
+ tagSummary: z.ZodOptional<z.ZodArray<z.ZodObject<{
611
+ id: z.ZodString;
612
+ displayName: z.ZodString;
613
+ count: z.ZodNumber;
614
+ when: z.ZodArray<z.ZodString, "many">;
615
+ examples: z.ZodArray<z.ZodString, "many">;
616
+ }, "strip", z.ZodTypeAny, {
617
+ id: string;
618
+ when: string[];
619
+ displayName: string;
620
+ examples: string[];
621
+ count: number;
622
+ }, {
623
+ id: string;
624
+ when: string[];
625
+ displayName: string;
626
+ examples: string[];
627
+ count: number;
628
+ }>, "many">>;
629
+ _nextStep: z.ZodOptional<z.ZodString>;
575
630
  staleRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
631
+ warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
576
632
  sources: z.ZodOptional<z.ZodArray<z.ZodObject<{
577
633
  sourceKey: z.ZodString;
578
- category: z.ZodEnum<["built_in", "personal", "legacy_project", "rooted_sharing", "external"]>;
634
+ category: z.ZodEnum<["built_in", "personal", "legacy_project", "rooted_sharing", "external", "managed"]>;
579
635
  source: z.ZodObject<{
580
636
  kind: z.ZodEnum<["bundled", "user", "project", "custom", "git", "remote", "plugin"]>;
581
637
  displayName: z.ZodString;
@@ -603,6 +659,14 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
603
659
  rootPath: string;
604
660
  groupLabel: string;
605
661
  }>>;
662
+ managed: z.ZodOptional<z.ZodObject<{
663
+ addedAtMs: z.ZodNumber;
664
+ }, "strip", z.ZodTypeAny, {
665
+ addedAtMs: number;
666
+ }, {
667
+ addedAtMs: number;
668
+ }>>;
669
+ stale: z.ZodOptional<z.ZodLiteral<true>>;
606
670
  migration: z.ZodOptional<z.ZodObject<{
607
671
  preferredSource: z.ZodLiteral<"rooted_sharing">;
608
672
  currentSource: z.ZodLiteral<"legacy_project">;
@@ -624,7 +688,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
624
688
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
625
689
  displayName: string;
626
690
  };
627
- category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external";
691
+ category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external" | "managed";
628
692
  sourceKey: string;
629
693
  sourceMode: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "live_directory";
630
694
  effectiveWorkflowCount: number;
@@ -641,12 +705,16 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
641
705
  preferredSource: "rooted_sharing";
642
706
  currentSource: "legacy_project";
643
707
  } | undefined;
708
+ managed?: {
709
+ addedAtMs: number;
710
+ } | undefined;
711
+ stale?: true | undefined;
644
712
  }, {
645
713
  source: {
646
714
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
647
715
  displayName: string;
648
716
  };
649
- category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external";
717
+ category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external" | "managed";
650
718
  sourceKey: string;
651
719
  sourceMode: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "live_directory";
652
720
  effectiveWorkflowCount: number;
@@ -663,6 +731,10 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
663
731
  preferredSource: "rooted_sharing";
664
732
  currentSource: "legacy_project";
665
733
  } | undefined;
734
+ managed?: {
735
+ addedAtMs: number;
736
+ } | undefined;
737
+ stale?: true | undefined;
666
738
  }>, "many">>;
667
739
  }, "strip", z.ZodTypeAny, {
668
740
  workflows: {
@@ -701,7 +773,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
701
773
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
702
774
  displayName: string;
703
775
  };
704
- category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external";
776
+ category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external" | "managed";
705
777
  sourceKey: string;
706
778
  sourceMode: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "live_directory";
707
779
  effectiveWorkflowCount: number;
@@ -718,7 +790,20 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
718
790
  preferredSource: "rooted_sharing";
719
791
  currentSource: "legacy_project";
720
792
  } | undefined;
793
+ managed?: {
794
+ addedAtMs: number;
795
+ } | undefined;
796
+ stale?: true | undefined;
721
797
  }[] | undefined;
798
+ warnings?: string[] | undefined;
799
+ tagSummary?: {
800
+ id: string;
801
+ when: string[];
802
+ displayName: string;
803
+ examples: string[];
804
+ count: number;
805
+ }[] | undefined;
806
+ _nextStep?: string | undefined;
722
807
  staleRoots?: string[] | undefined;
723
808
  }, {
724
809
  workflows: {
@@ -757,7 +842,7 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
757
842
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
758
843
  displayName: string;
759
844
  };
760
- category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external";
845
+ category: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "external" | "managed";
761
846
  sourceKey: string;
762
847
  sourceMode: "built_in" | "personal" | "legacy_project" | "rooted_sharing" | "live_directory";
763
848
  effectiveWorkflowCount: number;
@@ -774,7 +859,20 @@ export declare const V2WorkflowListOutputSchema: z.ZodObject<{
774
859
  preferredSource: "rooted_sharing";
775
860
  currentSource: "legacy_project";
776
861
  } | undefined;
862
+ managed?: {
863
+ addedAtMs: number;
864
+ } | undefined;
865
+ stale?: true | undefined;
866
+ }[] | undefined;
867
+ warnings?: string[] | undefined;
868
+ tagSummary?: {
869
+ id: string;
870
+ when: string[];
871
+ displayName: string;
872
+ examples: string[];
873
+ count: number;
777
874
  }[] | undefined;
875
+ _nextStep?: string | undefined;
778
876
  staleRoots?: string[] | undefined;
779
877
  }>;
780
878
  export declare const V2WorkflowInspectOutputSchema: z.ZodObject<{
@@ -859,6 +957,7 @@ export declare const V2WorkflowInspectOutputSchema: z.ZodObject<{
859
957
  } | undefined;
860
958
  }>>>;
861
959
  staleRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
960
+ warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
862
961
  references: z.ZodOptional<z.ZodArray<z.ZodObject<{
863
962
  id: z.ZodString;
864
963
  title: z.ZodString;
@@ -907,6 +1006,7 @@ export declare const V2WorkflowInspectOutputSchema: z.ZodObject<{
907
1006
  authoritative: boolean;
908
1007
  resolveFrom?: "workspace" | "package" | undefined;
909
1008
  }[] | undefined;
1009
+ warnings?: string[] | undefined;
910
1010
  visibility?: {
911
1011
  source: {
912
1012
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -944,6 +1044,7 @@ export declare const V2WorkflowInspectOutputSchema: z.ZodObject<{
944
1044
  authoritative: boolean;
945
1045
  resolveFrom?: "workspace" | "package" | undefined;
946
1046
  }[] | undefined;
1047
+ warnings?: string[] | undefined;
947
1048
  visibility?: {
948
1049
  source: {
949
1050
  kind: "custom" | "bundled" | "user" | "project" | "git" | "remote" | "plugin";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2CheckpointWorkflowOutputSchema = exports.V2ResumeSessionOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2StepContextSchema = exports.V2BindingDriftWarningSchema = exports.V2BlockerReportSchema = exports.V2ResumeNextCallSchema = exports.V2NextCallSchema = exports.V2NextIntentSchema = exports.V2PreferencesSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.V2WorkflowSourceCatalogEntrySchema = exports.V2WorkflowListItemSchema = exports.StalenessSummarySchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
3
+ exports.OpenDashboardOutputSchema = exports.ReadSessionSchemaOutputSchema = exports.ReadSessionOutputSchema = exports.UpdateSessionOutputSchema = exports.CreateSessionOutputSchema = exports.V2StartWorkflowOutputSchema = exports.V2CheckpointWorkflowOutputSchema = exports.V2ResumeSessionOutputSchema = exports.V2ContinueWorkflowOutputSchema = exports.V2StepContextSchema = exports.V2BindingDriftWarningSchema = exports.V2BlockerReportSchema = exports.V2ResumeNextCallSchema = exports.V2NextCallSchema = exports.V2NextIntentSchema = exports.V2PreferencesSchema = exports.V2PendingStepSchema = exports.V2WorkflowInspectOutputSchema = exports.V2WorkflowListOutputSchema = exports.TagSummaryItemSchema = exports.V2WorkflowSourceCatalogEntrySchema = exports.V2WorkflowListItemSchema = exports.StalenessSummarySchema = exports.WorkflowGetSchemaOutputSchema = exports.WorkflowValidateJsonOutputSchema = exports.WorkflowNextOutputSchema = exports.WorkflowGetOutputSchema = exports.WorkflowListOutputSchema = exports.WorkflowSummarySchema = exports.JsonValueSchema = void 0;
4
4
  exports.toPendingStep = toPendingStep;
5
5
  const zod_1 = require("zod");
6
6
  const state_js_1 = require("../domain/execution/state.js");
@@ -82,7 +82,7 @@ exports.V2WorkflowListItemSchema = zod_1.z.object({
82
82
  });
83
83
  exports.V2WorkflowSourceCatalogEntrySchema = zod_1.z.object({
84
84
  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.'),
85
- category: zod_1.z.enum(['built_in', 'personal', 'legacy_project', 'rooted_sharing', 'external']),
85
+ category: zod_1.z.enum(['built_in', 'personal', 'legacy_project', 'rooted_sharing', 'external', 'managed']),
86
86
  source: zod_1.z.object({
87
87
  kind: zod_1.z.enum(['bundled', 'user', 'project', 'custom', 'git', 'remote', 'plugin']),
88
88
  displayName: zod_1.z.string().min(1),
@@ -96,6 +96,11 @@ exports.V2WorkflowSourceCatalogEntrySchema = zod_1.z.object({
96
96
  rootPath: zod_1.z.string().min(1),
97
97
  groupLabel: zod_1.z.string().min(1),
98
98
  }).optional(),
99
+ managed: zod_1.z.object({
100
+ addedAtMs: zod_1.z.number().int().min(0),
101
+ }).optional(),
102
+ stale: zod_1.z.literal(true).optional().describe('Present and true when this source directory was not accessible during discovery. ' +
103
+ 'The path is also included in staleRoots. Workflows from this source were not loaded.'),
99
104
  migration: zod_1.z.object({
100
105
  preferredSource: zod_1.z.literal('rooted_sharing'),
101
106
  currentSource: zod_1.z.literal('legacy_project'),
@@ -103,11 +108,24 @@ exports.V2WorkflowSourceCatalogEntrySchema = zod_1.z.object({
103
108
  summary: zod_1.z.string().min(1),
104
109
  }).optional(),
105
110
  });
111
+ exports.TagSummaryItemSchema = zod_1.z.object({
112
+ id: zod_1.z.string().min(1).describe('Tag identifier, e.g. "coding" or "review_audit".'),
113
+ displayName: zod_1.z.string().min(1).describe('Human-readable tag name.'),
114
+ count: zod_1.z.number().int().min(0).describe('Number of workflows with this tag.'),
115
+ when: zod_1.z.array(zod_1.z.string()).describe('Intent phrases describing when to use workflows in this tag.'),
116
+ examples: zod_1.z.array(zod_1.z.string()).describe('Representative workflow IDs for this tag.'),
117
+ });
106
118
  exports.V2WorkflowListOutputSchema = zod_1.z.object({
107
119
  workflows: zod_1.z.array(exports.V2WorkflowListItemSchema),
108
- staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Remembered workspace roots that were inaccessible during workflow discovery. ' +
109
- 'Workflows from these roots were not included in this response. ' +
110
- 'These roots will be retried on the next call.'),
120
+ tagSummary: zod_1.z.array(exports.TagSummaryItemSchema).optional().describe('Tag summary for the workflow catalog. Present when no tags filter was applied. ' +
121
+ 'Each entry covers one domain tag with a workflow count, intent phrases (when to use), and representative workflow IDs. ' +
122
+ 'Use tags=[\"<id>\"] to get the full workflow list for a specific tag. Absent when a tags filter was applied.'),
123
+ _nextStep: zod_1.z.string().optional().describe('Guidance on what to do next. Present when tagSummary is returned (no tags filter applied).'),
124
+ staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Workflow source paths that were inaccessible during discovery (missing remembered roots or missing managed source directories). ' +
125
+ 'Workflows from these paths were not included in this response. ' +
126
+ 'These paths will be rechecked on the next call.'),
127
+ warnings: zod_1.z.array(zod_1.z.string()).optional().describe('Advisory messages about infrastructure issues that did not prevent a response but may have caused incomplete results. ' +
128
+ 'Example: the managed source store was temporarily unavailable and managed sources were not loaded.'),
111
129
  sources: zod_1.z.array(exports.V2WorkflowSourceCatalogEntrySchema).optional().describe('Source catalog for this workspace. Only present when includeSources was true in the request. ' +
112
130
  'Shows where workflows come from with effective and shadowed counts per source.'),
113
131
  });
@@ -117,9 +135,11 @@ exports.V2WorkflowInspectOutputSchema = zod_1.z.object({
117
135
  mode: zod_1.z.enum(['metadata', 'preview']),
118
136
  compiled: exports.JsonValueSchema,
119
137
  visibility: exports.V2WorkflowListItemSchema.shape.visibility.optional(),
120
- staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Remembered workspace roots that were inaccessible during workflow discovery. ' +
121
- 'Workflows from these roots were not included in this response. ' +
122
- 'These roots will be retried on the next call.'),
138
+ staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Workflow source paths that were inaccessible during discovery (missing remembered roots or missing managed source directories). ' +
139
+ 'Workflows from these paths were not included in this response. ' +
140
+ 'These paths will be rechecked on the next call.'),
141
+ warnings: zod_1.z.array(zod_1.z.string()).optional().describe('Advisory messages about infrastructure issues that did not prevent a response but may have caused incomplete results. ' +
142
+ 'Example: the managed source store was temporarily unavailable and managed sources were not loaded.'),
123
143
  references: zod_1.z.array(zod_1.z.object({
124
144
  id: zod_1.z.string().min(1),
125
145
  title: zod_1.z.string().min(1),
@@ -371,9 +391,9 @@ exports.V2StartWorkflowOutputSchema = zod_1.z.object({
371
391
  preferences: exports.V2PreferencesSchema,
372
392
  nextIntent: exports.V2NextIntentSchema,
373
393
  nextCall: exports.V2NextCallSchema,
374
- staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Remembered workspace roots that were inaccessible during workflow discovery. ' +
375
- 'Workflows from these roots were not included in this response. ' +
376
- 'These roots will be retried on the next call.'),
394
+ staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Workflow source paths that were inaccessible during discovery (missing remembered roots or missing managed source directories). ' +
395
+ 'Workflows from these paths were not included in this response. ' +
396
+ 'These paths will be rechecked on the next call.'),
377
397
  }).refine((data) => (data.pending ? data.continueToken != null : true), { message: 'continueToken is required when a pending step exists' });
378
398
  exports.CreateSessionOutputSchema = zod_1.z.object({
379
399
  sessionId: zod_1.z.string().min(1),
@@ -190,13 +190,14 @@ async function composeServer() {
190
190
  }
191
191
  const rootsManager = new workspace_roots_manager_js_1.WorkspaceRootsManager();
192
192
  const { Server } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/index.js')));
193
- const { CallToolRequestSchema, ListToolsRequestSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
193
+ const { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
194
194
  const server = new Server({
195
195
  name: 'workrail-server',
196
196
  version: '0.1.0',
197
197
  }, {
198
198
  capabilities: {
199
199
  tools: {},
200
+ resources: {},
200
201
  },
201
202
  });
202
203
  const tools = workflowEdition.tools.map(toMcpTool);
@@ -227,5 +228,51 @@ async function composeServer() {
227
228
  : ctx;
228
229
  return handler(args ?? {}, requestCtx);
229
230
  });
231
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
232
+ resources: [
233
+ {
234
+ uri: 'workrail://tags',
235
+ name: 'WorkRail Tag Catalog',
236
+ description: 'Closed-set tag definitions for workflow discovery. ' +
237
+ 'Read this before calling list_workflows — it tells you which tags exist ' +
238
+ 'and when to use each one, so you can call list_workflows with tags=[...] ' +
239
+ 'instead of loading all 36+ workflows into context.',
240
+ mimeType: 'application/json',
241
+ },
242
+ ],
243
+ }));
244
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
245
+ const uri = request.params?.uri ?? '';
246
+ if (uri !== 'workrail://tags') {
247
+ return {
248
+ contents: [],
249
+ isError: true,
250
+ _meta: { error: `Unknown resource: ${uri}` },
251
+ };
252
+ }
253
+ try {
254
+ const fs = await Promise.resolve().then(() => __importStar(require('fs')));
255
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
256
+ const tagsPath = path.resolve(__dirname, '../../spec/workflow-tags.json');
257
+ const raw = fs.readFileSync(tagsPath, 'utf-8');
258
+ return {
259
+ contents: [
260
+ {
261
+ uri: 'workrail://tags',
262
+ mimeType: 'application/json',
263
+ text: raw,
264
+ },
265
+ ],
266
+ };
267
+ }
268
+ catch (err) {
269
+ const message = err instanceof Error ? err.message : String(err);
270
+ return {
271
+ contents: [],
272
+ isError: true,
273
+ _meta: { error: `Failed to read tag catalog: ${message}` },
274
+ };
275
+ }
276
+ });
230
277
  return { server, ctx, rootsManager, rootsReader: rootsManager, tools, handlers };
231
278
  }