@exaudeus/workrail 2.1.0 → 3.1.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/services/compiler/resolve-templates.d.ts +5 -0
- package/dist/application/services/compiler/resolve-templates.js +35 -0
- package/dist/application/services/compiler/routine-loader.d.ts +11 -0
- package/dist/application/services/compiler/routine-loader.js +45 -0
- package/dist/application/services/compiler/template-registry.d.ts +4 -2
- package/dist/application/services/compiler/template-registry.js +105 -4
- package/dist/application/services/workflow-compiler.js +34 -3
- package/dist/di/container.js +10 -1
- package/dist/di/tokens.d.ts +1 -0
- package/dist/di/tokens.js +1 -0
- package/dist/engine/engine-factory.d.ts +3 -0
- package/dist/engine/engine-factory.js +295 -0
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.js +12 -0
- package/dist/engine/types.d.ts +130 -0
- package/dist/engine/types.js +18 -0
- package/dist/manifest.json +146 -74
- package/dist/mcp/handlers/v2-checkpoint.d.ts +31 -1
- package/dist/mcp/handlers/v2-checkpoint.js +76 -64
- package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.js +5 -5
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +17 -22
- package/dist/mcp/handlers/v2-execution/index.d.ts +10 -17
- package/dist/mcp/handlers/v2-execution/index.js +44 -54
- package/dist/mcp/handlers/v2-execution/replay.d.ts +4 -15
- package/dist/mcp/handlers/v2-execution/replay.js +52 -128
- package/dist/mcp/handlers/v2-execution/start.d.ts +3 -2
- package/dist/mcp/handlers/v2-execution/start.js +18 -46
- package/dist/mcp/handlers/v2-token-ops.d.ts +45 -24
- package/dist/mcp/handlers/v2-token-ops.js +372 -32
- package/dist/mcp/output-schemas.d.ts +104 -283
- package/dist/mcp/output-schemas.js +24 -22
- package/dist/mcp/server.js +8 -0
- package/dist/mcp/types.d.ts +4 -0
- package/dist/mcp/v2/tools.d.ts +22 -52
- package/dist/mcp/v2/tools.js +18 -32
- package/dist/mcp/v2-response-formatter.js +12 -16
- package/dist/runtime/runtime-mode.d.ts +2 -0
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +5 -3
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +14 -14
- package/dist/v2/durable-core/schemas/session/events.d.ts +4 -4
- package/dist/v2/durable-core/schemas/session/validation-event.d.ts +2 -2
- package/dist/v2/durable-core/tokens/payloads.d.ts +32 -32
- package/dist/v2/durable-core/tokens/short-token.d.ts +38 -0
- package/dist/v2/durable-core/tokens/short-token.js +126 -0
- package/dist/v2/durable-core/tokens/token-patterns.d.ts +4 -0
- package/dist/v2/durable-core/tokens/token-patterns.js +9 -0
- package/dist/v2/infra/in-memory/token-alias-store/index.d.ts +11 -0
- package/dist/v2/infra/in-memory/token-alias-store/index.js +38 -0
- package/dist/v2/infra/local/data-dir/index.d.ts +1 -0
- package/dist/v2/infra/local/data-dir/index.js +3 -0
- package/dist/v2/infra/local/token-alias-store/index.d.ts +16 -0
- package/dist/v2/infra/local/token-alias-store/index.js +117 -0
- package/dist/v2/ports/data-dir.port.d.ts +1 -0
- package/dist/v2/ports/token-alias-store.port.d.ts +33 -0
- package/dist/v2/ports/token-alias-store.port.js +2 -0
- package/package.json +8 -1
- package/workflows/coding-task-workflow-agentic.lean.v2.json +41 -3
- package/workflows/examples/routine-injection-example.json +28 -0
|
@@ -183,51 +183,22 @@ function buildInitialEvents(args) {
|
|
|
183
183
|
return mutableEvents;
|
|
184
184
|
}
|
|
185
185
|
function mintStartTokens(args) {
|
|
186
|
-
const { sessionId, runId, nodeId, attemptId, workflowHashRef, ports } = args;
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
workflowHashRef,
|
|
186
|
+
const { sessionId, runId, nodeId, attemptId, workflowHashRef, ports, aliasStore, entropy } = args;
|
|
187
|
+
const entryBase = {
|
|
188
|
+
sessionId: String(sessionId),
|
|
189
|
+
runId: String(runId),
|
|
190
|
+
nodeId: String(nodeId),
|
|
191
|
+
attemptId: String(attemptId),
|
|
192
|
+
workflowHashRef: String(workflowHashRef),
|
|
194
193
|
};
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
nodeId,
|
|
201
|
-
attemptId,
|
|
202
|
-
};
|
|
203
|
-
const checkpointPayload = {
|
|
204
|
-
tokenVersion: 1,
|
|
205
|
-
tokenKind: 'checkpoint',
|
|
206
|
-
sessionId,
|
|
207
|
-
runId,
|
|
208
|
-
nodeId,
|
|
209
|
-
attemptId,
|
|
210
|
-
};
|
|
211
|
-
const stateTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({ payload: statePayload, ports });
|
|
212
|
-
if (stateTokenRes.isErr()) {
|
|
213
|
-
return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: stateTokenRes.error });
|
|
214
|
-
}
|
|
215
|
-
const ackTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({ payload: ackPayload, ports });
|
|
216
|
-
if (ackTokenRes.isErr()) {
|
|
217
|
-
return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: ackTokenRes.error });
|
|
218
|
-
}
|
|
219
|
-
const checkpointTokenRes = (0, v2_token_ops_js_1.signTokenOrErr)({ payload: checkpointPayload, ports });
|
|
220
|
-
if (checkpointTokenRes.isErr()) {
|
|
221
|
-
return (0, neverthrow_1.errAsync)({ kind: 'token_signing_failed', cause: checkpointTokenRes.error });
|
|
222
|
-
}
|
|
223
|
-
return (0, neverthrow_1.okAsync)({
|
|
224
|
-
stateToken: stateTokenRes.value,
|
|
225
|
-
ackToken: ackTokenRes.value,
|
|
226
|
-
checkpointToken: checkpointTokenRes.value,
|
|
227
|
-
});
|
|
194
|
+
return (0, v2_token_ops_js_1.mintContinueAndCheckpointTokens)({ entry: entryBase, ports, aliasStore, entropy })
|
|
195
|
+
.mapErr((failure) => ({
|
|
196
|
+
kind: 'token_signing_failed',
|
|
197
|
+
cause: failure,
|
|
198
|
+
}));
|
|
228
199
|
}
|
|
229
200
|
function executeStartWorkflow(input, ctx) {
|
|
230
|
-
const { gate, sessionStore, snapshotStore, pinnedStore, crypto, tokenCodecPorts, idFactory, validationPipelineDeps } = ctx.v2;
|
|
201
|
+
const { gate, sessionStore, snapshotStore, pinnedStore, crypto, tokenCodecPorts, idFactory, validationPipelineDeps, tokenAliasStore, entropy } = ctx.v2;
|
|
231
202
|
const workflowReader = (0, request_workflow_reader_js_1.hasRequestWorkspaceSignal)({
|
|
232
203
|
workspacePath: input.workspacePath,
|
|
233
204
|
resolvedRootUris: ctx.v2.resolvedRootUris,
|
|
@@ -315,6 +286,8 @@ function executeStartWorkflow(input, ctx) {
|
|
|
315
286
|
attemptId,
|
|
316
287
|
workflowHashRef: wfRefRes.value,
|
|
317
288
|
ports: tokenCodecPorts,
|
|
289
|
+
aliasStore: tokenAliasStore,
|
|
290
|
+
entropy,
|
|
318
291
|
}).andThen((tokens) => {
|
|
319
292
|
const metaResult = (0, prompt_renderer_js_1.renderPendingPrompt)({
|
|
320
293
|
workflow: pinnedWorkflow,
|
|
@@ -332,18 +305,17 @@ function executeStartWorkflow(input, ctx) {
|
|
|
332
305
|
});
|
|
333
306
|
}
|
|
334
307
|
const meta = metaResult.value;
|
|
335
|
-
const pending =
|
|
308
|
+
const pending = (0, output_schemas_js_1.toPendingStep)(meta);
|
|
336
309
|
const preferences = v2_execution_helpers_js_1.defaultPreferences;
|
|
337
310
|
const nextIntent = (0, v2_state_conversion_js_1.deriveNextIntent)({ rehydrateOnly: false, isComplete: false, pending: meta });
|
|
338
311
|
return (0, neverthrow_1.okAsync)(output_schemas_js_1.V2StartWorkflowOutputSchema.parse({
|
|
339
|
-
|
|
340
|
-
ackToken: tokens.ackToken,
|
|
312
|
+
continueToken: tokens.continueToken,
|
|
341
313
|
checkpointToken: tokens.checkpointToken,
|
|
342
314
|
isComplete: false,
|
|
343
315
|
pending,
|
|
344
316
|
preferences,
|
|
345
317
|
nextIntent,
|
|
346
|
-
nextCall: (0, index_js_2.buildNextCall)({
|
|
318
|
+
nextCall: (0, index_js_2.buildNextCall)({ continueToken: tokens.continueToken, isComplete: false, pending }),
|
|
347
319
|
}));
|
|
348
320
|
});
|
|
349
321
|
});
|
|
@@ -1,38 +1,59 @@
|
|
|
1
|
+
import type { ResultAsync } from 'neverthrow';
|
|
1
2
|
import type { Result } from 'neverthrow';
|
|
2
3
|
import { type ParsedTokenV1Binary, type TokenDecodeErrorV2, type TokenVerifyErrorV2, type TokenSignErrorV2, type TokenPayloadV1, type AttemptId } from '../../v2/durable-core/tokens/index.js';
|
|
3
4
|
import type { TokenCodecPorts } from '../../v2/durable-core/tokens/token-codec-ports.js';
|
|
4
5
|
import type { Sha256PortV2 } from '../../v2/ports/sha256.port.js';
|
|
5
6
|
import { type ToolFailure } from './v2-execution-helpers.js';
|
|
7
|
+
import type { TokenAliasStorePortV2, TokenAliasEntryV2 } from '../../v2/ports/token-alias-store.port.js';
|
|
8
|
+
import type { RandomEntropyPortV2 } from '../../v2/ports/random-entropy.port.js';
|
|
9
|
+
import type { StateTokenPayloadV1, AckTokenPayloadV1, CheckpointTokenPayloadV1 } from '../../v2/durable-core/tokens/payloads.js';
|
|
6
10
|
export type StateTokenInput = ParsedTokenV1Binary & {
|
|
7
|
-
readonly payload:
|
|
11
|
+
readonly payload: StateTokenPayloadV1;
|
|
8
12
|
};
|
|
9
13
|
export type AckTokenInput = ParsedTokenV1Binary & {
|
|
10
|
-
readonly payload:
|
|
14
|
+
readonly payload: AckTokenPayloadV1;
|
|
11
15
|
};
|
|
12
16
|
export type CheckpointTokenInput = ParsedTokenV1Binary & {
|
|
13
|
-
readonly payload:
|
|
14
|
-
};
|
|
15
|
-
export declare function parseStateTokenOrFail(raw: string, ports: TokenCodecPorts): {
|
|
16
|
-
ok: true;
|
|
17
|
-
token: StateTokenInput;
|
|
18
|
-
} | {
|
|
19
|
-
ok: false;
|
|
20
|
-
failure: ToolFailure;
|
|
21
|
-
};
|
|
22
|
-
export declare function parseAckTokenOrFail(raw: string, ports: TokenCodecPorts): {
|
|
23
|
-
ok: true;
|
|
24
|
-
token: AckTokenInput;
|
|
25
|
-
} | {
|
|
26
|
-
ok: false;
|
|
27
|
-
failure: ToolFailure;
|
|
28
|
-
};
|
|
29
|
-
export declare function parseCheckpointTokenOrFail(raw: string, ports: TokenCodecPorts): {
|
|
30
|
-
ok: true;
|
|
31
|
-
token: CheckpointTokenInput;
|
|
32
|
-
} | {
|
|
33
|
-
ok: false;
|
|
34
|
-
failure: ToolFailure;
|
|
17
|
+
readonly payload: CheckpointTokenPayloadV1;
|
|
35
18
|
};
|
|
19
|
+
export interface ContinueTokenResolved {
|
|
20
|
+
readonly sessionId: string;
|
|
21
|
+
readonly runId: string;
|
|
22
|
+
readonly nodeId: string;
|
|
23
|
+
readonly attemptId: string;
|
|
24
|
+
readonly workflowHashRef: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function parseStateTokenOrFail(raw: string, ports: TokenCodecPorts, aliasStore: TokenAliasStorePortV2): ResultAsync<StateTokenInput, ToolFailure>;
|
|
27
|
+
export declare function parseAckTokenOrFail(raw: string, ports: TokenCodecPorts, aliasStore: TokenAliasStorePortV2): ResultAsync<AckTokenInput, ToolFailure>;
|
|
28
|
+
export declare function parseCheckpointTokenOrFail(raw: string, ports: TokenCodecPorts, aliasStore: TokenAliasStorePortV2): ResultAsync<CheckpointTokenInput, ToolFailure>;
|
|
29
|
+
export declare function parseContinueTokenOrFail(raw: string, ports: TokenCodecPorts, aliasStore: TokenAliasStorePortV2): ResultAsync<ContinueTokenResolved, ToolFailure>;
|
|
30
|
+
export interface ContinueAndCheckpointTokens {
|
|
31
|
+
readonly continueToken: string;
|
|
32
|
+
readonly checkpointToken: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function mintContinueAndCheckpointTokens(args: Omit<MintShortTokenTripleArgs, 'entry'> & {
|
|
35
|
+
readonly entry: Omit<TokenAliasEntryV2, 'nonceHex' | 'tokenKind'>;
|
|
36
|
+
}): ResultAsync<ContinueAndCheckpointTokens, ToolFailure>;
|
|
37
|
+
export interface ShortTokenTriple {
|
|
38
|
+
readonly stateToken: string;
|
|
39
|
+
readonly ackToken: string;
|
|
40
|
+
readonly checkpointToken: string;
|
|
41
|
+
}
|
|
42
|
+
export interface MintShortTokenTripleArgs {
|
|
43
|
+
readonly entry: Omit<TokenAliasEntryV2, 'nonceHex' | 'tokenKind'>;
|
|
44
|
+
readonly ports: TokenCodecPorts;
|
|
45
|
+
readonly aliasStore: TokenAliasStorePortV2;
|
|
46
|
+
readonly entropy: RandomEntropyPortV2;
|
|
47
|
+
}
|
|
48
|
+
export declare function mintShortTokenTriple(args: MintShortTokenTripleArgs): ResultAsync<ShortTokenTriple, ToolFailure>;
|
|
49
|
+
export interface MintSingleShortTokenArgs {
|
|
50
|
+
readonly kind: import('../../v2/durable-core/tokens/short-token.js').ShortTokenKind;
|
|
51
|
+
readonly entry: Omit<TokenAliasEntryV2, 'nonceHex' | 'tokenKind'>;
|
|
52
|
+
readonly ports: TokenCodecPorts;
|
|
53
|
+
readonly aliasStore: TokenAliasStorePortV2;
|
|
54
|
+
readonly entropy: RandomEntropyPortV2;
|
|
55
|
+
}
|
|
56
|
+
export declare function mintSingleShortToken(args: MintSingleShortTokenArgs): ResultAsync<string, ToolFailure>;
|
|
36
57
|
export declare function newAttemptId(idFactory: {
|
|
37
58
|
readonly mintAttemptId: () => AttemptId;
|
|
38
59
|
}): AttemptId;
|
|
@@ -3,70 +3,410 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseStateTokenOrFail = parseStateTokenOrFail;
|
|
4
4
|
exports.parseAckTokenOrFail = parseAckTokenOrFail;
|
|
5
5
|
exports.parseCheckpointTokenOrFail = parseCheckpointTokenOrFail;
|
|
6
|
+
exports.parseContinueTokenOrFail = parseContinueTokenOrFail;
|
|
7
|
+
exports.mintContinueAndCheckpointTokens = mintContinueAndCheckpointTokens;
|
|
8
|
+
exports.mintShortTokenTriple = mintShortTokenTriple;
|
|
9
|
+
exports.mintSingleShortToken = mintSingleShortToken;
|
|
6
10
|
exports.newAttemptId = newAttemptId;
|
|
7
11
|
exports.attemptIdForNextNode = attemptIdForNextNode;
|
|
8
12
|
exports.signTokenOrErr = signTokenOrErr;
|
|
9
13
|
const neverthrow_1 = require("neverthrow");
|
|
14
|
+
const neverthrow_2 = require("neverthrow");
|
|
10
15
|
const index_js_1 = require("../../v2/durable-core/tokens/index.js");
|
|
11
16
|
const attempt_id_derivation_js_1 = require("../../v2/durable-core/ids/attempt-id-derivation.js");
|
|
12
17
|
const types_js_1 = require("../types.js");
|
|
13
18
|
const v2_execution_helpers_js_1 = require("./v2-execution-helpers.js");
|
|
14
|
-
|
|
19
|
+
const short_token_js_1 = require("../../v2/durable-core/tokens/short-token.js");
|
|
20
|
+
const index_js_2 = require("../../v2/durable-core/ids/index.js");
|
|
21
|
+
function resolveShortToken(raw, ports, aliasStore) {
|
|
22
|
+
const parsed = (0, short_token_js_1.parseShortToken)(raw, ports.base64url);
|
|
23
|
+
if (parsed.isErr()) {
|
|
24
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', `Short token format invalid: ${parsed.error.code}`, {
|
|
25
|
+
suggestion: 'Use the token returned by WorkRail (st_... / ak_... / ck_...).',
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
const hmacResult = (0, short_token_js_1.verifyShortTokenHmac)(parsed.value, ports.keyring, ports.hmac, ports.base64url);
|
|
29
|
+
if (hmacResult.isErr()) {
|
|
30
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_BAD_SIGNATURE', 'Short token HMAC verification failed.', {
|
|
31
|
+
suggestion: 'Use the exact token returned by WorkRail — do not modify it.',
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
const entry = aliasStore.lookup(parsed.value.nonceHex);
|
|
35
|
+
if (!entry) {
|
|
36
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Short token not found in alias index (unknown nonce).', {
|
|
37
|
+
suggestion: 'Use the token returned by WorkRail in the current session.',
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
let payload;
|
|
41
|
+
if (entry.tokenKind === 'state') {
|
|
42
|
+
if (!entry.workflowHashRef) {
|
|
43
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Alias entry for state token is missing workflowHashRef.'));
|
|
44
|
+
}
|
|
45
|
+
const statePayload = {
|
|
46
|
+
tokenVersion: 1,
|
|
47
|
+
tokenKind: 'state',
|
|
48
|
+
sessionId: (0, index_js_2.asSessionId)(entry.sessionId),
|
|
49
|
+
runId: (0, index_js_2.asRunId)(entry.runId),
|
|
50
|
+
nodeId: (0, index_js_2.asNodeId)(entry.nodeId),
|
|
51
|
+
workflowHashRef: (0, index_js_2.asWorkflowHashRef)(entry.workflowHashRef),
|
|
52
|
+
};
|
|
53
|
+
payload = statePayload;
|
|
54
|
+
}
|
|
55
|
+
else if (entry.tokenKind === 'ack') {
|
|
56
|
+
if (!entry.attemptId) {
|
|
57
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Alias entry for ack token is missing attemptId.'));
|
|
58
|
+
}
|
|
59
|
+
const ackPayload = {
|
|
60
|
+
tokenVersion: 1,
|
|
61
|
+
tokenKind: 'ack',
|
|
62
|
+
sessionId: (0, index_js_2.asSessionId)(entry.sessionId),
|
|
63
|
+
runId: (0, index_js_2.asRunId)(entry.runId),
|
|
64
|
+
nodeId: (0, index_js_2.asNodeId)(entry.nodeId),
|
|
65
|
+
attemptId: (0, index_js_2.asAttemptId)(entry.attemptId),
|
|
66
|
+
};
|
|
67
|
+
payload = ackPayload;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (!entry.attemptId) {
|
|
71
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Alias entry for checkpoint token is missing attemptId.'));
|
|
72
|
+
}
|
|
73
|
+
const ckPayload = {
|
|
74
|
+
tokenVersion: 1,
|
|
75
|
+
tokenKind: 'checkpoint',
|
|
76
|
+
sessionId: (0, index_js_2.asSessionId)(entry.sessionId),
|
|
77
|
+
runId: (0, index_js_2.asRunId)(entry.runId),
|
|
78
|
+
nodeId: (0, index_js_2.asNodeId)(entry.nodeId),
|
|
79
|
+
attemptId: (0, index_js_2.asAttemptId)(entry.attemptId),
|
|
80
|
+
};
|
|
81
|
+
payload = ckPayload;
|
|
82
|
+
}
|
|
83
|
+
const synthetic = {
|
|
84
|
+
hrp: entry.tokenKind === 'state' ? 'st' : entry.tokenKind === 'ack' ? 'ack' : 'chk',
|
|
85
|
+
version: '1',
|
|
86
|
+
payloadBytes: new Uint8Array(66),
|
|
87
|
+
signatureBytes: new Uint8Array(32),
|
|
88
|
+
payload,
|
|
89
|
+
};
|
|
90
|
+
return (0, neverthrow_1.okAsync)(synthetic);
|
|
91
|
+
}
|
|
92
|
+
function parseStateTokenOrFail(raw, ports, aliasStore) {
|
|
93
|
+
if (raw.startsWith('st_')) {
|
|
94
|
+
return resolveShortToken(raw, ports, aliasStore).andThen((resolved) => {
|
|
95
|
+
if (resolved.payload.tokenKind !== 'state') {
|
|
96
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected a state token (st_... or st1...).', {
|
|
97
|
+
suggestion: 'Use the stateToken returned by WorkRail.',
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
return (0, neverthrow_1.okAsync)(resolved);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
15
103
|
const parsedRes = (0, index_js_1.parseTokenV1Binary)(raw, ports);
|
|
16
104
|
if (parsedRes.isErr()) {
|
|
17
|
-
return
|
|
105
|
+
return (0, neverthrow_1.errAsync)((0, v2_execution_helpers_js_1.mapTokenDecodeErrorToToolError)(parsedRes.error));
|
|
18
106
|
}
|
|
19
107
|
const verified = (0, index_js_1.verifyTokenSignatureV1Binary)(parsedRes.value, ports);
|
|
20
108
|
if (verified.isErr()) {
|
|
21
|
-
return
|
|
109
|
+
return (0, neverthrow_1.errAsync)((0, v2_execution_helpers_js_1.mapTokenVerifyErrorToToolError)(verified.error));
|
|
22
110
|
}
|
|
23
111
|
if (parsedRes.value.payload.tokenKind !== 'state') {
|
|
24
|
-
return {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
suggestion: 'Use the stateToken returned by WorkRail.',
|
|
28
|
-
}),
|
|
29
|
-
};
|
|
112
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected a state token (st1...).', {
|
|
113
|
+
suggestion: 'Use the stateToken returned by WorkRail.',
|
|
114
|
+
}));
|
|
30
115
|
}
|
|
31
|
-
return
|
|
116
|
+
return (0, neverthrow_1.okAsync)(parsedRes.value);
|
|
32
117
|
}
|
|
33
|
-
function parseAckTokenOrFail(raw, ports) {
|
|
118
|
+
function parseAckTokenOrFail(raw, ports, aliasStore) {
|
|
119
|
+
if (raw.startsWith('ak_')) {
|
|
120
|
+
return resolveShortToken(raw, ports, aliasStore).andThen((resolved) => {
|
|
121
|
+
if (resolved.payload.tokenKind !== 'ack') {
|
|
122
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected an ack token (ak_... or ack1...).', {
|
|
123
|
+
suggestion: 'Use the ackToken returned by WorkRail.',
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
return (0, neverthrow_1.okAsync)(resolved);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
34
129
|
const parsedRes = (0, index_js_1.parseTokenV1Binary)(raw, ports);
|
|
35
130
|
if (parsedRes.isErr()) {
|
|
36
|
-
return
|
|
131
|
+
return (0, neverthrow_1.errAsync)((0, v2_execution_helpers_js_1.mapTokenDecodeErrorToToolError)(parsedRes.error));
|
|
37
132
|
}
|
|
38
133
|
const verified = (0, index_js_1.verifyTokenSignatureV1Binary)(parsedRes.value, ports);
|
|
39
134
|
if (verified.isErr()) {
|
|
40
|
-
return
|
|
135
|
+
return (0, neverthrow_1.errAsync)((0, v2_execution_helpers_js_1.mapTokenVerifyErrorToToolError)(verified.error));
|
|
41
136
|
}
|
|
42
137
|
if (parsedRes.value.payload.tokenKind !== 'ack') {
|
|
43
|
-
return {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
suggestion: 'Use the ackToken returned by WorkRail.',
|
|
47
|
-
}),
|
|
48
|
-
};
|
|
138
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected an ack token (ack1...).', {
|
|
139
|
+
suggestion: 'Use the ackToken returned by WorkRail.',
|
|
140
|
+
}));
|
|
49
141
|
}
|
|
50
|
-
return
|
|
142
|
+
return (0, neverthrow_1.okAsync)(parsedRes.value);
|
|
51
143
|
}
|
|
52
|
-
function parseCheckpointTokenOrFail(raw, ports) {
|
|
144
|
+
function parseCheckpointTokenOrFail(raw, ports, aliasStore) {
|
|
145
|
+
if (raw.startsWith('ck_')) {
|
|
146
|
+
return resolveShortToken(raw, ports, aliasStore).andThen((resolved) => {
|
|
147
|
+
if (resolved.payload.tokenKind !== 'checkpoint') {
|
|
148
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected a checkpoint token (ck_... or chk1...).', {
|
|
149
|
+
suggestion: 'Use the checkpointToken returned by WorkRail.',
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
return (0, neverthrow_1.okAsync)(resolved);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
53
155
|
const parsedRes = (0, index_js_1.parseTokenV1Binary)(raw, ports);
|
|
54
156
|
if (parsedRes.isErr()) {
|
|
55
|
-
return
|
|
157
|
+
return (0, neverthrow_1.errAsync)((0, v2_execution_helpers_js_1.mapTokenDecodeErrorToToolError)(parsedRes.error));
|
|
56
158
|
}
|
|
57
159
|
const verified = (0, index_js_1.verifyTokenSignatureV1Binary)(parsedRes.value, ports);
|
|
58
160
|
if (verified.isErr()) {
|
|
59
|
-
return
|
|
161
|
+
return (0, neverthrow_1.errAsync)((0, v2_execution_helpers_js_1.mapTokenVerifyErrorToToolError)(verified.error));
|
|
60
162
|
}
|
|
61
163
|
if (parsedRes.value.payload.tokenKind !== 'checkpoint') {
|
|
62
|
-
return {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
164
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected a checkpoint token (chk1...).', {
|
|
165
|
+
suggestion: 'Use the checkpointToken returned by WorkRail.',
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
return (0, neverthrow_1.okAsync)(parsedRes.value);
|
|
169
|
+
}
|
|
170
|
+
function parseContinueTokenOrFail(raw, ports, aliasStore) {
|
|
171
|
+
if (!raw.startsWith('ct_')) {
|
|
172
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Expected a continue token (ct_...).', {
|
|
173
|
+
suggestion: 'Use the continueToken returned by WorkRail.',
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
const parsed = (0, short_token_js_1.parseShortToken)(raw, ports.base64url);
|
|
177
|
+
if (parsed.isErr()) {
|
|
178
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', `Continue token format invalid: ${parsed.error.code}`, {
|
|
179
|
+
suggestion: 'Use the continueToken returned by WorkRail.',
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
const hmacResult = (0, short_token_js_1.verifyShortTokenHmac)(parsed.value, ports.keyring, ports.hmac, ports.base64url);
|
|
183
|
+
if (hmacResult.isErr()) {
|
|
184
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_BAD_SIGNATURE', 'Continue token HMAC verification failed.', {
|
|
185
|
+
suggestion: 'Use the exact continueToken returned by WorkRail -- do not modify it.',
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
const entry = aliasStore.lookup(parsed.value.nonceHex);
|
|
189
|
+
if (!entry) {
|
|
190
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Continue token not found in alias index (unknown nonce).', {
|
|
191
|
+
suggestion: 'Use the continueToken returned by WorkRail in the current session.',
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
if (entry.tokenKind !== 'continue') {
|
|
195
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Token alias is not a continue token.', {
|
|
196
|
+
suggestion: 'Use the continueToken returned by WorkRail.',
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
if (!entry.attemptId || !entry.workflowHashRef) {
|
|
200
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('TOKEN_INVALID_FORMAT', 'Continue token alias entry is missing required fields.', {
|
|
201
|
+
suggestion: 'Use the continueToken returned by WorkRail.',
|
|
202
|
+
}));
|
|
203
|
+
}
|
|
204
|
+
return (0, neverthrow_1.okAsync)({
|
|
205
|
+
sessionId: entry.sessionId,
|
|
206
|
+
runId: entry.runId,
|
|
207
|
+
nodeId: entry.nodeId,
|
|
208
|
+
attemptId: entry.attemptId,
|
|
209
|
+
workflowHashRef: entry.workflowHashRef,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function mintContinueAndCheckpointTokens(args) {
|
|
213
|
+
const { entry, ports, aliasStore, entropy } = args;
|
|
214
|
+
const existingContinue = aliasStore.lookupByPosition('continue', entry.sessionId, entry.nodeId, entry.attemptId, entry.aliasSlot);
|
|
215
|
+
const existingCk = aliasStore.lookupByPosition('checkpoint', entry.sessionId, entry.nodeId, entry.attemptId, entry.aliasSlot);
|
|
216
|
+
if (existingContinue && existingCk) {
|
|
217
|
+
const replayContinue = reTokenFromNonceHex('continue', existingContinue.nonceHex, ports);
|
|
218
|
+
const replayCk = reTokenFromNonceHex('checkpoint', existingCk.nonceHex, ports);
|
|
219
|
+
if (replayContinue.isOk() && replayCk.isOk()) {
|
|
220
|
+
return (0, neverthrow_1.okAsync)({
|
|
221
|
+
continueToken: replayContinue.value,
|
|
222
|
+
checkpointToken: replayCk.value,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const continueNonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
227
|
+
const continueMinted = (0, short_token_js_1.mintShortToken)('continue', continueNonce, ports.keyring, ports.hmac, ports.base64url);
|
|
228
|
+
if (continueMinted.isErr()) {
|
|
229
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Token minting failed: ${continueMinted.error.code}`));
|
|
230
|
+
}
|
|
231
|
+
const continueNonceHex = bufToHex(continueNonce);
|
|
232
|
+
let ckTokenStr;
|
|
233
|
+
if (existingCk) {
|
|
234
|
+
const replayCk = reTokenFromNonceHex('checkpoint', existingCk.nonceHex, ports);
|
|
235
|
+
if (replayCk.isOk()) {
|
|
236
|
+
const continueEntry = {
|
|
237
|
+
nonceHex: continueNonceHex, tokenKind: 'continue', aliasSlot: entry.aliasSlot,
|
|
238
|
+
sessionId: entry.sessionId, runId: entry.runId, nodeId: entry.nodeId,
|
|
239
|
+
attemptId: entry.attemptId, workflowHashRef: entry.workflowHashRef,
|
|
240
|
+
};
|
|
241
|
+
return aliasStore.register(continueEntry)
|
|
242
|
+
.map(() => ({ continueToken: continueMinted.value, checkpointToken: replayCk.value }))
|
|
243
|
+
.mapErr((regErr) => (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Alias registration failed: ${regErr.code}`));
|
|
244
|
+
}
|
|
245
|
+
const ckNonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
246
|
+
const ckMinted = (0, short_token_js_1.mintShortToken)('checkpoint', ckNonce, ports.keyring, ports.hmac, ports.base64url);
|
|
247
|
+
if (ckMinted.isErr())
|
|
248
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Token minting failed: ${ckMinted.error.code}`));
|
|
249
|
+
ckTokenStr = ckMinted.value;
|
|
250
|
+
const ckEntry = { nonceHex: bufToHex(ckNonce), tokenKind: 'checkpoint', aliasSlot: entry.aliasSlot, sessionId: entry.sessionId, runId: entry.runId, nodeId: entry.nodeId, attemptId: entry.attemptId };
|
|
251
|
+
return aliasStore.register({ nonceHex: continueNonceHex, tokenKind: 'continue', aliasSlot: entry.aliasSlot, sessionId: entry.sessionId, runId: entry.runId, nodeId: entry.nodeId, attemptId: entry.attemptId, workflowHashRef: entry.workflowHashRef })
|
|
252
|
+
.andThen(() => aliasStore.register(ckEntry))
|
|
253
|
+
.map(() => ({ continueToken: continueMinted.value, checkpointToken: ckTokenStr }))
|
|
254
|
+
.mapErr((regErr) => (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Alias registration failed: ${regErr.code}`));
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
const ckNonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
258
|
+
const ckMinted = (0, short_token_js_1.mintShortToken)('checkpoint', ckNonce, ports.keyring, ports.hmac, ports.base64url);
|
|
259
|
+
if (ckMinted.isErr())
|
|
260
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Token minting failed: ${ckMinted.error.code}`));
|
|
261
|
+
ckTokenStr = ckMinted.value;
|
|
262
|
+
const ckEntry = { nonceHex: bufToHex(ckNonce), tokenKind: 'checkpoint', aliasSlot: entry.aliasSlot, sessionId: entry.sessionId, runId: entry.runId, nodeId: entry.nodeId, attemptId: entry.attemptId };
|
|
263
|
+
return aliasStore.register({ nonceHex: continueNonceHex, tokenKind: 'continue', aliasSlot: entry.aliasSlot, sessionId: entry.sessionId, runId: entry.runId, nodeId: entry.nodeId, attemptId: entry.attemptId, workflowHashRef: entry.workflowHashRef })
|
|
264
|
+
.andThen(() => aliasStore.register(ckEntry))
|
|
265
|
+
.map(() => ({ continueToken: continueMinted.value, checkpointToken: ckTokenStr }))
|
|
266
|
+
.mapErr((regErr) => (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Alias registration failed: ${regErr.code}`));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function reTokenFromNonceHex(kind, nonceHex, ports) {
|
|
270
|
+
const nonceBytes = hexToBuf(nonceHex);
|
|
271
|
+
if (!nonceBytes) {
|
|
272
|
+
return (0, neverthrow_2.err)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Invalid stored nonce hex: ${nonceHex}`));
|
|
273
|
+
}
|
|
274
|
+
const result = (0, short_token_js_1.mintShortToken)(kind, nonceBytes, ports.keyring, ports.hmac, ports.base64url);
|
|
275
|
+
if (result.isErr()) {
|
|
276
|
+
return (0, neverthrow_2.err)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Failed to reconstruct token from nonce: ${result.error.code}`));
|
|
277
|
+
}
|
|
278
|
+
return (0, neverthrow_2.ok)(result.value);
|
|
279
|
+
}
|
|
280
|
+
function mintShortTokenTriple(args) {
|
|
281
|
+
const { entry, ports, aliasStore, entropy } = args;
|
|
282
|
+
const existingState = aliasStore.lookupByPosition('state', entry.sessionId, entry.nodeId, undefined, entry.aliasSlot);
|
|
283
|
+
const existingAck = aliasStore.lookupByPosition('ack', entry.sessionId, entry.nodeId, entry.attemptId, entry.aliasSlot);
|
|
284
|
+
const existingCk = aliasStore.lookupByPosition('checkpoint', entry.sessionId, entry.nodeId, entry.attemptId, entry.aliasSlot);
|
|
285
|
+
if (existingState && existingAck && existingCk) {
|
|
286
|
+
const replayState = reTokenFromNonceHex('state', existingState.nonceHex, ports);
|
|
287
|
+
const replayAck = reTokenFromNonceHex('ack', existingAck.nonceHex, ports);
|
|
288
|
+
const replayCk = reTokenFromNonceHex('checkpoint', existingCk.nonceHex, ports);
|
|
289
|
+
if (replayState.isOk() && replayAck.isOk() && replayCk.isOk()) {
|
|
290
|
+
return (0, neverthrow_1.okAsync)({
|
|
291
|
+
stateToken: replayState.value,
|
|
292
|
+
ackToken: replayAck.value,
|
|
293
|
+
checkpointToken: replayCk.value,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const stateNonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
298
|
+
const ackNonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
299
|
+
const ckNonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
300
|
+
const stateMinted = (0, short_token_js_1.mintShortToken)('state', stateNonce, ports.keyring, ports.hmac, ports.base64url);
|
|
301
|
+
const ackMinted = (0, short_token_js_1.mintShortToken)('ack', ackNonce, ports.keyring, ports.hmac, ports.base64url);
|
|
302
|
+
const ckMinted = (0, short_token_js_1.mintShortToken)('checkpoint', ckNonce, ports.keyring, ports.hmac, ports.base64url);
|
|
303
|
+
if (stateMinted.isErr() || ackMinted.isErr() || ckMinted.isErr()) {
|
|
304
|
+
const msg = stateMinted.isErr()
|
|
305
|
+
? stateMinted.error.code
|
|
306
|
+
: ackMinted.isErr()
|
|
307
|
+
? ackMinted.error.code
|
|
308
|
+
: ckMinted.isErr()
|
|
309
|
+
? ckMinted.error.code
|
|
310
|
+
: 'UNKNOWN';
|
|
311
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Short token minting failed: ${msg}`));
|
|
312
|
+
}
|
|
313
|
+
const stateTokenStr = stateMinted.value;
|
|
314
|
+
const ackTokenStr = ackMinted.value;
|
|
315
|
+
const ckTokenStr = ckMinted.value;
|
|
316
|
+
const stateNonceHex = bufToHex(stateNonce);
|
|
317
|
+
const ackNonceHex = bufToHex(ackNonce);
|
|
318
|
+
const ckNonceHex = bufToHex(ckNonce);
|
|
319
|
+
const stateEntry = {
|
|
320
|
+
nonceHex: stateNonceHex,
|
|
321
|
+
tokenKind: 'state',
|
|
322
|
+
aliasSlot: entry.aliasSlot,
|
|
323
|
+
sessionId: entry.sessionId,
|
|
324
|
+
runId: entry.runId,
|
|
325
|
+
nodeId: entry.nodeId,
|
|
326
|
+
workflowHashRef: entry.workflowHashRef,
|
|
327
|
+
};
|
|
328
|
+
const ackEntry = {
|
|
329
|
+
nonceHex: ackNonceHex,
|
|
330
|
+
tokenKind: 'ack',
|
|
331
|
+
aliasSlot: entry.aliasSlot,
|
|
332
|
+
sessionId: entry.sessionId,
|
|
333
|
+
runId: entry.runId,
|
|
334
|
+
nodeId: entry.nodeId,
|
|
335
|
+
attemptId: entry.attemptId,
|
|
336
|
+
};
|
|
337
|
+
const ckEntry = {
|
|
338
|
+
nonceHex: ckNonceHex,
|
|
339
|
+
tokenKind: 'checkpoint',
|
|
340
|
+
aliasSlot: entry.aliasSlot,
|
|
341
|
+
sessionId: entry.sessionId,
|
|
342
|
+
runId: entry.runId,
|
|
343
|
+
nodeId: entry.nodeId,
|
|
344
|
+
attemptId: entry.attemptId,
|
|
345
|
+
};
|
|
346
|
+
return aliasStore.register(stateEntry)
|
|
347
|
+
.andThen(() => aliasStore.register(ackEntry))
|
|
348
|
+
.andThen(() => aliasStore.register(ckEntry))
|
|
349
|
+
.map(() => ({
|
|
350
|
+
stateToken: stateTokenStr,
|
|
351
|
+
ackToken: ackTokenStr,
|
|
352
|
+
checkpointToken: ckTokenStr,
|
|
353
|
+
}))
|
|
354
|
+
.mapErr((regErr) => {
|
|
355
|
+
const detail = regErr.code === 'ALIAS_DUPLICATE_NONCE'
|
|
356
|
+
? `duplicate nonce: ${regErr.nonceHex}`
|
|
357
|
+
: regErr.message;
|
|
358
|
+
return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Token alias registration failed: ${detail}`);
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
function mintSingleShortToken(args) {
|
|
362
|
+
const { kind, entry, ports, aliasStore, entropy } = args;
|
|
363
|
+
const lookupAttemptId = kind === 'state' ? undefined : entry.attemptId;
|
|
364
|
+
const existing = aliasStore.lookupByPosition(kind, entry.sessionId, entry.nodeId, lookupAttemptId, entry.aliasSlot);
|
|
365
|
+
if (existing) {
|
|
366
|
+
const rebuilt = reTokenFromNonceHex(kind, existing.nonceHex, ports);
|
|
367
|
+
if (rebuilt.isOk())
|
|
368
|
+
return (0, neverthrow_1.okAsync)(rebuilt.value);
|
|
369
|
+
}
|
|
370
|
+
const nonce = entropy.generateBytes(short_token_js_1.SHORT_TOKEN_NONCE_BYTES);
|
|
371
|
+
const minted = (0, short_token_js_1.mintShortToken)(kind, nonce, ports.keyring, ports.hmac, ports.base64url);
|
|
372
|
+
if (minted.isErr()) {
|
|
373
|
+
return (0, neverthrow_1.errAsync)((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Short token minting failed: ${minted.error.code}`));
|
|
374
|
+
}
|
|
375
|
+
const tokenStr = minted.value;
|
|
376
|
+
const nonceHex = bufToHex(nonce);
|
|
377
|
+
const aliasEntry = {
|
|
378
|
+
nonceHex,
|
|
379
|
+
tokenKind: kind,
|
|
380
|
+
aliasSlot: entry.aliasSlot,
|
|
381
|
+
sessionId: entry.sessionId,
|
|
382
|
+
runId: entry.runId,
|
|
383
|
+
nodeId: entry.nodeId,
|
|
384
|
+
attemptId: entry.attemptId,
|
|
385
|
+
workflowHashRef: entry.workflowHashRef,
|
|
386
|
+
};
|
|
387
|
+
return aliasStore.register(aliasEntry)
|
|
388
|
+
.map(() => tokenStr)
|
|
389
|
+
.mapErr((regErr) => {
|
|
390
|
+
const detail = regErr.code === 'ALIAS_DUPLICATE_NONCE'
|
|
391
|
+
? `duplicate nonce: ${regErr.nonceHex}`
|
|
392
|
+
: regErr.message;
|
|
393
|
+
return (0, types_js_1.errNotRetryable)('INTERNAL_ERROR', `Token alias registration failed: ${detail}`);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
function bufToHex(bytes) {
|
|
397
|
+
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
398
|
+
}
|
|
399
|
+
function hexToBuf(hex) {
|
|
400
|
+
if (hex.length % 2 !== 0)
|
|
401
|
+
return null;
|
|
402
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
403
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
404
|
+
const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
405
|
+
if (isNaN(byte))
|
|
406
|
+
return null;
|
|
407
|
+
bytes[i] = byte;
|
|
68
408
|
}
|
|
69
|
-
return
|
|
409
|
+
return bytes;
|
|
70
410
|
}
|
|
71
411
|
function newAttemptId(idFactory) {
|
|
72
412
|
return idFactory.mintAttemptId();
|
|
@@ -77,6 +417,6 @@ function attemptIdForNextNode(parentAttemptId, sha256) {
|
|
|
77
417
|
function signTokenOrErr(args) {
|
|
78
418
|
const token = (0, index_js_1.signTokenV1Binary)(args.payload, args.ports);
|
|
79
419
|
if (token.isErr())
|
|
80
|
-
return (0,
|
|
81
|
-
return (0,
|
|
420
|
+
return (0, neverthrow_2.err)(token.error);
|
|
421
|
+
return (0, neverthrow_2.ok)(token.value);
|
|
82
422
|
}
|