@exaudeus/workrail 3.16.0 → 3.17.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.
- package/dist/application/use-cases/raw-workflow-file-scanner.js +10 -13
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.js +72 -0
- package/dist/cli.js +13 -1
- package/dist/config/config-file.d.ts +8 -0
- package/dist/config/config-file.js +141 -0
- package/dist/config/feature-flags.js +8 -0
- package/dist/console/assets/index-BwJelCXK.js +28 -0
- package/dist/console/index.html +1 -1
- package/dist/di/container.d.ts +1 -0
- package/dist/di/container.js +24 -7
- package/dist/infrastructure/session/HttpServer.d.ts +0 -1
- package/dist/infrastructure/session/HttpServer.js +4 -46
- package/dist/manifest.json +101 -109
- package/dist/mcp/assert-output.js +2 -1
- package/dist/mcp/dev-mode.d.ts +1 -0
- package/dist/mcp/dev-mode.js +12 -0
- package/dist/mcp/handler-factory.d.ts +1 -1
- package/dist/mcp/handler-factory.js +8 -7
- package/dist/mcp/handlers/shared/request-workflow-reader.d.ts +1 -0
- package/dist/mcp/handlers/shared/request-workflow-reader.js +90 -20
- package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.js +3 -1
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +2 -1
- package/dist/mcp/handlers/v2-execution/index.js +2 -0
- package/dist/mcp/handlers/v2-execution/replay.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/replay.js +3 -0
- package/dist/mcp/handlers/v2-execution/start.js +48 -20
- package/dist/mcp/handlers/v2-workflow.js +4 -2
- package/dist/mcp/output-schemas.d.ts +5 -0
- package/dist/mcp/output-schemas.js +2 -0
- package/dist/mcp/server.js +3 -2
- package/dist/mcp/v2-response-formatter.d.ts +1 -1
- package/dist/mcp/v2-response-formatter.js +2 -3
- package/dist/types/workflow-definition.d.ts +3 -1
- package/dist/types/workflow-definition.js +2 -0
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +1 -2
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +4 -3
- package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +2 -0
- package/dist/v2/infra/local/pinned-workflow-store/index.js +49 -0
- package/dist/v2/infra/local/remembered-roots-store/index.d.ts +3 -1
- package/dist/v2/infra/local/remembered-roots-store/index.js +6 -3
- package/dist/v2/infra/local/workspace-anchor/index.js +4 -2
- package/dist/v2/ports/pinned-workflow-store.port.d.ts +2 -0
- package/dist/v2/usecases/console-routes.js +3 -2
- package/package.json +1 -1
- package/dist/console/assets/index-BE5PAgPO.js +0 -28
- package/dist/env-flags.d.ts +0 -1
- package/dist/env-flags.js +0 -4
- package/dist/mcp/handlers/v2-resolve-refs-envelope.d.ts +0 -5
- package/dist/mcp/handlers/v2-resolve-refs-envelope.js +0 -17
|
@@ -110,13 +110,15 @@ export interface WorkflowRecommendedPreferences {
|
|
|
110
110
|
readonly recommendedAutonomy?: 'guided' | 'full_auto_stop_on_user_deps' | 'full_auto_never_stop';
|
|
111
111
|
readonly recommendedRiskPolicy?: 'conservative' | 'balanced' | 'aggressive';
|
|
112
112
|
}
|
|
113
|
+
export declare const RESOLVE_FROM_VALUES: readonly ["workspace", "package"];
|
|
114
|
+
export type ResolveFrom = typeof RESOLVE_FROM_VALUES[number];
|
|
113
115
|
export interface WorkflowReference {
|
|
114
116
|
readonly id: string;
|
|
115
117
|
readonly title: string;
|
|
116
118
|
readonly source: string;
|
|
117
119
|
readonly purpose: string;
|
|
118
120
|
readonly authoritative: boolean;
|
|
119
|
-
readonly resolveFrom?:
|
|
121
|
+
readonly resolveFrom?: ResolveFrom;
|
|
120
122
|
}
|
|
121
123
|
export interface WorkflowDefinition {
|
|
122
124
|
readonly id: string;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESOLVE_FROM_VALUES = void 0;
|
|
3
4
|
exports.isLoopStepDefinition = isLoopStepDefinition;
|
|
4
5
|
exports.isWorkflowStepDefinition = isWorkflowStepDefinition;
|
|
5
6
|
exports.stepHasPromptSource = stepHasPromptSource;
|
|
6
7
|
exports.hasWorkflowDefinitionShape = hasWorkflowDefinitionShape;
|
|
7
8
|
exports.createWorkflowDefinition = createWorkflowDefinition;
|
|
9
|
+
exports.RESOLVE_FROM_VALUES = ['workspace', 'package'];
|
|
8
10
|
function isLoopStepDefinition(step) {
|
|
9
11
|
return 'type' in step && step.type === 'loop';
|
|
10
12
|
}
|
|
@@ -25,4 +25,5 @@ export declare function renderPendingPrompt(args: {
|
|
|
25
25
|
readonly nodeId: NodeId;
|
|
26
26
|
readonly rehydrateOnly: boolean;
|
|
27
27
|
readonly precomputedIndex?: import('../session-index.js').SessionIndex;
|
|
28
|
+
readonly cleanResponseFormat?: boolean;
|
|
28
29
|
}): Result<StepMetadata, PromptRenderError>;
|
|
@@ -17,7 +17,6 @@ const sorted_event_log_js_1 = require("../sorted-event-log.js");
|
|
|
17
17
|
const condition_evaluator_js_1 = require("../../../utils/condition-evaluator.js");
|
|
18
18
|
const context_template_resolver_js_1 = require("./context-template-resolver.js");
|
|
19
19
|
const retrieval_contract_js_1 = require("./retrieval-contract.js");
|
|
20
|
-
const env_flags_js_1 = require("../../../env-flags.js");
|
|
21
20
|
function buildNonTipSegments(args) {
|
|
22
21
|
const segments = [];
|
|
23
22
|
const childSummary = (0, recap_recovery_js_1.buildChildSummary)({ nodeId: args.nodeId, dag: args.run });
|
|
@@ -246,7 +245,7 @@ function renderPendingPrompt(args) {
|
|
|
246
245
|
const renderContext = { ...sessionContext, ...loopRenderContext };
|
|
247
246
|
const basePrompt = (0, context_template_resolver_js_1.resolveContextTemplates)(step.prompt ?? '', renderContext);
|
|
248
247
|
const baseTitle = (0, context_template_resolver_js_1.resolveContextTemplates)(step.title, renderContext);
|
|
249
|
-
const cleanResponseFormat =
|
|
248
|
+
const cleanResponseFormat = args.cleanResponseFormat ?? false;
|
|
250
249
|
const loopBanner = buildLoopContextBanner({ loopPath: args.loopPath, isExitStep, maxIterations, cleanFormat: cleanResponseFormat });
|
|
251
250
|
const validationCriteria = step.validationCriteria;
|
|
252
251
|
const requirements = (0, validation_requirements_extractor_js_1.extractValidationRequirements)(validationCriteria);
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CompiledWorkflowSnapshotSchema = exports.CompiledWorkflowSnapshotV1Schema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const json_zod_js_1 = require("../../canonical/json-zod.js");
|
|
6
|
+
const workflow_definition_js_1 = require("../../../../types/workflow-definition.js");
|
|
6
7
|
const CompiledWorkflowSnapshotV1PreviewSchema = zod_1.z.object({
|
|
7
8
|
schemaVersion: zod_1.z.literal(1),
|
|
8
9
|
sourceKind: zod_1.z.literal('v1_preview'),
|
|
@@ -33,7 +34,7 @@ const CompiledWorkflowSnapshotV1PinnedSchema = zod_1.z.object({
|
|
|
33
34
|
source: zod_1.z.string().min(1),
|
|
34
35
|
purpose: zod_1.z.string().min(1),
|
|
35
36
|
authoritative: zod_1.z.boolean(),
|
|
36
|
-
resolveFrom: zod_1.z.enum(
|
|
37
|
+
resolveFrom: zod_1.z.enum(workflow_definition_js_1.RESOLVE_FROM_VALUES),
|
|
37
38
|
status: zod_1.z.literal('resolved'),
|
|
38
39
|
resolvedPath: zod_1.z.string().min(1),
|
|
39
40
|
}),
|
|
@@ -43,7 +44,7 @@ const CompiledWorkflowSnapshotV1PinnedSchema = zod_1.z.object({
|
|
|
43
44
|
source: zod_1.z.string().min(1),
|
|
44
45
|
purpose: zod_1.z.string().min(1),
|
|
45
46
|
authoritative: zod_1.z.boolean(),
|
|
46
|
-
resolveFrom: zod_1.z.enum(
|
|
47
|
+
resolveFrom: zod_1.z.enum(workflow_definition_js_1.RESOLVE_FROM_VALUES),
|
|
47
48
|
status: zod_1.z.literal('unresolved'),
|
|
48
49
|
}),
|
|
49
50
|
zod_1.z.object({
|
|
@@ -52,7 +53,7 @@ const CompiledWorkflowSnapshotV1PinnedSchema = zod_1.z.object({
|
|
|
52
53
|
source: zod_1.z.string().min(1),
|
|
53
54
|
purpose: zod_1.z.string().min(1),
|
|
54
55
|
authoritative: zod_1.z.boolean(),
|
|
55
|
-
resolveFrom: zod_1.z.enum(
|
|
56
|
+
resolveFrom: zod_1.z.enum(workflow_definition_js_1.RESOLVE_FROM_VALUES),
|
|
56
57
|
status: zod_1.z.literal('pinned'),
|
|
57
58
|
}),
|
|
58
59
|
])).optional(),
|
|
@@ -9,5 +9,7 @@ export declare class LocalPinnedWorkflowStoreV2 implements PinnedWorkflowStorePo
|
|
|
9
9
|
private readonly fs;
|
|
10
10
|
constructor(dataDir: DataDirPortV2, fs: FileSystemPortV2);
|
|
11
11
|
get(workflowHash: WorkflowHash): ResultAsync<CompiledWorkflowSnapshot | null, PinnedWorkflowStoreError>;
|
|
12
|
+
list(): ResultAsync<readonly WorkflowHash[], PinnedWorkflowStoreError>;
|
|
13
|
+
prune(_olderThanMs: number): ResultAsync<number, PinnedWorkflowStoreError>;
|
|
12
14
|
put(workflowHash: WorkflowHash, compiled: CompiledWorkflowSnapshot): ResultAsync<void, PinnedWorkflowStoreError>;
|
|
13
15
|
}
|
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.LocalPinnedWorkflowStoreV2 = void 0;
|
|
37
|
+
const nodePath = __importStar(require("node:path"));
|
|
4
38
|
const neverthrow_1 = require("neverthrow");
|
|
5
39
|
const index_js_1 = require("../../../durable-core/schemas/compiled-workflow/index.js");
|
|
6
40
|
const jcs_js_1 = require("../../../durable-core/canonical/jcs.js");
|
|
@@ -43,6 +77,21 @@ class LocalPinnedWorkflowStoreV2 {
|
|
|
43
77
|
return (0, neverthrow_1.okAsync)(validated.data);
|
|
44
78
|
});
|
|
45
79
|
}
|
|
80
|
+
list() {
|
|
81
|
+
const dir = this.dataDir.pinnedWorkflowsDir();
|
|
82
|
+
return this.fs.readdir(dir)
|
|
83
|
+
.orElse((e) => {
|
|
84
|
+
if (e.code === 'FS_NOT_FOUND')
|
|
85
|
+
return (0, neverthrow_1.okAsync)([]);
|
|
86
|
+
return (0, neverthrow_1.errAsync)(mapFsToStoreError(e));
|
|
87
|
+
})
|
|
88
|
+
.map((entries) => entries
|
|
89
|
+
.filter((name) => name.endsWith('.json') && !name.endsWith('.tmp'))
|
|
90
|
+
.map((name) => nodePath.basename(name, '.json')));
|
|
91
|
+
}
|
|
92
|
+
prune(_olderThanMs) {
|
|
93
|
+
return (0, neverthrow_1.okAsync)(0);
|
|
94
|
+
}
|
|
46
95
|
put(workflowHash, compiled) {
|
|
47
96
|
const dir = this.dataDir.pinnedWorkflowsDir();
|
|
48
97
|
const filePath = this.dataDir.pinnedWorkflowPath(workflowHash);
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { ResultAsync } from 'neverthrow';
|
|
2
2
|
import type { DataDirPortV2 } from '../../../ports/data-dir.port.js';
|
|
3
3
|
import type { FileSystemPortV2 } from '../../../ports/fs.port.js';
|
|
4
|
+
import type { TimeClockPortV2 } from '../../../ports/time-clock.port.js';
|
|
4
5
|
import type { RememberedRootRecordV2, RememberedRootsStoreError, RememberedRootsStorePortV2 } from '../../../ports/remembered-roots-store.port.js';
|
|
5
6
|
export declare class LocalRememberedRootsStoreV2 implements RememberedRootsStorePortV2 {
|
|
6
7
|
private readonly dataDir;
|
|
7
8
|
private readonly fs;
|
|
8
|
-
|
|
9
|
+
private readonly clock;
|
|
10
|
+
constructor(dataDir: DataDirPortV2, fs: FileSystemPortV2, clock: TimeClockPortV2);
|
|
9
11
|
listRoots(): ResultAsync<readonly string[], RememberedRootsStoreError>;
|
|
10
12
|
listRootRecords(): ResultAsync<readonly RememberedRootRecordV2[], RememberedRootsStoreError>;
|
|
11
13
|
rememberRoot(rootPath: string): ResultAsync<void, RememberedRootsStoreError>;
|
|
@@ -9,6 +9,7 @@ const zod_1 = require("zod");
|
|
|
9
9
|
const neverthrow_1 = require("neverthrow");
|
|
10
10
|
const jcs_js_1 = require("../../../durable-core/canonical/jcs.js");
|
|
11
11
|
const REMEMBERED_ROOTS_LOCK_RETRY_MS = 250;
|
|
12
|
+
const TTL_30_DAYS_MS = 30 * 24 * 60 * 60 * 1000;
|
|
12
13
|
const RememberedRootRecordSchema = zod_1.z.object({
|
|
13
14
|
path: zod_1.z.string(),
|
|
14
15
|
addedAtMs: zod_1.z.number().int().nonnegative(),
|
|
@@ -48,9 +49,10 @@ function normalizeRootRecords(roots) {
|
|
|
48
49
|
return normalized;
|
|
49
50
|
}
|
|
50
51
|
class LocalRememberedRootsStoreV2 {
|
|
51
|
-
constructor(dataDir, fs) {
|
|
52
|
+
constructor(dataDir, fs, clock) {
|
|
52
53
|
this.dataDir = dataDir;
|
|
53
54
|
this.fs = fs;
|
|
55
|
+
this.clock = clock;
|
|
54
56
|
}
|
|
55
57
|
listRoots() {
|
|
56
58
|
return this.listRootRecords().map((roots) => roots.map((root) => root.path));
|
|
@@ -88,7 +90,7 @@ class LocalRememberedRootsStoreV2 {
|
|
|
88
90
|
}
|
|
89
91
|
rememberRoot(rootPath) {
|
|
90
92
|
const normalizedRoot = path_1.default.resolve(rootPath);
|
|
91
|
-
const nowMs =
|
|
93
|
+
const nowMs = this.clock.nowMs();
|
|
92
94
|
return this.withLock(() => this.listRootRecords().andThen((roots) => {
|
|
93
95
|
const existing = roots.find((root) => root.path === normalizedRoot);
|
|
94
96
|
const nextRoots = existing
|
|
@@ -104,7 +106,8 @@ class LocalRememberedRootsStoreV2 {
|
|
|
104
106
|
source: 'explicit_workspace_path',
|
|
105
107
|
},
|
|
106
108
|
];
|
|
107
|
-
|
|
109
|
+
const withEviction = nextRoots.filter((r) => r.lastSeenAtMs >= nowMs - TTL_30_DAYS_MS);
|
|
110
|
+
return this.persist(withEviction);
|
|
108
111
|
}));
|
|
109
112
|
}
|
|
110
113
|
persist(roots) {
|
|
@@ -44,11 +44,13 @@ class LocalWorkspaceAnchorV2 {
|
|
|
44
44
|
anchors.push({ key: 'repo_root_hash', value: repoRootHash });
|
|
45
45
|
}
|
|
46
46
|
anchors.push({ key: 'repo_root', value: repoRoot });
|
|
47
|
-
const branch = await
|
|
47
|
+
const [branch, sha] = await Promise.all([
|
|
48
|
+
this.gitCommand('git rev-parse --abbrev-ref HEAD', cwd),
|
|
49
|
+
this.gitCommand('git rev-parse HEAD', cwd),
|
|
50
|
+
]);
|
|
48
51
|
if (branch && branch !== 'HEAD') {
|
|
49
52
|
anchors.push({ key: 'git_branch', value: branch });
|
|
50
53
|
}
|
|
51
|
-
const sha = await this.gitCommand('git rev-parse HEAD', cwd);
|
|
52
54
|
if (sha && /^[0-9a-f]{40}$/.test(sha)) {
|
|
53
55
|
anchors.push({ key: 'git_head_sha', value: sha });
|
|
54
56
|
}
|
|
@@ -8,4 +8,6 @@ export type PinnedWorkflowStoreError = {
|
|
|
8
8
|
export interface PinnedWorkflowStorePortV2 {
|
|
9
9
|
get(workflowHash: WorkflowHash): ResultAsync<CompiledWorkflowSnapshot | null, PinnedWorkflowStoreError>;
|
|
10
10
|
put(workflowHash: WorkflowHash, compiled: CompiledWorkflowSnapshot): ResultAsync<void, PinnedWorkflowStoreError>;
|
|
11
|
+
list(): ResultAsync<readonly WorkflowHash[], PinnedWorkflowStoreError>;
|
|
12
|
+
prune(olderThanMs: number): ResultAsync<number, PinnedWorkflowStoreError>;
|
|
11
13
|
}
|
|
@@ -82,13 +82,14 @@ function mountConsoleRoutes(app, consoleService, workflowService, timingRingBuff
|
|
|
82
82
|
req.on('close', () => { sseClients.delete(res); });
|
|
83
83
|
res.on('close', () => { sseClients.delete(res); });
|
|
84
84
|
});
|
|
85
|
-
|
|
85
|
+
const devMode = (0, dev_mode_js_1.isDevMode)();
|
|
86
|
+
if (devMode) {
|
|
86
87
|
app.get('/api/v2/perf/tool-calls', (req, res) => {
|
|
87
88
|
const rawLimit = req.query['limit'];
|
|
88
89
|
const limit = typeof rawLimit === 'string' ? parseInt(rawLimit, 10) : undefined;
|
|
89
90
|
const safeLimit = (limit !== undefined && Number.isFinite(limit) && limit > 0) ? limit : undefined;
|
|
90
91
|
const observations = timingRingBuffer ? timingRingBuffer.recent(safeLimit) : [];
|
|
91
|
-
res.json({ success: true, data: { observations, total: timingRingBuffer?.size ?? 0, devMode
|
|
92
|
+
res.json({ success: true, data: { observations, total: timingRingBuffer?.size ?? 0, devMode } });
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
95
|
app.get('/api/v2/sessions', async (_req, res) => {
|