@exaudeus/workrail 1.5.4 → 1.6.1
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/manifest.json +24 -16
- package/dist/mcp/handlers/v2-execution/start.js +6 -3
- package/dist/mcp/handlers/v2-resume.js +5 -2
- package/dist/mcp/server.js +27 -3
- package/dist/mcp/types.d.ts +3 -2
- package/dist/mcp/workspace-roots-manager.d.ts +11 -0
- package/dist/mcp/workspace-roots-manager.js +15 -0
- package/dist/v2/infra/local/session-summary-provider/index.js +22 -4
- package/dist/v2/infra/local/workspace-anchor/index.d.ts +7 -4
- package/dist/v2/infra/local/workspace-anchor/index.js +31 -8
- package/dist/v2/ports/workspace-anchor.port.d.ts +4 -0
- package/package.json +1 -1
- package/workflows/test-session-persistence.json +33 -0
package/dist/manifest.json
CHANGED
|
@@ -686,16 +686,16 @@
|
|
|
686
686
|
"bytes": 2789
|
|
687
687
|
},
|
|
688
688
|
"mcp/handlers/v2-execution/start.js": {
|
|
689
|
-
"sha256": "
|
|
690
|
-
"bytes":
|
|
689
|
+
"sha256": "5eab7a7a5fdf021f7e4bc656de1dbfe791e6610ab9e1bacb15dad4f6423f1d58",
|
|
690
|
+
"bytes": 15248
|
|
691
691
|
},
|
|
692
692
|
"mcp/handlers/v2-resume.d.ts": {
|
|
693
693
|
"sha256": "d88f6c35bcaf946666c837b72fda3702a2ebab5e478eb90f7b4b672a0e5fa24f",
|
|
694
694
|
"bytes": 471
|
|
695
695
|
},
|
|
696
696
|
"mcp/handlers/v2-resume.js": {
|
|
697
|
-
"sha256": "
|
|
698
|
-
"bytes":
|
|
697
|
+
"sha256": "a8f51a680eec031e23148bd64f6d647d765c79eec738cbd6182650533248f16f",
|
|
698
|
+
"bytes": 2929
|
|
699
699
|
},
|
|
700
700
|
"mcp/handlers/v2-state-conversion.d.ts": {
|
|
701
701
|
"sha256": "94bd06904ef58dd210ff17ffb75c2492beea8937eb06d99749e5d860c0e0d96b",
|
|
@@ -750,8 +750,8 @@
|
|
|
750
750
|
"bytes": 168
|
|
751
751
|
},
|
|
752
752
|
"mcp/server.js": {
|
|
753
|
-
"sha256": "
|
|
754
|
-
"bytes":
|
|
753
|
+
"sha256": "fd9e264c759db2d5446d88eafce14ec27ce9b73756e62ef10351b2fca52c7c7c",
|
|
754
|
+
"bytes": 11892
|
|
755
755
|
},
|
|
756
756
|
"mcp/tool-description-provider.d.ts": {
|
|
757
757
|
"sha256": "1d46abc3112e11b68e57197e846f5708293ec9b2281fa71a9124ee2aad71e41b",
|
|
@@ -786,8 +786,8 @@
|
|
|
786
786
|
"bytes": 8360
|
|
787
787
|
},
|
|
788
788
|
"mcp/types.d.ts": {
|
|
789
|
-
"sha256": "
|
|
790
|
-
"bytes":
|
|
789
|
+
"sha256": "2ef7f9c1bffbe365b06469dfad43b45c4ae3b5292dd269b33423bf1c8c9c7c43",
|
|
790
|
+
"bytes": 4355
|
|
791
791
|
},
|
|
792
792
|
"mcp/types.js": {
|
|
793
793
|
"sha256": "d10c4070e4c3454d80f0fa9cdc0e978c69c53c13fd09baa8710fcd802fed8926",
|
|
@@ -905,6 +905,14 @@
|
|
|
905
905
|
"sha256": "08870a96c6f32c09e617f43f6eb83593c15007fe39241d498bd9bbbd420101fc",
|
|
906
906
|
"bytes": 635
|
|
907
907
|
},
|
|
908
|
+
"mcp/workspace-roots-manager.d.ts": {
|
|
909
|
+
"sha256": "32f342eb4cf2c1a94982f8077dea4185b74f118c1587b40a370200cf2aa06f9c",
|
|
910
|
+
"bytes": 363
|
|
911
|
+
},
|
|
912
|
+
"mcp/workspace-roots-manager.js": {
|
|
913
|
+
"sha256": "1037fa12885161c91af1beed0dc0a0cb05a5636b4a63d1756e1ed3cab76e1d32",
|
|
914
|
+
"bytes": 419
|
|
915
|
+
},
|
|
908
916
|
"mcp/zod-to-json-schema.d.ts": {
|
|
909
917
|
"sha256": "c80cfa6980a88c823ac47d04706b2223a351de3f4c76ee778f81ad3dda2c766b",
|
|
910
918
|
"bytes": 456
|
|
@@ -1806,8 +1814,8 @@
|
|
|
1806
1814
|
"bytes": 1069
|
|
1807
1815
|
},
|
|
1808
1816
|
"v2/infra/local/session-summary-provider/index.js": {
|
|
1809
|
-
"sha256": "
|
|
1810
|
-
"bytes":
|
|
1817
|
+
"sha256": "736989809f7a78b3b6b0584609d8cce8424fde20e4eb8e7c513d7b012d45d9d2",
|
|
1818
|
+
"bytes": 6463
|
|
1811
1819
|
},
|
|
1812
1820
|
"v2/infra/local/sha256/index.d.ts": {
|
|
1813
1821
|
"sha256": "8a727b7e54a38275ca6f9f1b8730f97cfc0a212df035df1bdc58e716e6824230",
|
|
@@ -1842,12 +1850,12 @@
|
|
|
1842
1850
|
"bytes": 304
|
|
1843
1851
|
},
|
|
1844
1852
|
"v2/infra/local/workspace-anchor/index.d.ts": {
|
|
1845
|
-
"sha256": "
|
|
1846
|
-
"bytes":
|
|
1853
|
+
"sha256": "90515ae92ac0230a279a28b82e26bc8be8f62c4cd6f6999630dc07f9a64e3296",
|
|
1854
|
+
"bytes": 705
|
|
1847
1855
|
},
|
|
1848
1856
|
"v2/infra/local/workspace-anchor/index.js": {
|
|
1849
|
-
"sha256": "
|
|
1850
|
-
"bytes":
|
|
1857
|
+
"sha256": "69541a7f2a6837ff0790c99740000a71521a60671b4fd7c4a2245a48e56bb9b7",
|
|
1858
|
+
"bytes": 2102
|
|
1851
1859
|
},
|
|
1852
1860
|
"v2/ports/base32.port.d.ts": {
|
|
1853
1861
|
"sha256": "64aa2f2003a552917cbf71474472fc5e4afffaa29577204bbcbe5ffa989ceb82",
|
|
@@ -1986,8 +1994,8 @@
|
|
|
1986
1994
|
"bytes": 77
|
|
1987
1995
|
},
|
|
1988
1996
|
"v2/ports/workspace-anchor.port.d.ts": {
|
|
1989
|
-
"sha256": "
|
|
1990
|
-
"bytes":
|
|
1997
|
+
"sha256": "228cce9bff3cbaa430bf38be3a1bc326885ec07c7952af2824735bc7adbf9af3",
|
|
1998
|
+
"bytes": 759
|
|
1991
1999
|
},
|
|
1992
2000
|
"v2/ports/workspace-anchor.port.js": {
|
|
1993
2001
|
"sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
|
|
@@ -229,9 +229,12 @@ function executeStartWorkflow(input, ctx) {
|
|
|
229
229
|
pinnedStore,
|
|
230
230
|
})
|
|
231
231
|
.andThen(({ workflow, firstStep, workflowHash, pinnedWorkflow }) => {
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
|
|
232
|
+
const workspaceResolver = ctx.v2.workspaceResolver;
|
|
233
|
+
const primaryRootUri = ctx.v2.resolvedRootUris?.[0];
|
|
234
|
+
const anchorsRA = workspaceResolver
|
|
235
|
+
? (primaryRootUri
|
|
236
|
+
? workspaceResolver.resolveFromUri(primaryRootUri)
|
|
237
|
+
: workspaceResolver.resolveFromCwd())
|
|
235
238
|
.map((anchors) => (0, observation_builder_js_1.anchorsToObservations)(anchors))
|
|
236
239
|
.orElse(() => (0, neverthrow_1.okAsync)([]))
|
|
237
240
|
: (0, neverthrow_1.okAsync)([]);
|
|
@@ -19,8 +19,11 @@ async function handleV2ResumeSession(input, ctx) {
|
|
|
19
19
|
return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'resume_session requires sessionSummaryProvider port');
|
|
20
20
|
}
|
|
21
21
|
let anchors = [];
|
|
22
|
-
if (v2.
|
|
23
|
-
const
|
|
22
|
+
if (v2.workspaceResolver) {
|
|
23
|
+
const primaryRootUri = v2.resolvedRootUris?.[0];
|
|
24
|
+
const anchorRes = await (primaryRootUri
|
|
25
|
+
? v2.workspaceResolver.resolveFromUri(primaryRootUri)
|
|
26
|
+
: v2.workspaceResolver.resolveFromCwd());
|
|
24
27
|
if (anchorRes.isOk()) {
|
|
25
28
|
anchors = anchorRes.value;
|
|
26
29
|
}
|
package/dist/mcp/server.js
CHANGED
|
@@ -41,6 +41,7 @@ const tokens_js_1 = require("../di/tokens.js");
|
|
|
41
41
|
const assert_never_js_1 = require("../runtime/assert-never.js");
|
|
42
42
|
const token_codec_ports_js_1 = require("../v2/durable-core/tokens/token-codec-ports.js");
|
|
43
43
|
const index_js_1 = require("../v2/infra/local/workspace-anchor/index.js");
|
|
44
|
+
const workspace_roots_manager_js_1 = require("./workspace-roots-manager.js");
|
|
44
45
|
const index_js_2 = require("../v2/infra/local/directory-listing/index.js");
|
|
45
46
|
const index_js_3 = require("../v2/infra/local/session-summary-provider/index.js");
|
|
46
47
|
const tool_factory_js_1 = require("./tool-factory.js");
|
|
@@ -101,7 +102,8 @@ async function createToolContext() {
|
|
|
101
102
|
crypto,
|
|
102
103
|
idFactory,
|
|
103
104
|
tokenCodecPorts,
|
|
104
|
-
|
|
105
|
+
resolvedRootUris: [],
|
|
106
|
+
workspaceResolver: new index_js_1.LocalWorkspaceAnchorV2(process.cwd()),
|
|
105
107
|
dataDir,
|
|
106
108
|
directoryListing,
|
|
107
109
|
sessionSummaryProvider: new index_js_3.LocalSessionSummaryProviderV2({
|
|
@@ -148,9 +150,10 @@ async function startServer() {
|
|
|
148
150
|
default:
|
|
149
151
|
(0, assert_never_js_1.assertNever)(workflowEdition);
|
|
150
152
|
}
|
|
153
|
+
const rootsManager = new workspace_roots_manager_js_1.WorkspaceRootsManager();
|
|
151
154
|
const { Server } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/index.js')));
|
|
152
155
|
const { StdioServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/stdio.js')));
|
|
153
|
-
const { CallToolRequestSchema, ListToolsRequestSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
|
|
156
|
+
const { CallToolRequestSchema, ListToolsRequestSchema, RootsListChangedNotificationSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
|
|
154
157
|
const server = new Server({
|
|
155
158
|
name: 'workrail-server',
|
|
156
159
|
version: '0.1.0',
|
|
@@ -182,10 +185,31 @@ async function startServer() {
|
|
|
182
185
|
isError: true,
|
|
183
186
|
};
|
|
184
187
|
}
|
|
185
|
-
|
|
188
|
+
const requestCtx = ctx.v2
|
|
189
|
+
? { ...ctx, v2: { ...ctx.v2, resolvedRootUris: rootsManager.getCurrentRootUris() } }
|
|
190
|
+
: ctx;
|
|
191
|
+
return handler(args ?? {}, requestCtx);
|
|
192
|
+
});
|
|
193
|
+
server.setNotificationHandler(RootsListChangedNotificationSchema, async () => {
|
|
194
|
+
try {
|
|
195
|
+
const result = await server.listRoots();
|
|
196
|
+
rootsManager.updateRootUris(result.roots.map((r) => r.uri));
|
|
197
|
+
console.error(`[Roots] Updated workspace roots: ${result.roots.map((r) => r.uri).join(', ') || '(none)'}`);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
console.error('[Roots] Failed to fetch updated roots after change notification');
|
|
201
|
+
}
|
|
186
202
|
});
|
|
187
203
|
const transport = new StdioServerTransport();
|
|
188
204
|
await server.connect(transport);
|
|
205
|
+
try {
|
|
206
|
+
const result = await server.listRoots();
|
|
207
|
+
rootsManager.updateRootUris(result.roots.map((r) => r.uri));
|
|
208
|
+
console.error(`[Roots] Initial workspace roots: ${result.roots.map((r) => r.uri).join(', ') || '(none)'}`);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
console.error('[Roots] Client does not support roots/list; workspace context will use server CWD fallback');
|
|
212
|
+
}
|
|
189
213
|
console.error('WorkRail MCP Server running on stdio');
|
|
190
214
|
const shutdownEvents = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ShutdownEvents);
|
|
191
215
|
const processSignals = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessSignals);
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { CryptoPortV2 } from '../v2/durable-core/canonical/hashing.js';
|
|
|
12
12
|
import type { IdFactoryV2 } from '../v2/infra/local/id-factory/index.js';
|
|
13
13
|
import type { JsonValue } from './output-schemas.js';
|
|
14
14
|
import type { TokenCodecPorts } from '../v2/durable-core/tokens/token-codec-ports.js';
|
|
15
|
-
import type {
|
|
15
|
+
import type { WorkspaceContextResolverPortV2 } from '../v2/ports/workspace-anchor.port.js';
|
|
16
16
|
import type { DataDirPortV2 } from '../v2/ports/data-dir.port.js';
|
|
17
17
|
import type { DirectoryListingPortV2 } from '../v2/ports/directory-listing.port.js';
|
|
18
18
|
import type { SessionSummaryProviderPortV2 } from '../v2/ports/session-summary-provider.port.js';
|
|
@@ -55,7 +55,8 @@ export interface V2Dependencies {
|
|
|
55
55
|
readonly crypto: CryptoPortV2;
|
|
56
56
|
readonly idFactory: IdFactoryV2;
|
|
57
57
|
readonly tokenCodecPorts: TokenCodecPorts;
|
|
58
|
-
readonly
|
|
58
|
+
readonly resolvedRootUris?: readonly string[];
|
|
59
|
+
readonly workspaceResolver?: WorkspaceContextResolverPortV2;
|
|
59
60
|
readonly dataDir?: DataDirPortV2;
|
|
60
61
|
readonly directoryListing?: DirectoryListingPortV2;
|
|
61
62
|
readonly sessionSummaryProvider?: SessionSummaryProviderPortV2;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface RootsReader {
|
|
2
|
+
getCurrentRootUris(): readonly string[];
|
|
3
|
+
}
|
|
4
|
+
export interface RootsWriter {
|
|
5
|
+
updateRootUris(uris: readonly string[]): void;
|
|
6
|
+
}
|
|
7
|
+
export declare class WorkspaceRootsManager implements RootsReader, RootsWriter {
|
|
8
|
+
private rootUris;
|
|
9
|
+
updateRootUris(uris: readonly string[]): void;
|
|
10
|
+
getCurrentRootUris(): readonly string[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkspaceRootsManager = void 0;
|
|
4
|
+
class WorkspaceRootsManager {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.rootUris = Object.freeze([]);
|
|
7
|
+
}
|
|
8
|
+
updateRootUris(uris) {
|
|
9
|
+
this.rootUris = Object.freeze([...uris]);
|
|
10
|
+
}
|
|
11
|
+
getCurrentRootUris() {
|
|
12
|
+
return this.rootUris;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.WorkspaceRootsManager = WorkspaceRootsManager;
|
|
@@ -68,7 +68,7 @@ class LocalSessionSummaryProviderV2 {
|
|
|
68
68
|
const run = bestRun.run;
|
|
69
69
|
const outputsRes = (0, node_outputs_js_1.projectNodeOutputsV2)(truth.events);
|
|
70
70
|
const recapSnippet = outputsRes.isOk() && run.preferredTipNodeId
|
|
71
|
-
?
|
|
71
|
+
? extractAggregateRecap(outputsRes.value, run, run.preferredTipNodeId)
|
|
72
72
|
: null;
|
|
73
73
|
const observations = extractObservations(truth.events);
|
|
74
74
|
const workflow = extractWorkflowIdentity(truth.events, run.runId);
|
|
@@ -88,7 +88,19 @@ class LocalSessionSummaryProviderV2 {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
exports.LocalSessionSummaryProviderV2 = LocalSessionSummaryProviderV2;
|
|
91
|
-
|
|
91
|
+
const MAX_RECAP_ANCESTOR_DEPTH = 100;
|
|
92
|
+
function collectAncestorNodeIds(nodesById, nodeId, remainingDepth) {
|
|
93
|
+
if (remainingDepth === 0)
|
|
94
|
+
return [nodeId];
|
|
95
|
+
const node = nodesById[nodeId];
|
|
96
|
+
if (!node)
|
|
97
|
+
return [nodeId];
|
|
98
|
+
const parentIds = node.parentNodeId
|
|
99
|
+
? collectAncestorNodeIds(nodesById, node.parentNodeId, remainingDepth - 1)
|
|
100
|
+
: [];
|
|
101
|
+
return [nodeId, ...parentIds];
|
|
102
|
+
}
|
|
103
|
+
function extractNodeRecapMarkdown(outputs, nodeId) {
|
|
92
104
|
const nodeView = outputs.nodesById[nodeId];
|
|
93
105
|
if (!nodeView)
|
|
94
106
|
return null;
|
|
@@ -99,9 +111,15 @@ function extractRecapFromOutputs(outputs, nodeId) {
|
|
|
99
111
|
if (latest.payload.payloadKind !== 'notes')
|
|
100
112
|
return null;
|
|
101
113
|
const markdown = latest.payload.notesMarkdown;
|
|
102
|
-
|
|
114
|
+
return (markdown && typeof markdown === 'string') ? markdown : null;
|
|
115
|
+
}
|
|
116
|
+
function extractAggregateRecap(outputs, run, tipNodeId) {
|
|
117
|
+
const parts = collectAncestorNodeIds(run.nodesById, tipNodeId, MAX_RECAP_ANCESTOR_DEPTH)
|
|
118
|
+
.map((nodeId) => extractNodeRecapMarkdown(outputs, nodeId))
|
|
119
|
+
.filter((md) => md !== null);
|
|
120
|
+
if (parts.length === 0)
|
|
103
121
|
return null;
|
|
104
|
-
return (0, resume_ranking_js_1.asRecapSnippet)(
|
|
122
|
+
return (0, resume_ranking_js_1.asRecapSnippet)(parts.join('\n\n'));
|
|
105
123
|
}
|
|
106
124
|
function extractObservations(events) {
|
|
107
125
|
let gitHeadSha = null;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { ResultAsync as RA } from 'neverthrow';
|
|
2
|
-
import type { WorkspaceAnchorPortV2, WorkspaceAnchor, WorkspaceAnchorError } from '../../../ports/workspace-anchor.port.js';
|
|
3
|
-
export declare class LocalWorkspaceAnchorV2 implements WorkspaceAnchorPortV2 {
|
|
4
|
-
private readonly
|
|
5
|
-
constructor(
|
|
2
|
+
import type { WorkspaceAnchorPortV2, WorkspaceContextResolverPortV2, WorkspaceAnchor, WorkspaceAnchorError } from '../../../ports/workspace-anchor.port.js';
|
|
3
|
+
export declare class LocalWorkspaceAnchorV2 implements WorkspaceAnchorPortV2, WorkspaceContextResolverPortV2 {
|
|
4
|
+
private readonly defaultCwd;
|
|
5
|
+
constructor(defaultCwd: string);
|
|
6
6
|
resolveAnchors(): RA<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
7
|
+
resolveFromUri(rootUri: string): RA<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
8
|
+
resolveFromCwd(): RA<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
9
|
+
private resolveFromPath;
|
|
7
10
|
private resolve;
|
|
8
11
|
private gitCommand;
|
|
9
12
|
}
|
|
@@ -4,33 +4,46 @@ exports.LocalWorkspaceAnchorV2 = void 0;
|
|
|
4
4
|
const neverthrow_1 = require("neverthrow");
|
|
5
5
|
const child_process_1 = require("child_process");
|
|
6
6
|
const util_1 = require("util");
|
|
7
|
+
const url_1 = require("url");
|
|
7
8
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
8
9
|
class LocalWorkspaceAnchorV2 {
|
|
9
|
-
constructor(
|
|
10
|
-
this.
|
|
10
|
+
constructor(defaultCwd) {
|
|
11
|
+
this.defaultCwd = defaultCwd;
|
|
11
12
|
}
|
|
12
13
|
resolveAnchors() {
|
|
13
|
-
return
|
|
14
|
+
return this.resolveFromPath(this.defaultCwd);
|
|
15
|
+
}
|
|
16
|
+
resolveFromUri(rootUri) {
|
|
17
|
+
const fsPath = uriToFsPath(rootUri);
|
|
18
|
+
if (fsPath === null)
|
|
19
|
+
return (0, neverthrow_1.okAsync)([]);
|
|
20
|
+
return this.resolveFromPath(fsPath);
|
|
21
|
+
}
|
|
22
|
+
resolveFromCwd() {
|
|
23
|
+
return this.resolveFromPath(this.defaultCwd);
|
|
24
|
+
}
|
|
25
|
+
resolveFromPath(cwd) {
|
|
26
|
+
return neverthrow_1.ResultAsync.fromPromise(this.resolve(cwd), (cause) => ({
|
|
14
27
|
code: 'ANCHOR_RESOLVE_FAILED',
|
|
15
28
|
message: `Failed to resolve workspace anchors: ${String(cause)}`,
|
|
16
29
|
}));
|
|
17
30
|
}
|
|
18
|
-
async resolve() {
|
|
31
|
+
async resolve(cwd) {
|
|
19
32
|
const anchors = [];
|
|
20
|
-
const branch = await this.gitCommand('git rev-parse --abbrev-ref HEAD');
|
|
33
|
+
const branch = await this.gitCommand('git rev-parse --abbrev-ref HEAD', cwd);
|
|
21
34
|
if (branch && branch !== 'HEAD') {
|
|
22
35
|
anchors.push({ key: 'git_branch', value: branch });
|
|
23
36
|
}
|
|
24
|
-
const sha = await this.gitCommand('git rev-parse HEAD');
|
|
37
|
+
const sha = await this.gitCommand('git rev-parse HEAD', cwd);
|
|
25
38
|
if (sha && /^[0-9a-f]{40}$/.test(sha)) {
|
|
26
39
|
anchors.push({ key: 'git_head_sha', value: sha });
|
|
27
40
|
}
|
|
28
41
|
return anchors;
|
|
29
42
|
}
|
|
30
|
-
async gitCommand(cmd) {
|
|
43
|
+
async gitCommand(cmd, cwd) {
|
|
31
44
|
try {
|
|
32
45
|
const { stdout } = await execAsync(cmd, {
|
|
33
|
-
cwd
|
|
46
|
+
cwd,
|
|
34
47
|
timeout: 5000,
|
|
35
48
|
encoding: 'utf8',
|
|
36
49
|
});
|
|
@@ -42,3 +55,13 @@ class LocalWorkspaceAnchorV2 {
|
|
|
42
55
|
}
|
|
43
56
|
}
|
|
44
57
|
exports.LocalWorkspaceAnchorV2 = LocalWorkspaceAnchorV2;
|
|
58
|
+
function uriToFsPath(uri) {
|
|
59
|
+
if (!uri.startsWith('file://'))
|
|
60
|
+
return null;
|
|
61
|
+
try {
|
|
62
|
+
return (0, url_1.fileURLToPath)(uri);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -16,3 +16,7 @@ export type WorkspaceAnchorError = {
|
|
|
16
16
|
export interface WorkspaceAnchorPortV2 {
|
|
17
17
|
resolveAnchors(): ResultAsync<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
18
18
|
}
|
|
19
|
+
export interface WorkspaceContextResolverPortV2 {
|
|
20
|
+
resolveFromUri(rootUri: string): ResultAsync<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
21
|
+
resolveFromCwd(): ResultAsync<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "test-session-persistence",
|
|
3
|
+
"name": "Session Persistence Test",
|
|
4
|
+
"description": "Purpose-built workflow for testing v2 session persistence, cross-chat resume, and checkpoint mechanics. Has 5 simple steps that agents can complete quickly with unique marker outputs.",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"steps": [
|
|
7
|
+
{
|
|
8
|
+
"id": "step-1-alpha",
|
|
9
|
+
"title": "Step 1: Alpha Marker",
|
|
10
|
+
"prompt": "You are testing WorkRail v2 session persistence.\n\nYour task is simple: provide output containing the unique marker **ALPHA**.\n\nInclude in your output:\n- The marker string exactly as shown above\n- A brief note that you completed this step\n\nThis marker will be used in a future test to verify cross-chat session resumption works correctly."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "step-2-beta",
|
|
14
|
+
"title": "Step 2: Beta Marker",
|
|
15
|
+
"prompt": "You are testing WorkRail v2 session persistence.\n\nYour task is simple: provide output containing the unique marker **BETA**.\n\nInclude in your output:\n- The marker string exactly as shown above\n- A brief note that you completed this step\n\nThis marker will be used in a future test to verify cross-chat session resumption works correctly."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "step-3-gamma",
|
|
19
|
+
"title": "Step 3: Gamma Marker",
|
|
20
|
+
"prompt": "You are testing WorkRail v2 session persistence.\n\nYour task is simple: provide output containing the unique marker **GAMMA**.\n\nInclude in your output:\n- The marker string exactly as shown above\n- A brief note that you completed this step\n\nThis marker will be used in a future test to verify cross-chat session resumption works correctly."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "step-4-delta",
|
|
24
|
+
"title": "Step 4: Delta Marker",
|
|
25
|
+
"prompt": "You are testing WorkRail v2 session persistence.\n\nYour task is simple: provide output containing the unique marker **DELTA**.\n\nInclude in your output:\n- The marker string exactly as shown above\n- A brief note that you completed this step\n\nThis is the penultimate step."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "step-5-final",
|
|
29
|
+
"title": "Step 5: Final Step",
|
|
30
|
+
"prompt": "You are testing WorkRail v2 session persistence.\n\nThis is the **final step**. Provide a summary:\n- How many unique markers did you write? (Should be 4: ALPHA, BETA, GAMMA, DELTA)\n- Did the workflow progress smoothly through all steps?\n- What CHAT_ID were you using?\n\nAfter you provide this output, the workflow will complete."
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|