@exaudeus/workrail 3.12.0 → 3.13.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 (47) hide show
  1. package/dist/console/assets/{index-CRgjJiMS.js → index-EsSXrC_a.js} +11 -11
  2. package/dist/console/index.html +1 -1
  3. package/dist/di/container.js +8 -0
  4. package/dist/di/tokens.d.ts +1 -0
  5. package/dist/di/tokens.js +1 -0
  6. package/dist/infrastructure/session/HttpServer.js +2 -14
  7. package/dist/manifest.json +83 -43
  8. package/dist/mcp/boundary-coercion.d.ts +2 -0
  9. package/dist/mcp/boundary-coercion.js +73 -0
  10. package/dist/mcp/handler-factory.d.ts +1 -1
  11. package/dist/mcp/handler-factory.js +13 -6
  12. package/dist/mcp/handlers/v2-manage-workflow-source.d.ts +7 -0
  13. package/dist/mcp/handlers/v2-manage-workflow-source.js +50 -0
  14. package/dist/mcp/server.js +2 -0
  15. package/dist/mcp/tool-descriptions.js +20 -0
  16. package/dist/mcp/tools.js +6 -0
  17. package/dist/mcp/types/tool-description-types.d.ts +1 -1
  18. package/dist/mcp/types/tool-description-types.js +1 -0
  19. package/dist/mcp/types/workflow-tool-edition.d.ts +1 -1
  20. package/dist/mcp/types.d.ts +2 -0
  21. package/dist/mcp/v2/tool-registry.js +8 -0
  22. package/dist/mcp/v2/tools.d.ts +12 -0
  23. package/dist/mcp/v2/tools.js +7 -1
  24. package/dist/v2/infra/in-memory/managed-source-store/index.d.ts +8 -0
  25. package/dist/v2/infra/in-memory/managed-source-store/index.js +33 -0
  26. package/dist/v2/infra/local/data-dir/index.d.ts +2 -0
  27. package/dist/v2/infra/local/data-dir/index.js +6 -0
  28. package/dist/v2/infra/local/managed-source-store/index.d.ts +15 -0
  29. package/dist/v2/infra/local/managed-source-store/index.js +164 -0
  30. package/dist/v2/ports/data-dir.port.d.ts +2 -0
  31. package/dist/v2/ports/managed-source-store.port.d.ts +25 -0
  32. package/dist/v2/ports/managed-source-store.port.js +2 -0
  33. package/package.json +1 -1
  34. package/workflows/adaptive-ticket-creation.json +276 -282
  35. package/workflows/document-creation-workflow.json +70 -191
  36. package/workflows/documentation-update-workflow.json +59 -309
  37. package/workflows/intelligent-test-case-generation.json +37 -212
  38. package/workflows/personal-learning-materials-creation-branched.json +1 -21
  39. package/workflows/presentation-creation.json +143 -308
  40. package/workflows/relocation-workflow-us.json +161 -535
  41. package/workflows/scoped-documentation-workflow.json +110 -181
  42. package/workflows/workflow-for-workflows.v2.json +21 -5
  43. package/workflows/CHANGELOG-bug-investigation.md +0 -298
  44. package/workflows/bug-investigation.agentic.json +0 -212
  45. package/workflows/bug-investigation.json +0 -112
  46. package/workflows/mr-review-workflow.agentic.json +0 -538
  47. package/workflows/mr-review-workflow.json +0 -277
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildV2ToolRegistry = buildV2ToolRegistry;
4
4
  const handler_factory_js_1 = require("../handler-factory.js");
5
5
  const tools_js_1 = require("./tools.js");
6
+ const v2_manage_workflow_source_js_1 = require("../handlers/v2-manage-workflow-source.js");
6
7
  const v2_execution_js_1 = require("../handlers/v2-execution.js");
7
8
  const v2_workflow_js_1 = require("../handlers/v2-workflow.js");
8
9
  const v2_checkpoint_js_1 = require("../handlers/v2-checkpoint.js");
