@exaudeus/workrail 3.11.1 → 3.12.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/console/assets/index-CRgjJiMS.js +28 -0
- package/dist/console/assets/index-DW78t31j.css +1 -0
- package/dist/console/index.html +2 -2
- package/dist/manifest.json +67 -59
- package/dist/mcp/handlers/shared/request-workflow-reader.d.ts +10 -2
- package/dist/mcp/handlers/shared/request-workflow-reader.js +27 -10
- package/dist/mcp/handlers/shared/workflow-source-visibility.d.ts +3 -1
- package/dist/mcp/handlers/shared/workflow-source-visibility.js +7 -3
- package/dist/mcp/handlers/v2-execution/replay.js +25 -1
- package/dist/mcp/handlers/v2-execution/start.js +23 -17
- package/dist/mcp/handlers/v2-workflow.js +123 -8
- package/dist/mcp/output-schemas.d.ts +393 -0
- package/dist/mcp/output-schemas.js +49 -1
- package/dist/mcp/tools.js +5 -5
- package/dist/mcp/v2/tools.d.ts +3 -0
- package/dist/mcp/v2/tools.js +3 -2
- package/dist/v2/durable-core/constants.d.ts +1 -0
- package/dist/v2/durable-core/constants.js +2 -1
- package/dist/v2/durable-core/domain/observation-builder.d.ts +4 -1
- package/dist/v2/durable-core/domain/observation-builder.js +9 -0
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +76 -16
- package/dist/v2/durable-core/schemas/session/events.d.ts +26 -5
- package/dist/v2/durable-core/schemas/session/events.js +2 -1
- package/dist/v2/infra/local/session-summary-provider/index.js +2 -0
- package/dist/v2/infra/local/workspace-anchor/index.js +1 -0
- package/dist/v2/ports/workspace-anchor.port.d.ts +3 -0
- package/dist/v2/projections/resume-ranking.d.ts +1 -0
- package/dist/v2/usecases/console-routes.js +26 -0
- package/dist/v2/usecases/console-service.js +25 -6
- package/dist/v2/usecases/console-types.d.ts +22 -1
- package/dist/v2/usecases/worktree-service.d.ts +10 -0
- package/dist/v2/usecases/worktree-service.js +136 -0
- package/package.json +1 -1
- package/workflows/architecture-scalability-audit.json +317 -0
- package/workflows/routines/tension-driven-design.json +5 -5
- package/dist/console/assets/index-C5C4nDs4.css +0 -1
- package/dist/console/assets/index-CSUqsoQl.js +0 -28
package/dist/mcp/v2/tools.js
CHANGED
|
@@ -16,14 +16,15 @@ const workspacePathField = zod_1.z.string()
|
|
|
16
16
|
const optionalWorkspacePathField = workspacePathField.optional();
|
|
17
17
|
exports.V2ListWorkflowsInput = zod_1.z.object({
|
|
18
18
|
workspacePath: workspacePathField.describe('Required. Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). WorkRail uses this to resolve project-scoped workflow variants against the correct workspace for discovery-sensitive workflow listing. Shared MCP servers cannot infer this safely.'),
|
|
19
|
+
includeSources: zod_1.z.boolean().optional().describe('When true, includes a source catalog in the response showing where workflows come from (built-in, project-scoped, rooted-sharing, external), with effective and shadowed workflow counts per source. Omit or set false for the default workflow-list-only response.'),
|
|
19
20
|
});
|
|
20
21
|
exports.V2InspectWorkflowInput = zod_1.z.object({
|
|
21
|
-
workflowId: zod_1.z.string().min(1).regex(/^[
|
|
22
|
+
workflowId: zod_1.z.string().min(1).regex(/^([a-z0-9_-]+|[a-z][a-z0-9_-]+\.[a-z][a-z0-9_-]+)$/, 'Workflow ID must be a valid legacy ID (e.g. my-workflow) or namespaced ID (e.g. wr.discovery)').describe('The workflow ID to inspect'),
|
|
22
23
|
mode: zod_1.z.enum(['metadata', 'preview']).default('preview').describe('Detail level: metadata (name and description only) or preview (full step-by-step breakdown, default)'),
|
|
23
24
|
workspacePath: workspacePathField.describe('Required. Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). WorkRail uses this to resolve the correct project-scoped workflow variant for discovery-sensitive workflow inspection. Shared MCP servers cannot infer this safely.'),
|
|
24
25
|
});
|
|
25
26
|
exports.V2StartWorkflowInput = zod_1.z.object({
|
|
26
|
-
workflowId: zod_1.z.string().min(1).regex(/^[
|
|
27
|
+
workflowId: zod_1.z.string().min(1).regex(/^([a-z0-9_-]+|[a-z][a-z0-9_-]+\.[a-z][a-z0-9_-]+)$/, 'Workflow ID must be a valid legacy ID (e.g. my-workflow) or namespaced ID (e.g. wr.discovery)').describe('The workflow ID to start'),
|
|
27
28
|
workspacePath: workspacePathField.describe('Required. Absolute path to your current workspace directory (e.g. the "Workspace:" value from your system parameters). WorkRail uses this to resolve the correct project-scoped workflow variant and to anchor the session to the correct repo for future resume_session discovery. Shared MCP servers cannot infer this safely.'),
|
|
28
29
|
});
|
|
29
30
|
exports.V2ContinueWorkflowInputShape = zod_1.z.object({
|
|
@@ -12,6 +12,7 @@ export declare const MAX_VALIDATION_SUGGESTIONS_BYTES = 4096;
|
|
|
12
12
|
export declare const MAX_CONTEXT_BYTES: number;
|
|
13
13
|
export declare const MAX_CONTEXT_DEPTH = 64;
|
|
14
14
|
export declare const MAX_OBSERVATION_SHORT_STRING_LENGTH = 80;
|
|
15
|
+
export declare const MAX_OBSERVATION_PATH_LENGTH = 512;
|
|
15
16
|
export declare const SESSION_LOCK_RETRY_AFTER_MS = 1000;
|
|
16
17
|
export declare const DEFAULT_RETRY_AFTER_MS = 1000;
|
|
17
18
|
export declare const TRUNCATION_MARKER = "\n\n[TRUNCATED]";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AUTONOMY_MODE = exports.ADVANCE_INTENT = exports.MANIFEST_KIND = exports.EDGE_CAUSE = exports.ADVANCE_OUTCOME = exports.ENGINE_STATE = exports.EDGE_KIND = exports.PAYLOAD_KIND = exports.OUTPUT_CHANNEL = exports.EVENT_KIND = exports.DELIMITER_SAFE_ID_PATTERN = exports.SHA256_DIGEST_PATTERN = exports.MAX_RESUME_PREVIEW_BYTES = exports.RECOVERY_BUDGET_BYTES = exports.TRUNCATION_MARKER = exports.DEFAULT_RETRY_AFTER_MS = exports.SESSION_LOCK_RETRY_AFTER_MS = exports.MAX_OBSERVATION_SHORT_STRING_LENGTH = exports.MAX_CONTEXT_DEPTH = exports.MAX_CONTEXT_BYTES = exports.MAX_VALIDATION_SUGGESTIONS_BYTES = exports.MAX_VALIDATION_ISSUES_BYTES = exports.MAX_VALIDATION_SUGGESTION_ITEM_BYTES = exports.MAX_VALIDATION_ISSUE_ITEM_BYTES = exports.MAX_OUTPUT_NOTES_MARKDOWN_BYTES = exports.MAX_DECISION_TRACE_TOTAL_BYTES = exports.MAX_DECISION_TRACE_ENTRY_SUMMARY_BYTES = exports.MAX_DECISION_TRACE_ENTRIES = exports.MAX_BLOCKER_SUGGESTED_FIX_BYTES = exports.MAX_BLOCKER_MESSAGE_BYTES = exports.MAX_BLOCKERS = void 0;
|
|
3
|
+
exports.AUTONOMY_MODE = exports.ADVANCE_INTENT = exports.MANIFEST_KIND = exports.EDGE_CAUSE = exports.ADVANCE_OUTCOME = exports.ENGINE_STATE = exports.EDGE_KIND = exports.PAYLOAD_KIND = exports.OUTPUT_CHANNEL = exports.EVENT_KIND = exports.DELIMITER_SAFE_ID_PATTERN = exports.SHA256_DIGEST_PATTERN = exports.MAX_RESUME_PREVIEW_BYTES = exports.RECOVERY_BUDGET_BYTES = exports.TRUNCATION_MARKER = exports.DEFAULT_RETRY_AFTER_MS = exports.SESSION_LOCK_RETRY_AFTER_MS = exports.MAX_OBSERVATION_PATH_LENGTH = exports.MAX_OBSERVATION_SHORT_STRING_LENGTH = exports.MAX_CONTEXT_DEPTH = exports.MAX_CONTEXT_BYTES = exports.MAX_VALIDATION_SUGGESTIONS_BYTES = exports.MAX_VALIDATION_ISSUES_BYTES = exports.MAX_VALIDATION_SUGGESTION_ITEM_BYTES = exports.MAX_VALIDATION_ISSUE_ITEM_BYTES = exports.MAX_OUTPUT_NOTES_MARKDOWN_BYTES = exports.MAX_DECISION_TRACE_TOTAL_BYTES = exports.MAX_DECISION_TRACE_ENTRY_SUMMARY_BYTES = exports.MAX_DECISION_TRACE_ENTRIES = exports.MAX_BLOCKER_SUGGESTED_FIX_BYTES = exports.MAX_BLOCKER_MESSAGE_BYTES = exports.MAX_BLOCKERS = void 0;
|
|
4
4
|
exports.MAX_BLOCKERS = 10;
|
|
5
5
|
exports.MAX_BLOCKER_MESSAGE_BYTES = 512;
|
|
6
6
|
exports.MAX_BLOCKER_SUGGESTED_FIX_BYTES = 1024;
|
|
@@ -15,6 +15,7 @@ exports.MAX_VALIDATION_SUGGESTIONS_BYTES = 4096;
|
|
|
15
15
|
exports.MAX_CONTEXT_BYTES = 256 * 1024;
|
|
16
16
|
exports.MAX_CONTEXT_DEPTH = 64;
|
|
17
17
|
exports.MAX_OBSERVATION_SHORT_STRING_LENGTH = 80;
|
|
18
|
+
exports.MAX_OBSERVATION_PATH_LENGTH = 512;
|
|
18
19
|
exports.SESSION_LOCK_RETRY_AFTER_MS = 1000;
|
|
19
20
|
exports.DEFAULT_RETRY_AFTER_MS = 1000;
|
|
20
21
|
exports.TRUNCATION_MARKER = '\n\n[TRUNCATED]';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { WorkspaceAnchor } from '../../ports/workspace-anchor.port.js';
|
|
2
2
|
export interface ObservationEventData {
|
|
3
|
-
readonly key: 'git_branch' | 'git_head_sha' | 'repo_root_hash';
|
|
3
|
+
readonly key: 'git_branch' | 'git_head_sha' | 'repo_root_hash' | 'repo_root';
|
|
4
4
|
readonly value: {
|
|
5
5
|
readonly type: 'short_string';
|
|
6
6
|
readonly value: string;
|
|
@@ -10,6 +10,9 @@ export interface ObservationEventData {
|
|
|
10
10
|
} | {
|
|
11
11
|
readonly type: 'sha256';
|
|
12
12
|
readonly value: string;
|
|
13
|
+
} | {
|
|
14
|
+
readonly type: 'path';
|
|
15
|
+
readonly value: string;
|
|
13
16
|
};
|
|
14
17
|
readonly confidence: 'low' | 'med' | 'high';
|
|
15
18
|
}
|
|
@@ -33,6 +33,15 @@ function anchorsToObservations(anchors) {
|
|
|
33
33
|
confidence: 'high',
|
|
34
34
|
});
|
|
35
35
|
break;
|
|
36
|
+
case 'repo_root':
|
|
37
|
+
if (anchor.value.length > constants_js_1.MAX_OBSERVATION_PATH_LENGTH)
|
|
38
|
+
break;
|
|
39
|
+
observations.push({
|
|
40
|
+
key: 'repo_root',
|
|
41
|
+
value: { type: 'path', value: anchor.value },
|
|
42
|
+
confidence: 'high',
|
|
43
|
+
});
|
|
44
|
+
break;
|
|
36
45
|
default: {
|
|
37
46
|
const _exhaustive = anchor;
|
|
38
47
|
return _exhaustive;
|
|
@@ -110,7 +110,7 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
110
110
|
kind: z.ZodLiteral<"observation_recorded">;
|
|
111
111
|
scope: z.ZodUndefined;
|
|
112
112
|
data: z.ZodObject<{
|
|
113
|
-
key: z.ZodEnum<["git_branch", "git_head_sha", "repo_root_hash"]>;
|
|
113
|
+
key: z.ZodEnum<["git_branch", "git_head_sha", "repo_root_hash", "repo_root"]>;
|
|
114
114
|
value: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
115
115
|
type: z.ZodLiteral<"short_string">;
|
|
116
116
|
value: z.ZodString;
|
|
@@ -138,6 +138,15 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
138
138
|
}, {
|
|
139
139
|
value: string;
|
|
140
140
|
type: "sha256";
|
|
141
|
+
}>, z.ZodObject<{
|
|
142
|
+
type: z.ZodLiteral<"path">;
|
|
143
|
+
value: z.ZodString;
|
|
144
|
+
}, "strip", z.ZodTypeAny, {
|
|
145
|
+
value: string;
|
|
146
|
+
type: "path";
|
|
147
|
+
}, {
|
|
148
|
+
value: string;
|
|
149
|
+
type: "path";
|
|
141
150
|
}>]>;
|
|
142
151
|
confidence: z.ZodEnum<["low", "med", "high"]>;
|
|
143
152
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -150,8 +159,11 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
150
159
|
} | {
|
|
151
160
|
value: string;
|
|
152
161
|
type: "sha256";
|
|
162
|
+
} | {
|
|
163
|
+
value: string;
|
|
164
|
+
type: "path";
|
|
153
165
|
};
|
|
154
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
166
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
155
167
|
confidence: "high" | "low" | "med";
|
|
156
168
|
}, {
|
|
157
169
|
value: {
|
|
@@ -163,8 +175,11 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
163
175
|
} | {
|
|
164
176
|
value: string;
|
|
165
177
|
type: "sha256";
|
|
178
|
+
} | {
|
|
179
|
+
value: string;
|
|
180
|
+
type: "path";
|
|
166
181
|
};
|
|
167
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
182
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
168
183
|
confidence: "high" | "low" | "med";
|
|
169
184
|
}>;
|
|
170
185
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -180,8 +195,11 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
180
195
|
} | {
|
|
181
196
|
value: string;
|
|
182
197
|
type: "sha256";
|
|
198
|
+
} | {
|
|
199
|
+
value: string;
|
|
200
|
+
type: "path";
|
|
183
201
|
};
|
|
184
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
202
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
185
203
|
confidence: "high" | "low" | "med";
|
|
186
204
|
};
|
|
187
205
|
v: 1;
|
|
@@ -202,8 +220,11 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
202
220
|
} | {
|
|
203
221
|
value: string;
|
|
204
222
|
type: "sha256";
|
|
223
|
+
} | {
|
|
224
|
+
value: string;
|
|
225
|
+
type: "path";
|
|
205
226
|
};
|
|
206
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
227
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
207
228
|
confidence: "high" | "low" | "med";
|
|
208
229
|
};
|
|
209
230
|
v: 1;
|
|
@@ -4727,8 +4748,11 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
4727
4748
|
} | {
|
|
4728
4749
|
value: string;
|
|
4729
4750
|
type: "sha256";
|
|
4751
|
+
} | {
|
|
4752
|
+
value: string;
|
|
4753
|
+
type: "path";
|
|
4730
4754
|
};
|
|
4731
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
4755
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
4732
4756
|
confidence: "high" | "low" | "med";
|
|
4733
4757
|
};
|
|
4734
4758
|
v: 1;
|
|
@@ -5300,8 +5324,11 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
|
|
|
5300
5324
|
} | {
|
|
5301
5325
|
value: string;
|
|
5302
5326
|
type: "sha256";
|
|
5327
|
+
} | {
|
|
5328
|
+
value: string;
|
|
5329
|
+
type: "path";
|
|
5303
5330
|
};
|
|
5304
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
5331
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
5305
5332
|
confidence: "high" | "low" | "med";
|
|
5306
5333
|
};
|
|
5307
5334
|
v: 1;
|
|
@@ -5791,7 +5818,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
5791
5818
|
kind: z.ZodLiteral<"observation_recorded">;
|
|
5792
5819
|
scope: z.ZodUndefined;
|
|
5793
5820
|
data: z.ZodObject<{
|
|
5794
|
-
key: z.ZodEnum<["git_branch", "git_head_sha", "repo_root_hash"]>;
|
|
5821
|
+
key: z.ZodEnum<["git_branch", "git_head_sha", "repo_root_hash", "repo_root"]>;
|
|
5795
5822
|
value: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
5796
5823
|
type: z.ZodLiteral<"short_string">;
|
|
5797
5824
|
value: z.ZodString;
|
|
@@ -5819,6 +5846,15 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
5819
5846
|
}, {
|
|
5820
5847
|
value: string;
|
|
5821
5848
|
type: "sha256";
|
|
5849
|
+
}>, z.ZodObject<{
|
|
5850
|
+
type: z.ZodLiteral<"path">;
|
|
5851
|
+
value: z.ZodString;
|
|
5852
|
+
}, "strip", z.ZodTypeAny, {
|
|
5853
|
+
value: string;
|
|
5854
|
+
type: "path";
|
|
5855
|
+
}, {
|
|
5856
|
+
value: string;
|
|
5857
|
+
type: "path";
|
|
5822
5858
|
}>]>;
|
|
5823
5859
|
confidence: z.ZodEnum<["low", "med", "high"]>;
|
|
5824
5860
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -5831,8 +5867,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
5831
5867
|
} | {
|
|
5832
5868
|
value: string;
|
|
5833
5869
|
type: "sha256";
|
|
5870
|
+
} | {
|
|
5871
|
+
value: string;
|
|
5872
|
+
type: "path";
|
|
5834
5873
|
};
|
|
5835
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
5874
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
5836
5875
|
confidence: "high" | "low" | "med";
|
|
5837
5876
|
}, {
|
|
5838
5877
|
value: {
|
|
@@ -5844,8 +5883,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
5844
5883
|
} | {
|
|
5845
5884
|
value: string;
|
|
5846
5885
|
type: "sha256";
|
|
5886
|
+
} | {
|
|
5887
|
+
value: string;
|
|
5888
|
+
type: "path";
|
|
5847
5889
|
};
|
|
5848
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
5890
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
5849
5891
|
confidence: "high" | "low" | "med";
|
|
5850
5892
|
}>;
|
|
5851
5893
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -5861,8 +5903,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
5861
5903
|
} | {
|
|
5862
5904
|
value: string;
|
|
5863
5905
|
type: "sha256";
|
|
5906
|
+
} | {
|
|
5907
|
+
value: string;
|
|
5908
|
+
type: "path";
|
|
5864
5909
|
};
|
|
5865
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
5910
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
5866
5911
|
confidence: "high" | "low" | "med";
|
|
5867
5912
|
};
|
|
5868
5913
|
v: 1;
|
|
@@ -5883,8 +5928,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
5883
5928
|
} | {
|
|
5884
5929
|
value: string;
|
|
5885
5930
|
type: "sha256";
|
|
5931
|
+
} | {
|
|
5932
|
+
value: string;
|
|
5933
|
+
type: "path";
|
|
5886
5934
|
};
|
|
5887
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
5935
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
5888
5936
|
confidence: "high" | "low" | "med";
|
|
5889
5937
|
};
|
|
5890
5938
|
v: 1;
|
|
@@ -10408,8 +10456,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
10408
10456
|
} | {
|
|
10409
10457
|
value: string;
|
|
10410
10458
|
type: "sha256";
|
|
10459
|
+
} | {
|
|
10460
|
+
value: string;
|
|
10461
|
+
type: "path";
|
|
10411
10462
|
};
|
|
10412
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
10463
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
10413
10464
|
confidence: "high" | "low" | "med";
|
|
10414
10465
|
};
|
|
10415
10466
|
v: 1;
|
|
@@ -10981,8 +11032,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
10981
11032
|
} | {
|
|
10982
11033
|
value: string;
|
|
10983
11034
|
type: "sha256";
|
|
11035
|
+
} | {
|
|
11036
|
+
value: string;
|
|
11037
|
+
type: "path";
|
|
10984
11038
|
};
|
|
10985
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
11039
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
10986
11040
|
confidence: "high" | "low" | "med";
|
|
10987
11041
|
};
|
|
10988
11042
|
v: 1;
|
|
@@ -11583,8 +11637,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
11583
11637
|
} | {
|
|
11584
11638
|
value: string;
|
|
11585
11639
|
type: "sha256";
|
|
11640
|
+
} | {
|
|
11641
|
+
value: string;
|
|
11642
|
+
type: "path";
|
|
11586
11643
|
};
|
|
11587
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
11644
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
11588
11645
|
confidence: "high" | "low" | "med";
|
|
11589
11646
|
};
|
|
11590
11647
|
v: 1;
|
|
@@ -12173,8 +12230,11 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
12173
12230
|
} | {
|
|
12174
12231
|
value: string;
|
|
12175
12232
|
type: "sha256";
|
|
12233
|
+
} | {
|
|
12234
|
+
value: string;
|
|
12235
|
+
type: "path";
|
|
12176
12236
|
};
|
|
12177
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
12237
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
12178
12238
|
confidence: "high" | "low" | "med";
|
|
12179
12239
|
};
|
|
12180
12240
|
v: 1;
|
|
@@ -95,7 +95,7 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
|
|
|
95
95
|
kind: z.ZodLiteral<"observation_recorded">;
|
|
96
96
|
scope: z.ZodUndefined;
|
|
97
97
|
data: z.ZodObject<{
|
|
98
|
-
key: z.ZodEnum<["git_branch", "git_head_sha", "repo_root_hash"]>;
|
|
98
|
+
key: z.ZodEnum<["git_branch", "git_head_sha", "repo_root_hash", "repo_root"]>;
|
|
99
99
|
value: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
100
100
|
type: z.ZodLiteral<"short_string">;
|
|
101
101
|
value: z.ZodString;
|
|
@@ -123,6 +123,15 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
|
|
|
123
123
|
}, {
|
|
124
124
|
value: string;
|
|
125
125
|
type: "sha256";
|
|
126
|
+
}>, z.ZodObject<{
|
|
127
|
+
type: z.ZodLiteral<"path">;
|
|
128
|
+
value: z.ZodString;
|
|
129
|
+
}, "strip", z.ZodTypeAny, {
|
|
130
|
+
value: string;
|
|
131
|
+
type: "path";
|
|
132
|
+
}, {
|
|
133
|
+
value: string;
|
|
134
|
+
type: "path";
|
|
126
135
|
}>]>;
|
|
127
136
|
confidence: z.ZodEnum<["low", "med", "high"]>;
|
|
128
137
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -135,8 +144,11 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
|
|
|
135
144
|
} | {
|
|
136
145
|
value: string;
|
|
137
146
|
type: "sha256";
|
|
147
|
+
} | {
|
|
148
|
+
value: string;
|
|
149
|
+
type: "path";
|
|
138
150
|
};
|
|
139
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
151
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
140
152
|
confidence: "high" | "low" | "med";
|
|
141
153
|
}, {
|
|
142
154
|
value: {
|
|
@@ -148,8 +160,11 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
|
|
|
148
160
|
} | {
|
|
149
161
|
value: string;
|
|
150
162
|
type: "sha256";
|
|
163
|
+
} | {
|
|
164
|
+
value: string;
|
|
165
|
+
type: "path";
|
|
151
166
|
};
|
|
152
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
167
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
153
168
|
confidence: "high" | "low" | "med";
|
|
154
169
|
}>;
|
|
155
170
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -165,8 +180,11 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
|
|
|
165
180
|
} | {
|
|
166
181
|
value: string;
|
|
167
182
|
type: "sha256";
|
|
183
|
+
} | {
|
|
184
|
+
value: string;
|
|
185
|
+
type: "path";
|
|
168
186
|
};
|
|
169
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
187
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
170
188
|
confidence: "high" | "low" | "med";
|
|
171
189
|
};
|
|
172
190
|
v: 1;
|
|
@@ -187,8 +205,11 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
|
|
|
187
205
|
} | {
|
|
188
206
|
value: string;
|
|
189
207
|
type: "sha256";
|
|
208
|
+
} | {
|
|
209
|
+
value: string;
|
|
210
|
+
type: "path";
|
|
190
211
|
};
|
|
191
|
-
key: "git_branch" | "git_head_sha" | "repo_root_hash";
|
|
212
|
+
key: "git_branch" | "git_head_sha" | "repo_root_hash" | "repo_root";
|
|
192
213
|
confidence: "high" | "low" | "med";
|
|
193
214
|
};
|
|
194
215
|
v: 1;
|
|
@@ -107,11 +107,12 @@ exports.DomainEventV1Schema = zod_1.z.discriminatedUnion('kind', [
|
|
|
107
107
|
kind: zod_1.z.literal('observation_recorded'),
|
|
108
108
|
scope: zod_1.z.undefined(),
|
|
109
109
|
data: zod_1.z.object({
|
|
110
|
-
key: zod_1.z.enum(['git_branch', 'git_head_sha', 'repo_root_hash']),
|
|
110
|
+
key: zod_1.z.enum(['git_branch', 'git_head_sha', 'repo_root_hash', 'repo_root']),
|
|
111
111
|
value: zod_1.z.discriminatedUnion('type', [
|
|
112
112
|
zod_1.z.object({ type: zod_1.z.literal('short_string'), value: zod_1.z.string().min(1).max(constants_js_1.MAX_OBSERVATION_SHORT_STRING_LENGTH) }),
|
|
113
113
|
zod_1.z.object({ type: zod_1.z.literal('git_sha1'), value: zod_1.z.string().regex(/^[0-9a-f]{40}$/) }),
|
|
114
114
|
zod_1.z.object({ type: zod_1.z.literal('sha256'), value: sha256DigestSchema }),
|
|
115
|
+
zod_1.z.object({ type: zod_1.z.literal('path'), value: zod_1.z.string().min(1).max(constants_js_1.MAX_OBSERVATION_PATH_LENGTH) }),
|
|
115
116
|
]),
|
|
116
117
|
confidence: zod_1.z.enum(['low', 'med', 'high']),
|
|
117
118
|
}),
|
|
@@ -17,6 +17,7 @@ const EMPTY_OBSERVATIONS = {
|
|
|
17
17
|
gitHeadSha: null,
|
|
18
18
|
gitBranch: null,
|
|
19
19
|
repoRootHash: null,
|
|
20
|
+
repoRoot: null,
|
|
20
21
|
};
|
|
21
22
|
const TITLE_CONTEXT_KEYS = ['goal', 'taskDescription', 'mrTitle', 'prTitle', 'ticketTitle', 'problem'];
|
|
22
23
|
class LocalSessionSummaryProviderV2 {
|
|
@@ -131,6 +132,7 @@ function extractObservations(events) {
|
|
|
131
132
|
case 'git_head_sha': return { ...acc, gitHeadSha: e.data.value.value };
|
|
132
133
|
case 'git_branch': return { ...acc, gitBranch: e.data.value.value };
|
|
133
134
|
case 'repo_root_hash': return { ...acc, repoRootHash: e.data.value.value };
|
|
135
|
+
case 'repo_root': return { ...acc, repoRoot: e.data.value.value };
|
|
134
136
|
}
|
|
135
137
|
}, EMPTY_OBSERVATIONS);
|
|
136
138
|
}
|
|
@@ -40,6 +40,7 @@ class LocalWorkspaceAnchorV2 {
|
|
|
40
40
|
if (repoRootHash) {
|
|
41
41
|
anchors.push({ key: 'repo_root_hash', value: repoRootHash });
|
|
42
42
|
}
|
|
43
|
+
anchors.push({ key: 'repo_root', value: repoRoot });
|
|
43
44
|
const branch = await this.gitCommand('git rev-parse --abbrev-ref HEAD', cwd);
|
|
44
45
|
if (branch && branch !== 'HEAD') {
|
|
45
46
|
anchors.push({ key: 'git_branch', value: branch });
|
|
@@ -7,6 +7,7 @@ exports.mountConsoleRoutes = mountConsoleRoutes;
|
|
|
7
7
|
const express_1 = __importDefault(require("express"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const worktree_service_js_1 = require("./worktree-service.js");
|
|
10
11
|
function resolveConsoleDist() {
|
|
11
12
|
const releasedDist = path_1.default.join(__dirname, '../../console');
|
|
12
13
|
if (fs_1.default.existsSync(releasedDist))
|
|
@@ -24,6 +25,31 @@ function mountConsoleRoutes(app, consoleService) {
|
|
|
24
25
|
const result = await consoleService.getSessionList();
|
|
25
26
|
result.match((data) => res.json({ success: true, data }), (error) => res.status(500).json({ success: false, error: error.message }));
|
|
26
27
|
});
|
|
28
|
+
let cwdRepoRootPromise = null;
|
|
29
|
+
const REPO_ROOTS_TTL_MS = 60000;
|
|
30
|
+
let cachedRepoRoots = [];
|
|
31
|
+
let repoRootsExpiresAt = 0;
|
|
32
|
+
app.get('/api/v2/worktrees', async (_req, res) => {
|
|
33
|
+
try {
|
|
34
|
+
const sessionResult = await consoleService.getSessionList();
|
|
35
|
+
const sessions = sessionResult.isOk() ? sessionResult.value.sessions : [];
|
|
36
|
+
const activeSessions = (0, worktree_service_js_1.buildActiveSessionCounts)(sessions);
|
|
37
|
+
if (Date.now() > repoRootsExpiresAt) {
|
|
38
|
+
cwdRepoRootPromise ?? (cwdRepoRootPromise = (0, worktree_service_js_1.resolveRepoRoot)(process.cwd()));
|
|
39
|
+
const cwdRoot = await cwdRepoRootPromise;
|
|
40
|
+
const repoRootSet = new Set(sessions.map(s => s.repoRoot).filter((r) => r !== null));
|
|
41
|
+
if (cwdRoot !== null)
|
|
42
|
+
repoRootSet.add(cwdRoot);
|
|
43
|
+
cachedRepoRoots = [...repoRootSet];
|
|
44
|
+
repoRootsExpiresAt = Date.now() + REPO_ROOTS_TTL_MS;
|
|
45
|
+
}
|
|
46
|
+
const data = await (0, worktree_service_js_1.getWorktreeList)(cachedRepoRoots, activeSessions);
|
|
47
|
+
res.json({ success: true, data });
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
res.status(500).json({ success: false, error: e instanceof Error ? e.message : String(e) });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
27
53
|
app.get('/api/v2/sessions/:sessionId', async (req, res) => {
|
|
28
54
|
const { sessionId } = req.params;
|
|
29
55
|
const result = await consoleService.getSessionDetail(sessionId);
|
|
@@ -14,6 +14,7 @@ const run_context_js_1 = require("../projections/run-context.js");
|
|
|
14
14
|
const constants_js_1 = require("../durable-core/constants.js");
|
|
15
15
|
const index_js_1 = require("../durable-core/ids/index.js");
|
|
16
16
|
const MAX_SESSIONS_TO_LOAD = 500;
|
|
17
|
+
const DORMANCY_THRESHOLD_MS = 3 * 24 * 60 * 60 * 1000;
|
|
17
18
|
class ConsoleService {
|
|
18
19
|
constructor(ports) {
|
|
19
20
|
this.ports = ports;
|
|
@@ -91,13 +92,14 @@ class ConsoleService {
|
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
94
|
collectSessionSummaries(sessionIds, mtimeBySessionId) {
|
|
94
|
-
const
|
|
95
|
+
const nowMs = Date.now();
|
|
96
|
+
const tasks = sessionIds.map((id) => this.loadSessionSummary(id, mtimeBySessionId.get(id) ?? 0, nowMs));
|
|
95
97
|
return neverthrow_1.ResultAsync.combine(tasks).map((results) => {
|
|
96
98
|
const sessions = results.filter((s) => s !== null);
|
|
97
99
|
return { sessions, totalCount: sessions.length };
|
|
98
100
|
});
|
|
99
101
|
}
|
|
100
|
-
loadSessionSummary(sessionId, lastModifiedMs) {
|
|
102
|
+
loadSessionSummary(sessionId, lastModifiedMs, nowMs) {
|
|
101
103
|
return this.ports.sessionStore
|
|
102
104
|
.load(sessionId)
|
|
103
105
|
.andThen((truth) => {
|
|
@@ -108,7 +110,7 @@ class ConsoleService {
|
|
|
108
110
|
return neverthrow_1.ResultAsync.combine([
|
|
109
111
|
resolveRunCompletion(truth.events, this.ports.snapshotStore),
|
|
110
112
|
workflowNamesRA,
|
|
111
|
-
]).map(([completionMap, workflowNames]) => projectSessionSummary(sessionId, truth, completionMap, workflowNames, lastModifiedMs));
|
|
113
|
+
]).map(([completionMap, workflowNames]) => projectSessionSummary(sessionId, truth, completionMap, workflowNames, lastModifiedMs, nowMs));
|
|
112
114
|
})
|
|
113
115
|
.orElse(() => (0, neverthrow_2.okAsync)(null));
|
|
114
116
|
}
|
|
@@ -313,12 +315,22 @@ function extractGitBranch(events) {
|
|
|
313
315
|
}
|
|
314
316
|
return null;
|
|
315
317
|
}
|
|
318
|
+
function extractRepoRoot(events) {
|
|
319
|
+
for (const e of events) {
|
|
320
|
+
if (e.kind !== constants_js_1.EVENT_KIND.OBSERVATION_RECORDED)
|
|
321
|
+
continue;
|
|
322
|
+
if (e.data.key === 'repo_root') {
|
|
323
|
+
return e.data.value.value;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
316
328
|
function truncateTitle(text, maxLen = 120) {
|
|
317
329
|
if (text.length <= maxLen)
|
|
318
330
|
return text;
|
|
319
331
|
return text.slice(0, maxLen - 1) + '…';
|
|
320
332
|
}
|
|
321
|
-
function projectSessionSummary(sessionId, truth, completionByRunId, workflowNames, lastModifiedMs) {
|
|
333
|
+
function projectSessionSummary(sessionId, truth, completionByRunId, workflowNames, lastModifiedMs, nowMs) {
|
|
322
334
|
const { events } = truth;
|
|
323
335
|
const health = (0, session_health_js_1.projectSessionHealthV2)(truth);
|
|
324
336
|
if (health.isErr())
|
|
@@ -332,9 +344,11 @@ function projectSessionSummary(sessionId, truth, completionByRunId, workflowName
|
|
|
332
344
|
const gapsRes = (0, gaps_js_1.projectGapsV2)(events);
|
|
333
345
|
const sessionTitle = deriveSessionTitle(events);
|
|
334
346
|
const gitBranch = extractGitBranch(events);
|
|
347
|
+
const repoRoot = extractRepoRoot(events);
|
|
335
348
|
const runs = Object.values(dag.runsById);
|
|
336
349
|
const run = runs[0];
|
|
337
350
|
if (!run) {
|
|
351
|
+
const noRunStatus = nowMs - lastModifiedMs > DORMANCY_THRESHOLD_MS ? 'dormant' : 'in_progress';
|
|
338
352
|
return {
|
|
339
353
|
sessionId,
|
|
340
354
|
sessionTitle,
|
|
@@ -342,7 +356,7 @@ function projectSessionSummary(sessionId, truth, completionByRunId, workflowName
|
|
|
342
356
|
workflowName: null,
|
|
343
357
|
workflowHash: null,
|
|
344
358
|
runId: null,
|
|
345
|
-
status:
|
|
359
|
+
status: noRunStatus,
|
|
346
360
|
health: sessionHealth,
|
|
347
361
|
nodeCount: 0,
|
|
348
362
|
edgeCount: 0,
|
|
@@ -350,6 +364,7 @@ function projectSessionSummary(sessionId, truth, completionByRunId, workflowName
|
|
|
350
364
|
hasUnresolvedGaps: false,
|
|
351
365
|
recapSnippet: null,
|
|
352
366
|
gitBranch,
|
|
367
|
+
repoRoot,
|
|
353
368
|
lastModifiedMs,
|
|
354
369
|
};
|
|
355
370
|
}
|
|
@@ -358,7 +373,10 @@ function projectSessionSummary(sessionId, truth, completionByRunId, workflowName
|
|
|
358
373
|
const workflowHash = workflow.kind === 'with_workflow' ? workflow.workflowHash : null;
|
|
359
374
|
const workflowName = workflowHash ? (workflowNames[workflowHash] ?? null) : null;
|
|
360
375
|
const statusSignals = statusRes.isOk() ? statusRes.value.byRunId[run.runId] : undefined;
|
|
361
|
-
const
|
|
376
|
+
const runStatus = deriveRunStatus(statusSignals?.isBlocked ?? false, statusSignals?.hasUnresolvedCriticalGaps ?? false, completionByRunId[run.runId] ?? false);
|
|
377
|
+
const status = runStatus === 'in_progress' && nowMs - lastModifiedMs > DORMANCY_THRESHOLD_MS
|
|
378
|
+
? 'dormant'
|
|
379
|
+
: runStatus;
|
|
362
380
|
const hasUnresolvedGaps = gapsRes.isOk()
|
|
363
381
|
? Object.keys(gapsRes.value.unresolvedCriticalByRunId).length > 0
|
|
364
382
|
: false;
|
|
@@ -389,6 +407,7 @@ function projectSessionSummary(sessionId, truth, completionByRunId, workflowName
|
|
|
389
407
|
hasUnresolvedGaps,
|
|
390
408
|
recapSnippet,
|
|
391
409
|
gitBranch,
|
|
410
|
+
repoRoot,
|
|
392
411
|
lastModifiedMs,
|
|
393
412
|
};
|
|
394
413
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type ConsoleRunStatus = 'in_progress' | 'complete' | 'complete_with_gaps' | 'blocked';
|
|
2
|
+
export type ConsoleSessionStatus = ConsoleRunStatus | 'dormant';
|
|
2
3
|
export type ConsoleSessionHealth = 'healthy' | 'corrupt';
|
|
3
4
|
export interface ConsoleSessionSummary {
|
|
4
5
|
readonly sessionId: string;
|
|
@@ -7,7 +8,7 @@ export interface ConsoleSessionSummary {
|
|
|
7
8
|
readonly workflowName: string | null;
|
|
8
9
|
readonly workflowHash: string | null;
|
|
9
10
|
readonly runId: string | null;
|
|
10
|
-
readonly status:
|
|
11
|
+
readonly status: ConsoleSessionStatus;
|
|
11
12
|
readonly health: ConsoleSessionHealth;
|
|
12
13
|
readonly nodeCount: number;
|
|
13
14
|
readonly edgeCount: number;
|
|
@@ -15,6 +16,7 @@ export interface ConsoleSessionSummary {
|
|
|
15
16
|
readonly hasUnresolvedGaps: boolean;
|
|
16
17
|
readonly recapSnippet: string | null;
|
|
17
18
|
readonly gitBranch: string | null;
|
|
19
|
+
readonly repoRoot: string | null;
|
|
18
20
|
readonly lastModifiedMs: number;
|
|
19
21
|
}
|
|
20
22
|
export interface ConsoleSessionListResponse {
|
|
@@ -81,6 +83,25 @@ export interface ConsoleArtifact {
|
|
|
81
83
|
readonly byteLength: number;
|
|
82
84
|
readonly content: unknown;
|
|
83
85
|
}
|
|
86
|
+
export interface ConsoleWorktreeSummary {
|
|
87
|
+
readonly path: string;
|
|
88
|
+
readonly name: string;
|
|
89
|
+
readonly branch: string | null;
|
|
90
|
+
readonly headHash: string;
|
|
91
|
+
readonly headMessage: string;
|
|
92
|
+
readonly headTimestampMs: number;
|
|
93
|
+
readonly changedCount: number;
|
|
94
|
+
readonly aheadCount: number;
|
|
95
|
+
readonly activeSessionCount: number;
|
|
96
|
+
}
|
|
97
|
+
export interface ConsoleRepoWorktrees {
|
|
98
|
+
readonly repoName: string;
|
|
99
|
+
readonly repoRoot: string;
|
|
100
|
+
readonly worktrees: readonly ConsoleWorktreeSummary[];
|
|
101
|
+
}
|
|
102
|
+
export interface ConsoleWorktreeListResponse {
|
|
103
|
+
readonly repos: readonly ConsoleRepoWorktrees[];
|
|
104
|
+
}
|
|
84
105
|
export interface ConsoleNodeDetail {
|
|
85
106
|
readonly nodeId: string;
|
|
86
107
|
readonly nodeKind: 'step' | 'checkpoint' | 'blocked_attempt';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ConsoleWorktreeListResponse, ConsoleSessionStatus } from './console-types.js';
|
|
2
|
+
export declare function resolveRepoRoot(path: string): Promise<string | null>;
|
|
3
|
+
export interface ActiveSessionsByBranch {
|
|
4
|
+
readonly counts: ReadonlyMap<string, number>;
|
|
5
|
+
}
|
|
6
|
+
export declare function buildActiveSessionCounts(sessions: ReadonlyArray<{
|
|
7
|
+
gitBranch: string | null;
|
|
8
|
+
status: ConsoleSessionStatus;
|
|
9
|
+
}>): ActiveSessionsByBranch;
|
|
10
|
+
export declare function getWorktreeList(repoRoots: readonly string[], activeSessions: ActiveSessionsByBranch): Promise<ConsoleWorktreeListResponse>;
|