@@ -46,6 +47,12 @@ function buildV2ToolRegistry(buildTool) {
46
47
  inputSchema: tools_js_1.V2ResumeSessionInput,
47
48
  annotations: tools_js_1.V2_TOOL_ANNOTATIONS.resume_session,
48
49
  }),
50
+ buildTool({
51
+ name: 'manage_workflow_source',
52
+ title: tools_js_1.V2_TOOL_TITLES.manage_workflow_source,
53
+ inputSchema: tools_js_1.V2ManageWorkflowSourceInput,
54
+ annotations: tools_js_1.V2_TOOL_ANNOTATIONS.manage_workflow_source,
55
+ }),
49
56
  ];
50
57
  const handlers = {
51
58
  list_workflows: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ListWorkflowsInput, v2_workflow_js_1.handleV2ListWorkflows),
@@ -54,6 +61,7 @@ function buildV2ToolRegistry(buildTool) {
54
61
  continue_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ContinueWorkflowInput, v2_execution_js_1.handleV2ContinueWorkflow, tools_js_1.V2ContinueWorkflowInputShape, workflow_protocol_contracts_js_1.CONTINUE_WORKFLOW_PROTOCOL.aliasMap),
55
62
  checkpoint_workflow: (0, handler_factory_js_1.createHandler)(tools_js_1.V2CheckpointWorkflowInput, v2_checkpoint_js_1.handleV2CheckpointWorkflow),
56
63
  resume_session: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ResumeSessionInput, v2_resume_js_1.handleV2ResumeSession),
64
+ manage_workflow_source: (0, handler_factory_js_1.createHandler)(tools_js_1.V2ManageWorkflowSourceInput, v2_manage_workflow_source_js_1.handleV2ManageWorkflowSource),
57
65
  };
58
66
  return { tools, handlers };
59
67
  }
@@ -174,6 +174,17 @@ export declare const V2ResumeSessionInput: z.ZodObject<{
174
174
  sameWorkspaceOnly?: boolean | undefined;
175
175
  }>;
176
176
  export type V2ResumeSessionInput = z.infer<typeof V2ResumeSessionInput>;
177
+ export declare const V2ManageWorkflowSourceInput: z.ZodObject<{
178
+ action: z.ZodEnum<["attach", "detach"]>;
179
+ path: z.ZodEffects<z.ZodString, string, string>;
180
+ }, "strict", z.ZodTypeAny, {
181
+ path: string;
182
+ action: "attach" | "detach";
183
+ }, {
184
+ path: string;
185
+ action: "attach" | "detach";
186
+ }>;
187
+ export type V2ManageWorkflowSourceInput = z.infer<typeof V2ManageWorkflowSourceInput>;
177
188
  export declare const V2CheckpointWorkflowInput: z.ZodObject<{
178
189
  checkpointToken: z.ZodString;
179
190
  }, "strict", z.ZodTypeAny, {
@@ -189,5 +200,6 @@ export declare const V2_TOOL_TITLES: {
189
200
  readonly continue_workflow: "Continue Workflow (v2)";
190
201
  readonly checkpoint_workflow: "Checkpoint Workflow (v2)";
191
202
  readonly resume_session: "Resume Session (v2)";
203
+ readonly manage_workflow_source: "Manage Workflow Source (v2)";
192
204
  };
193
205
  export declare const V2_TOOL_ANNOTATIONS: Readonly<Record<keyof typeof V2_TOOL_TITLES, ToolAnnotations>>;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2CheckpointWorkflowInput = exports.V2ResumeSessionInput = exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
6
+ exports.V2_TOOL_ANNOTATIONS = exports.V2_TOOL_TITLES = exports.V2CheckpointWorkflowInput = exports.V2ManageWorkflowSourceInput = exports.V2ResumeSessionInput = exports.V2ContinueWorkflowInput = exports.V2ContinueWorkflowInputShape = exports.V2StartWorkflowInput = exports.V2InspectWorkflowInput = exports.V2ListWorkflowsInput = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const zod_1 = require("zod");
9
9
  const workflow_protocol_contracts_js_1 = require("../workflow-protocol-contracts.js");
@@ -112,6 +112,10 @@ exports.V2ResumeSessionInput = zod_1.z.object({
112
112
  sameWorkspaceOnly: zod_1.z.boolean().optional().describe('If true, only sessions from the same repo/workspace are considered when repo_root_hash is available. ' +
113
113
  'Use this when the user clearly means "resume work from this repo only".'),
114
114
  }).strict();
115
+ exports.V2ManageWorkflowSourceInput = zod_1.z.object({
116
+ action: zod_1.z.enum(['attach', 'detach']).describe('The operation to perform. "attach" registers the directory as a managed workflow source; "detach" removes it. Both operations are idempotent.'),
117
+ path: zod_1.z.string().min(1).refine((p) => path_1.default.isAbsolute(p), 'path must be an absolute path').describe('Absolute filesystem path to the workflow directory to attach or detach. Must be an absolute path. The path is normalized (resolved) before storage.'),
118
+ }).strict();
115
119
  exports.V2CheckpointWorkflowInput = zod_1.z.object({
116
120
  checkpointToken: zod_1.z.string().min(1).describe('The checkpoint token from the most recent start_workflow or continue_workflow response. ' +
117
121
  'Creates a checkpoint on the current step without advancing. Idempotent — calling with the same token is safe.'),
@@ -123,6 +127,7 @@ exports.V2_TOOL_TITLES = {
123
127
  continue_workflow: 'Continue Workflow (v2)',
124
128
  checkpoint_workflow: 'Checkpoint Workflow (v2)',
125
129
  resume_session: 'Resume Session (v2)',
130
+ manage_workflow_source: 'Manage Workflow Source (v2)',
126
131
  };
127
132
  exports.V2_TOOL_ANNOTATIONS = {
128
133
  list_workflows: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -131,4 +136,5 @@ exports.V2_TOOL_ANNOTATIONS = {
131
136
  continue_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
132
137
  checkpoint_workflow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
133
138
  resume_session: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
139
+ manage_workflow_source: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
134
140
  };
@@ -0,0 +1,8 @@
1
+ import type { ResultAsync } from 'neverthrow';
2
+ import type { ManagedSourceRecordV2, ManagedSourceStoreError, ManagedSourceStorePortV2 } from '../../../ports/managed-source-store.port.js';
3
+ export declare class InMemoryManagedSourceStoreV2 implements ManagedSourceStorePortV2 {
4
+ private readonly sources;
5
+ list(): ResultAsync<readonly ManagedSourceRecordV2[], ManagedSourceStoreError>;
6
+ attach(sourcePath: string): ResultAsync<void, ManagedSourceStoreError>;
7
+ detach(sourcePath: string): ResultAsync<void, ManagedSourceStoreError>;
8
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InMemoryManagedSourceStoreV2 = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const neverthrow_1 = require("neverthrow");
9
+ class InMemoryManagedSourceStoreV2 {
10
+ constructor() {
11
+ this.sources = [];
12
+ }
13
+ list() {
14
+ return (0, neverthrow_1.okAsync)([...this.sources]);
15
+ }
16
+ attach(sourcePath) {
17
+ const normalizedPath = path_1.default.resolve(sourcePath);
18
+ const alreadyPresent = this.sources.some((s) => s.path === normalizedPath);
19
+ if (!alreadyPresent) {
20
+ this.sources.push({ path: normalizedPath, addedAtMs: Date.now() });
21
+ }
22
+ return (0, neverthrow_1.okAsync)(undefined);
23
+ }
24
+ detach(sourcePath) {
25
+ const normalizedPath = path_1.default.resolve(sourcePath);
26
+ const index = this.sources.findIndex((s) => s.path === normalizedPath);
27
+ if (index !== -1) {
28
+ this.sources.splice(index, 1);
29
+ }
30
+ return (0, neverthrow_1.okAsync)(undefined);
31
+ }
32
+ }
33
+ exports.InMemoryManagedSourceStoreV2 = InMemoryManagedSourceStoreV2;
@@ -19,4 +19,6 @@ export declare class LocalDataDirV2 implements DataDirPortV2 {
19
19
  sessionManifestPath(sessionId: SessionId): string;
20
20
  sessionLockPath(sessionId: SessionId): string;
21
21
  tokenIndexPath(): string;
22
+ managedSourcesPath(): string;
23
+ managedSourcesLockPath(): string;
22
24
  }
@@ -89,5 +89,11 @@ class LocalDataDirV2 {
89
89
  tokenIndexPath() {
90
90
  return path.join(this.keysDir(), 'token-index.jsonl');
91
91
  }
92
+ managedSourcesPath() {
93
+ return path.join(this.root(), 'managed-sources', 'managed-sources.json');
94
+ }
95
+ managedSourcesLockPath() {
96
+ return path.join(this.root(), 'managed-sources', 'managed-sources.lock');
97
+ }
92
98
  }
93
99
  exports.LocalDataDirV2 = LocalDataDirV2;
@@ -0,0 +1,15 @@
1
+ import type { ResultAsync } from 'neverthrow';
2
+ import type { DataDirPortV2 } from '../../../ports/data-dir.port.js';
3
+ import type { FileSystemPortV2 } from '../../../ports/fs.port.js';
4
+ import type { ManagedSourceRecordV2, ManagedSourceStoreError, ManagedSourceStorePortV2 } from '../../../ports/managed-source-store.port.js';
5
+ export declare class LocalManagedSourceStoreV2 implements ManagedSourceStorePortV2 {
6
+ private readonly dataDir;
7
+ private readonly fs;
8
+ constructor(dataDir: DataDirPortV2, fs: FileSystemPortV2);
9
+ list(): ResultAsync<readonly ManagedSourceRecordV2[], ManagedSourceStoreError>;
10
+ attach(sourcePath: string): ResultAsync<void, ManagedSourceStoreError>;
11
+ detach(sourcePath: string): ResultAsync<void, ManagedSourceStoreError>;
12
+ private readSources;
13
+ private persist;
14
+ private withLock;
15
+ }
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LocalManagedSourceStoreV2 = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const zod_1 = require("zod");
9
+ const neverthrow_1 = require("neverthrow");
10
+ const MANAGED_SOURCE_LOCK_RETRY_MS = 250;
11
+ const jcs_js_1 = require("../../../durable-core/canonical/jcs.js");
12
+ const ManagedSourceRecordSchema = zod_1.z.object({
13
+ path: zod_1.z.string(),
14
+ addedAtMs: zod_1.z.number().int().nonnegative(),
15
+ });
16
+ const ManagedSourcesFileSchema = zod_1.z.object({
17
+ v: zod_1.z.literal(1),
18
+ sources: zod_1.z.array(ManagedSourceRecordSchema),
19
+ });
20
+ function mapFsToManagedSourceError(e) {
21
+ if (e.code === 'FS_ALREADY_EXISTS') {
22
+ return {
23
+ code: 'MANAGED_SOURCE_BUSY',
24
+ message: 'Managed sources are being updated by another WorkRail process.',
25
+ retry: { kind: 'retryable_after_ms', afterMs: MANAGED_SOURCE_LOCK_RETRY_MS },
26
+ lockPath: 'managed-sources.lock',
27
+ };
28
+ }
29
+ return { code: 'MANAGED_SOURCE_IO_ERROR', message: e.message };
30
+ }
31
+ function normalizeRecords(sources) {
32
+ const seen = new Set();
33
+ const normalized = [];
34
+ for (const source of sources) {
35
+ const normalizedPath = path_1.default.resolve(source.path);
36
+ if (seen.has(normalizedPath))
37
+ continue;
38
+ seen.add(normalizedPath);
39
+ normalized.push({ path: normalizedPath, addedAtMs: source.addedAtMs });
40
+ }
41
+ return normalized;
42
+ }
43
+ class LocalManagedSourceStoreV2 {
44
+ constructor(dataDir, fs) {
45
+ this.dataDir = dataDir;
46
+ this.fs = fs;
47
+ }
48
+ list() {
49
+ return this.readSources();
50
+ }
51
+ attach(sourcePath) {
52
+ const normalizedPath = path_1.default.resolve(sourcePath);
53
+ const nowMs = Date.now();
54
+ return this.withLock(() => this.readSources().andThen((sources) => {
55
+ const alreadyPresent = sources.some((s) => s.path === normalizedPath);
56
+ if (alreadyPresent)
57
+ return (0, neverthrow_1.okAsync)(undefined);
58
+ const next = [...sources, { path: normalizedPath, addedAtMs: nowMs }];
59
+ return this.persist(next);
60
+ }));
61
+ }
62
+ detach(sourcePath) {
63
+ const normalizedPath = path_1.default.resolve(sourcePath);
64
+ return this.withLock(() => this.readSources().andThen((sources) => {
65
+ const next = sources.filter((s) => s.path !== normalizedPath);
66
+ if (next.length === sources.length)
67
+ return (0, neverthrow_1.okAsync)(undefined);
68
+ return this.persist(next);
69
+ }));
70
+ }
71
+ readSources() {
72
+ const filePath = this.dataDir.managedSourcesPath();
73
+ return this.fs.readFileUtf8(filePath)
74
+ .orElse((e) => {
75
+ if (e.code === 'FS_NOT_FOUND')
76
+ return (0, neverthrow_1.okAsync)('');
77
+ return (0, neverthrow_1.errAsync)(mapFsToManagedSourceError(e));
78
+ })
79
+ .andThen((raw) => {
80
+ if (raw === '')
81
+ return (0, neverthrow_1.okAsync)([]);
82
+ let parsed;
83
+ try {
84
+ parsed = JSON.parse(raw);
85
+ }
86
+ catch {
87
+ return (0, neverthrow_1.errAsync)({
88
+ code: 'MANAGED_SOURCE_CORRUPTION',
89
+ message: `Invalid JSON in managed sources file: ${filePath}`,
90
+ });
91
+ }
92
+ const validated = ManagedSourcesFileSchema.safeParse(parsed);
93
+ if (!validated.success) {
94
+ return (0, neverthrow_1.errAsync)({
95
+ code: 'MANAGED_SOURCE_CORRUPTION',
96
+ message: `Managed sources file has invalid shape: ${filePath}`,
97
+ });
98
+ }
99
+ return (0, neverthrow_1.okAsync)(normalizeRecords(validated.data.sources));
100
+ });
101
+ }
102
+ persist(sources) {
103
+ const filePath = this.dataDir.managedSourcesPath();
104
+ const dir = path_1.default.dirname(filePath);
105
+ const tmpPath = `${filePath}.tmp`;
106
+ const fileValue = {
107
+ v: 1,
108
+ sources: [...normalizeRecords(sources)],
109
+ };
110
+ const canonical = (0, jcs_js_1.toCanonicalBytes)(fileValue).mapErr((e) => ({
111
+ code: 'MANAGED_SOURCE_IO_ERROR',
112
+ message: `Failed to canonicalize managed sources state: ${e.message}`,
113
+ }));
114
+ if (canonical.isErr())
115
+ return (0, neverthrow_1.errAsync)(canonical.error);
116
+ const bytes = canonical.value;
117
+ return this.fs.mkdirp(dir)
118
+ .mapErr(mapFsToManagedSourceError)
119
+ .andThen(() => this.fs.openWriteTruncate(tmpPath).mapErr(mapFsToManagedSourceError))
120
+ .andThen(({ fd }) => this.fs.writeAll(fd, bytes)
121
+ .mapErr(mapFsToManagedSourceError)
122
+ .andThen(() => this.fs.fsyncFile(fd).mapErr(mapFsToManagedSourceError))
123
+ .andThen(() => this.fs.closeFile(fd).mapErr(mapFsToManagedSourceError))
124
+ .orElse((e) => this.fs.closeFile(fd)
125
+ .mapErr(() => e)
126
+ .andThen(() => (0, neverthrow_1.errAsync)(e))))
127
+ .andThen(() => this.fs.rename(tmpPath, filePath).mapErr(mapFsToManagedSourceError))
128
+ .andThen(() => this.fs.fsyncDir(dir).mapErr(mapFsToManagedSourceError));
129
+ }
130
+ withLock(run) {
131
+ const lockPath = this.dataDir.managedSourcesLockPath();
132
+ const dir = path_1.default.dirname(lockPath);
133
+ const lockBytes = new TextEncoder().encode(JSON.stringify({ v: 1, pid: process.pid }));
134
+ return this.fs.mkdirp(dir)
135
+ .mapErr(mapFsToManagedSourceError)
136
+ .andThen(() => this.fs.openExclusive(lockPath, lockBytes)
137
+ .mapErr((e) => {
138
+ const mapped = mapFsToManagedSourceError(e);
139
+ if (mapped.code === 'MANAGED_SOURCE_BUSY') {
140
+ return { ...mapped, lockPath };
141
+ }
142
+ return mapped;
143
+ }))
144
+ .andThen(({ fd }) => this.fs.fsyncFile(fd)
145
+ .mapErr(mapFsToManagedSourceError)
146
+ .andThen(() => this.fs.closeFile(fd).mapErr(mapFsToManagedSourceError))
147
+ .andThen(() => run())
148
+ .andThen((value) => this.fs.unlink(lockPath)
149
+ .orElse((e) => {
150
+ if (e.code === 'FS_NOT_FOUND')
151
+ return (0, neverthrow_1.okAsync)(undefined);
152
+ return (0, neverthrow_1.errAsync)(mapFsToManagedSourceError(e));
153
+ })
154
+ .map(() => value))
155
+ .orElse((error) => this.fs.unlink(lockPath)
156
+ .orElse((e) => {
157
+ if (e.code === 'FS_NOT_FOUND')
158
+ return (0, neverthrow_1.okAsync)(undefined);
159
+ return (0, neverthrow_1.errAsync)(mapFsToManagedSourceError(e));
160
+ })
161
+ .andThen(() => (0, neverthrow_1.errAsync)(error))));
162
+ }
163
+ }
164
+ exports.LocalManagedSourceStoreV2 = LocalManagedSourceStoreV2;
@@ -14,4 +14,6 @@ export interface DataDirPortV2 {
14
14
  sessionManifestPath(sessionId: SessionId): string;
15
15
  sessionLockPath(sessionId: SessionId): string;
16
16
  tokenIndexPath(): string;
17
+ managedSourcesPath(): string;
18
+ managedSourcesLockPath(): string;
17
19
  }
@@ -0,0 +1,25 @@
1
+ import type { ResultAsync } from 'neverthrow';
2
+ export type ManagedSourceStoreError = {
3
+ readonly code: 'MANAGED_SOURCE_BUSY';
4
+ readonly message: string;
5
+ readonly retry: {
6
+ readonly kind: 'retryable_after_ms';
7
+ readonly afterMs: number;
8
+ };
9
+ readonly lockPath: string;
10
+ } | {
11
+ readonly code: 'MANAGED_SOURCE_IO_ERROR';
12
+ readonly message: string;
13
+ } | {
14
+ readonly code: 'MANAGED_SOURCE_CORRUPTION';
15
+ readonly message: string;
16
+ };
17
+ export interface ManagedSourceRecordV2 {
18
+ readonly path: string;
19
+ readonly addedAtMs: number;
20
+ }
21
+ export interface ManagedSourceStorePortV2 {
22
+ list(): ResultAsync<readonly ManagedSourceRecordV2[], ManagedSourceStoreError>;
23
+ attach(path: string): ResultAsync<void, ManagedSourceStoreError>;
24
+ detach(path: string): ResultAsync<void, ManagedSourceStoreError>;
25
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exaudeus/workrail",
3
- "version": "3.12.0",
3
+ "version": "3.13.0",
4
4
  "description": "Step-by-step workflow enforcement for AI agents via MCP",
5
5
  "license": "MIT",
6
6
  "repository": {