@pikku/core 0.12.63 → 0.12.66
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/CHANGELOG.md +368 -0
- package/dist/dev/hot-reload.js +13 -55
- package/dist/dev/module-runner.d.ts +14 -0
- package/dist/dev/module-runner.js +59 -0
- package/dist/dev/reload-meta.d.ts +13 -0
- package/dist/dev/reload-meta.js +22 -0
- package/dist/errors/errors.d.ts +12 -0
- package/dist/errors/errors.js +19 -0
- package/dist/function/function-runner.d.ts +5 -5
- package/dist/function/function-runner.js +39 -111
- package/dist/function/functions.types.d.ts +17 -7
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -1
- package/dist/middleware/auth-apikey.d.ts +1 -0
- package/dist/middleware/auth-bearer.d.ts +1 -0
- package/dist/middleware/auth-cookie.d.ts +1 -0
- package/dist/middleware/cors.d.ts +1 -0
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/remote-auth.d.ts +1 -0
- package/dist/middleware/telemetry.d.ts +2 -0
- package/dist/middleware/timeout.d.ts +1 -0
- package/dist/permissions.d.ts +42 -27
- package/dist/permissions.js +101 -203
- package/dist/pikku-state.js +0 -2
- package/dist/scopes.d.ts +17 -0
- package/dist/scopes.js +59 -0
- package/dist/services/ai-embedding-service.d.ts +31 -0
- package/dist/services/ai-embedding-service.js +1 -0
- package/dist/services/credential-wire-service.d.ts +3 -1
- package/dist/services/credential-wire-service.js +10 -4
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.js +2 -0
- package/dist/services/meta-service.d.ts +15 -2
- package/dist/services/meta-service.js +51 -1
- package/dist/services/queue-webhook-service.d.ts +55 -0
- package/dist/services/queue-webhook-service.js +136 -0
- package/dist/services/scope-service.d.ts +67 -0
- package/dist/services/scope-service.js +1 -0
- package/dist/services/typed-secret-service.d.ts +8 -0
- package/dist/services/typed-secret-service.js +39 -4
- package/dist/services/webhook-service.d.ts +140 -0
- package/dist/services/webhook-service.js +44 -0
- package/dist/services/workflow-service.d.ts +7 -0
- package/dist/testing/service-tests.js +37 -0
- package/dist/types/core.types.d.ts +34 -6
- package/dist/types/state.types.d.ts +20 -2
- package/dist/utils/hmac.d.ts +16 -0
- package/dist/utils/hmac.js +26 -0
- package/dist/utils/safe-fetch.d.ts +51 -0
- package/dist/utils/safe-fetch.js +192 -0
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +84 -0
- package/dist/wirings/ai-agent/ai-agent-agui.js +305 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +105 -1
- package/dist/wirings/ai-agent/ai-agent-prepare.js +249 -11
- package/dist/wirings/ai-agent/ai-agent-runner.js +10 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +88 -16
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +56 -2
- package/dist/wirings/ai-agent/index.d.ts +2 -1
- package/dist/wirings/ai-agent/index.js +2 -1
- package/dist/wirings/ai-agent/voice-input.d.ts +1 -0
- package/dist/wirings/ai-agent/voice-input.js +5 -41
- package/dist/wirings/ai-agent/voice-output.d.ts +1 -0
- package/dist/wirings/channel/channel-common.js +0 -1
- package/dist/wirings/channel/channel-handler.js +1 -4
- package/dist/wirings/channel/channel-middleware-runner.d.ts +12 -0
- package/dist/wirings/channel/channel-middleware-runner.js +34 -19
- package/dist/wirings/channel/channel.types.d.ts +2 -6
- package/dist/wirings/cli/cli-runner.js +3 -2
- package/dist/wirings/cli/cli.types.d.ts +1 -2
- package/dist/wirings/cli/command-parser.d.ts +2 -0
- package/dist/wirings/cli/command-parser.js +59 -2
- package/dist/wirings/credential/credential.types.d.ts +14 -0
- package/dist/wirings/credential/validate-credential-definitions.js +1 -0
- package/dist/wirings/gateway/gateway-runner.js +100 -50
- package/dist/wirings/gateway/gateway.types.d.ts +8 -5
- package/dist/wirings/http/http-routes.js +0 -3
- package/dist/wirings/http/http-runner.d.ts +9 -29
- package/dist/wirings/http/http-runner.js +9 -34
- package/dist/wirings/http/http.types.d.ts +4 -12
- package/dist/wirings/mcp/mcp-runner.js +0 -2
- package/dist/wirings/mcp/mcp.types.d.ts +5 -11
- package/dist/wirings/oauth2/index.d.ts +0 -3
- package/dist/wirings/oauth2/index.js +1 -2
- package/dist/wirings/rpc/addon-runner.d.ts +28 -0
- package/dist/wirings/rpc/addon-runner.js +173 -0
- package/dist/wirings/rpc/index.d.ts +5 -1
- package/dist/wirings/rpc/index.js +3 -1
- package/dist/wirings/rpc/remote-addon-auth.d.ts +26 -0
- package/dist/wirings/rpc/remote-addon-auth.js +43 -0
- package/dist/wirings/rpc/rpc-runner.d.ts +19 -0
- package/dist/wirings/rpc/rpc-runner.js +109 -3
- package/dist/wirings/rpc/rpc-types.d.ts +15 -1
- package/dist/wirings/rpc/wire-addon.js +9 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +47 -0
- package/dist/wirings/rpc/wire-remote-addon.js +19 -0
- package/dist/wirings/scope/index.d.ts +3 -0
- package/dist/wirings/scope/index.js +2 -0
- package/dist/wirings/scope/scope.types.d.ts +39 -0
- package/dist/wirings/scope/scope.types.js +1 -0
- package/dist/wirings/scope/validate-scope-definitions.d.ts +16 -0
- package/dist/wirings/scope/validate-scope-definitions.js +76 -0
- package/dist/wirings/scope/wire-scope.d.ts +33 -0
- package/dist/wirings/scope/wire-scope.js +32 -0
- package/dist/wirings/secret/secret.types.d.ts +14 -0
- package/dist/wirings/secret/validate-secret-definitions.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.js +2 -0
- package/dist/wirings/variable/variable.types.d.ts +14 -0
- package/dist/wirings/workflow/dsl/index.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +89 -7
- package/dist/wirings/workflow/graph/graph-node.d.ts +2 -0
- package/dist/wirings/workflow/graph/graph-runner.js +3 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +6 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +1 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +5 -0
- package/dist/wirings/workflow/index.d.ts +2 -2
- package/dist/wirings/workflow/index.js +1 -1
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +59 -1
- package/dist/wirings/workflow/pikku-workflow-service.js +187 -0
- package/dist/wirings/workflow/workflow.types.d.ts +1 -3
- package/package.json +6 -1
- package/run-tests.sh +1 -0
- package/src/dev/hot-reload.ts +13 -68
- package/src/dev/module-runner.test.ts +169 -0
- package/src/dev/module-runner.ts +103 -0
- package/src/dev/reload-meta.test.ts +31 -2
- package/src/dev/reload-meta.ts +26 -0
- package/src/errors/errors.ts +24 -0
- package/src/function/function-runner.test.ts +276 -142
- package/src/function/function-runner.ts +52 -145
- package/src/function/functions.types.ts +28 -38
- package/src/index.ts +8 -6
- package/src/middleware/index.ts +1 -5
- package/src/permissions.test.ts +160 -373
- package/src/permissions.ts +137 -279
- package/src/pikku-state.ts +0 -2
- package/src/scopes.test.ts +167 -0
- package/src/scopes.ts +69 -0
- package/src/services/ai-embedding-service.ts +31 -0
- package/src/services/credential-wire-service.ts +10 -4
- package/src/services/index.ts +20 -0
- package/src/services/meta-service.ts +68 -3
- package/src/services/queue-webhook-service.test.ts +408 -0
- package/src/services/queue-webhook-service.ts +182 -0
- package/src/services/scope-service.ts +75 -0
- package/src/services/typed-secret-service.test.ts +35 -0
- package/src/services/typed-secret-service.ts +39 -4
- package/src/services/webhook-service.ts +180 -0
- package/src/services/workflow-service.ts +7 -0
- package/src/testing/service-tests.ts +49 -0
- package/src/types/core.types.ts +42 -14
- package/src/types/state.types.ts +23 -3
- package/src/utils/hmac.ts +27 -0
- package/src/utils/safe-fetch.test.ts +373 -0
- package/src/utils/safe-fetch.ts +213 -0
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +1127 -0
- package/src/wirings/ai-agent/ai-agent-agui.ts +386 -0
- package/src/wirings/ai-agent/ai-agent-authorization.test.ts +204 -0
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +483 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +324 -13
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +207 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +48 -1
- package/src/wirings/ai-agent/ai-agent-runner.ts +28 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +301 -10
- package/src/wirings/ai-agent/ai-agent-stream.ts +122 -16
- package/src/wirings/ai-agent/ai-agent.types.ts +57 -0
- package/src/wirings/ai-agent/index.ts +5 -0
- package/src/wirings/ai-agent/voice-input.test.ts +90 -0
- package/src/wirings/ai-agent/voice-input.ts +9 -40
- package/src/wirings/channel/channel-common.ts +0 -1
- package/src/wirings/channel/channel-handler.ts +1 -9
- package/src/wirings/channel/channel-middleware-runner.test.ts +28 -2
- package/src/wirings/channel/channel-middleware-runner.ts +39 -27
- package/src/wirings/channel/channel.types.ts +0 -6
- package/src/wirings/cli/cli-runner.ts +4 -2
- package/src/wirings/cli/cli.types.ts +0 -2
- package/src/wirings/cli/command-parser.test.ts +130 -0
- package/src/wirings/cli/command-parser.ts +80 -2
- package/src/wirings/credential/credential.types.ts +14 -0
- package/src/wirings/credential/validate-credential-definitions.ts +1 -0
- package/src/wirings/gateway/gateway-authorization.test.ts +444 -0
- package/src/wirings/gateway/gateway-runner.ts +114 -68
- package/src/wirings/gateway/gateway.types.ts +7 -9
- package/src/wirings/http/http-routes.ts +0 -3
- package/src/wirings/http/http-runner.test.ts +1 -11
- package/src/wirings/http/http-runner.ts +16 -39
- package/src/wirings/http/http.types.ts +7 -14
- package/src/wirings/mcp/mcp-runner.ts +0 -2
- package/src/wirings/mcp/mcp.types.ts +3 -11
- package/src/wirings/oauth2/index.ts +0 -3
- package/src/wirings/rpc/addon-runner.ts +233 -0
- package/src/wirings/rpc/index.ts +17 -1
- package/src/wirings/rpc/remote-addon-auth.ts +69 -0
- package/src/wirings/rpc/rpc-runner.test.ts +319 -16
- package/src/wirings/rpc/rpc-runner.ts +155 -3
- package/src/wirings/rpc/rpc-types.ts +16 -5
- package/src/wirings/rpc/wire-addon.test.ts +6 -3
- package/src/wirings/rpc/wire-addon.ts +9 -0
- package/src/wirings/rpc/wire-remote-addon.ts +57 -0
- package/src/wirings/scope/index.ts +14 -0
- package/src/wirings/scope/scope.test.ts +135 -0
- package/src/wirings/scope/scope.types.ts +44 -0
- package/src/wirings/scope/validate-scope-definitions.ts +110 -0
- package/src/wirings/scope/wire-scope.ts +34 -0
- package/src/wirings/secret/secret.types.ts +14 -0
- package/src/wirings/secret/validate-secret-definitions.ts +2 -0
- package/src/wirings/variable/validate-variable-definitions.ts +2 -0
- package/src/wirings/variable/variable.types.ts +14 -0
- package/src/wirings/workflow/dsl/index.ts +4 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +97 -6
- package/src/wirings/workflow/graph/graph-node.ts +2 -0
- package/src/wirings/workflow/graph/graph-runner.test.ts +58 -0
- package/src/wirings/workflow/graph/graph-runner.ts +3 -0
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +7 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +5 -0
- package/src/wirings/workflow/index.ts +5 -0
- package/src/wirings/workflow/pikku-workflow-service.test.ts +341 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +272 -0
- package/src/wirings/workflow/workflow-on-error.test.ts +154 -0
- package/src/wirings/workflow/workflow-step-session.test.ts +21 -5
- package/src/wirings/workflow/workflow.types.ts +4 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/src/wirings/oauth2/oauth2-client.test.ts +0 -930
- package/src/wirings/oauth2/oauth2-client.ts +0 -331
- package/src/wirings/oauth2/oauth2-routes.ts +0 -234
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FlatScope, ScopeDefinitions, ScopeDefinitionsMeta } from './scope.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Flattens declared scope trees into the full list of grantable scope ids,
|
|
4
|
+
* depth-first. Every node is emitted, including intermediate ones.
|
|
5
|
+
*
|
|
6
|
+
* Used by codegen to build the `ScopeId` union, and by a ScopeService to sync
|
|
7
|
+
* the declared set into its store.
|
|
8
|
+
*/
|
|
9
|
+
export declare const flattenScopeDefinitions: (definitions: ScopeDefinitions) => FlatScope[];
|
|
10
|
+
/**
|
|
11
|
+
* Validates declared scopes and keys them by name.
|
|
12
|
+
*
|
|
13
|
+
* Definitions sharing a name must be identical; a conflicting redeclaration is
|
|
14
|
+
* a hard error naming both source files.
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateAndBuildScopeDefinitionsMeta(definitions: ScopeDefinitions): ScopeDefinitionsMeta;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const SEPARATOR = ':';
|
|
2
|
+
const WILDCARD = '*';
|
|
3
|
+
const assertSegment = (segment, scopeName) => {
|
|
4
|
+
if (segment.includes(SEPARATOR)) {
|
|
5
|
+
throw new Error(`Scope segment '${segment}' in '${scopeName}' contains the '${SEPARATOR}' separator. ` +
|
|
6
|
+
`Nest scopes with the 'scopes' property instead of embedding '${SEPARATOR}' in a name.`);
|
|
7
|
+
}
|
|
8
|
+
if (segment === WILDCARD) {
|
|
9
|
+
throw new Error(`Scope segment '${segment}' in '${scopeName}' is the wildcard. ` +
|
|
10
|
+
`'${WILDCARD}' is reserved for granting a scope and its descendants, and cannot be declared.`);
|
|
11
|
+
}
|
|
12
|
+
if (segment.length === 0) {
|
|
13
|
+
throw new Error(`Scope '${scopeName}' contains an empty segment.`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const assertNodesValid = (nodes, scopeName) => {
|
|
17
|
+
for (const [segment, node] of Object.entries(nodes ?? {})) {
|
|
18
|
+
assertSegment(segment, scopeName);
|
|
19
|
+
assertNodesValid(node.scopes, scopeName);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const flattenNodes = (nodes, prefix, out) => {
|
|
23
|
+
for (const [segment, node] of Object.entries(nodes ?? {})) {
|
|
24
|
+
const id = `${prefix}${SEPARATOR}${segment}`;
|
|
25
|
+
out.push({ id, description: node.description });
|
|
26
|
+
flattenNodes(node.scopes, id, out);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Flattens declared scope trees into the full list of grantable scope ids,
|
|
31
|
+
* depth-first. Every node is emitted, including intermediate ones.
|
|
32
|
+
*
|
|
33
|
+
* Used by codegen to build the `ScopeId` union, and by a ScopeService to sync
|
|
34
|
+
* the declared set into its store.
|
|
35
|
+
*/
|
|
36
|
+
export const flattenScopeDefinitions = (definitions) => {
|
|
37
|
+
const out = [];
|
|
38
|
+
for (const def of definitions) {
|
|
39
|
+
out.push({ id: def.name, description: def.description });
|
|
40
|
+
flattenNodes(def.scopes, def.name, out);
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Validates declared scopes and keys them by name.
|
|
46
|
+
*
|
|
47
|
+
* Definitions sharing a name must be identical; a conflicting redeclaration is
|
|
48
|
+
* a hard error naming both source files.
|
|
49
|
+
*/
|
|
50
|
+
export function validateAndBuildScopeDefinitionsMeta(definitions) {
|
|
51
|
+
const meta = {};
|
|
52
|
+
for (const def of definitions) {
|
|
53
|
+
assertSegment(def.name, def.name);
|
|
54
|
+
assertNodesValid(def.scopes, def.name);
|
|
55
|
+
const existing = meta[def.name];
|
|
56
|
+
if (existing) {
|
|
57
|
+
const sameShape = JSON.stringify(existing.scopes ?? {}) ===
|
|
58
|
+
JSON.stringify(def.scopes ?? {});
|
|
59
|
+
if (!sameShape) {
|
|
60
|
+
throw new Error(`Scope '${def.name}' is declared with different nested scopes.\n` +
|
|
61
|
+
` First declaration: ${existing.sourceFile ?? 'unknown'}\n` +
|
|
62
|
+
` Second declaration: ${def.sourceFile ?? 'unknown'}\n` +
|
|
63
|
+
`Scopes sharing a name must declare the same tree.`);
|
|
64
|
+
}
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
meta[def.name] = {
|
|
68
|
+
name: def.name,
|
|
69
|
+
displayName: def.displayName,
|
|
70
|
+
description: def.description,
|
|
71
|
+
scopes: def.scopes,
|
|
72
|
+
sourceFile: def.sourceFile,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return meta;
|
|
76
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CoreScopes } from './scope.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* No-op function for declaring scopes.
|
|
4
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
5
|
+
* The CLI extracts metadata via AST parsing and generates a `ScopeId` union,
|
|
6
|
+
* so a function referencing an undeclared scope fails the build.
|
|
7
|
+
*
|
|
8
|
+
* Scopes are keyed by segment at every level: a scope is named by its key, and
|
|
9
|
+
* its value describes it. Every node is grantable — the declaration below
|
|
10
|
+
* yields `admin`, `admin:invoices`, `admin:invoices:create`,
|
|
11
|
+
* `admin:invoices:void` and `billing`.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* wireScope({
|
|
16
|
+
* admin: {
|
|
17
|
+
* displayName: 'Administration',
|
|
18
|
+
* description: 'Administrative access',
|
|
19
|
+
* scopes: {
|
|
20
|
+
* invoices: {
|
|
21
|
+
* description: 'Invoice management',
|
|
22
|
+
* scopes: {
|
|
23
|
+
* create: { description: 'Create invoices' },
|
|
24
|
+
* void: { description: 'Void invoices' },
|
|
25
|
+
* },
|
|
26
|
+
* },
|
|
27
|
+
* },
|
|
28
|
+
* },
|
|
29
|
+
* billing: {},
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const wireScope: (_config: CoreScopes) => void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No-op function for declaring scopes.
|
|
3
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
4
|
+
* The CLI extracts metadata via AST parsing and generates a `ScopeId` union,
|
|
5
|
+
* so a function referencing an undeclared scope fails the build.
|
|
6
|
+
*
|
|
7
|
+
* Scopes are keyed by segment at every level: a scope is named by its key, and
|
|
8
|
+
* its value describes it. Every node is grantable — the declaration below
|
|
9
|
+
* yields `admin`, `admin:invoices`, `admin:invoices:create`,
|
|
10
|
+
* `admin:invoices:void` and `billing`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* wireScope({
|
|
15
|
+
* admin: {
|
|
16
|
+
* displayName: 'Administration',
|
|
17
|
+
* description: 'Administrative access',
|
|
18
|
+
* scopes: {
|
|
19
|
+
* invoices: {
|
|
20
|
+
* description: 'Invoice management',
|
|
21
|
+
* scopes: {
|
|
22
|
+
* create: { description: 'Create invoices' },
|
|
23
|
+
* void: { description: 'Void invoices' },
|
|
24
|
+
* },
|
|
25
|
+
* },
|
|
26
|
+
* },
|
|
27
|
+
* },
|
|
28
|
+
* billing: {},
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export const wireScope = (_config) => { };
|
|
@@ -4,6 +4,13 @@ export type CoreSecret<T = unknown> = {
|
|
|
4
4
|
description?: string;
|
|
5
5
|
secretId: string;
|
|
6
6
|
schema: T;
|
|
7
|
+
/**
|
|
8
|
+
* Link to documentation explaining how to obtain this value — a provider's
|
|
9
|
+
* API-key page, a setup guide, an internal runbook. Surfaced by consoles and
|
|
10
|
+
* deploy UIs so a user facing a missing value has somewhere to go instead of
|
|
11
|
+
* an opaque identifier.
|
|
12
|
+
*/
|
|
13
|
+
docsUrl?: string;
|
|
7
14
|
/**
|
|
8
15
|
* Optional rotation cadence for this secret, e.g. '1d', '30day', '1w'.
|
|
9
16
|
* Stored in the generated secrets metadata so consumers can tell when a
|
|
@@ -25,6 +32,13 @@ export type SecretDefinitionMeta = {
|
|
|
25
32
|
description?: string;
|
|
26
33
|
secretId: string;
|
|
27
34
|
schema?: Record<string, unknown> | string;
|
|
35
|
+
/**
|
|
36
|
+
* Link to documentation explaining how to obtain this value — a provider's
|
|
37
|
+
* API-key page, a setup guide, an internal runbook. Surfaced by consoles and
|
|
38
|
+
* deploy UIs so a user facing a missing value has somewhere to go instead of
|
|
39
|
+
* an opaque identifier.
|
|
40
|
+
*/
|
|
41
|
+
docsUrl?: string;
|
|
28
42
|
oauth2?: OAuth2CredentialConfig;
|
|
29
43
|
rotationPeriod?: string;
|
|
30
44
|
sourceFile?: string;
|
|
@@ -34,6 +34,7 @@ export function validateAndBuildSecretDefinitionsMeta(definitions, schemaLookup)
|
|
|
34
34
|
schema: def.schema,
|
|
35
35
|
oauth2: def.oauth2,
|
|
36
36
|
rotationPeriod: def.rotationPeriod,
|
|
37
|
+
docsUrl: def.docsUrl,
|
|
37
38
|
sourceFile: def.sourceFile,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
@@ -49,6 +50,7 @@ export function validateAndBuildSecretDefinitionsMeta(definitions, schemaLookup)
|
|
|
49
50
|
schema: def.schema,
|
|
50
51
|
oauth2: def.oauth2,
|
|
51
52
|
rotationPeriod: def.rotationPeriod,
|
|
53
|
+
docsUrl: def.docsUrl,
|
|
52
54
|
sourceFile: def.sourceFile,
|
|
53
55
|
};
|
|
54
56
|
}
|
|
@@ -24,6 +24,7 @@ export function validateAndBuildVariableDefinitionsMeta(definitions, schemaLooku
|
|
|
24
24
|
description: def.description,
|
|
25
25
|
variableId: def.variableId,
|
|
26
26
|
schema: def.schema,
|
|
27
|
+
docsUrl: def.docsUrl,
|
|
27
28
|
sourceFile: def.sourceFile,
|
|
28
29
|
};
|
|
29
30
|
}
|
|
@@ -37,6 +38,7 @@ export function validateAndBuildVariableDefinitionsMeta(definitions, schemaLooku
|
|
|
37
38
|
description: def.description,
|
|
38
39
|
variableId: def.variableId,
|
|
39
40
|
schema: def.schema,
|
|
41
|
+
docsUrl: def.docsUrl,
|
|
40
42
|
sourceFile: def.sourceFile,
|
|
41
43
|
};
|
|
42
44
|
}
|
|
@@ -4,6 +4,13 @@ export type CoreVariable<T = unknown> = {
|
|
|
4
4
|
description?: string;
|
|
5
5
|
variableId: string;
|
|
6
6
|
schema: T;
|
|
7
|
+
/**
|
|
8
|
+
* Link to documentation explaining how to obtain this value — a provider's
|
|
9
|
+
* API-key page, a setup guide, an internal runbook. Surfaced by consoles and
|
|
10
|
+
* deploy UIs so a user facing a missing value has somewhere to go instead of
|
|
11
|
+
* an opaque identifier.
|
|
12
|
+
*/
|
|
13
|
+
docsUrl?: string;
|
|
7
14
|
};
|
|
8
15
|
export type VariableDefinitionMeta = {
|
|
9
16
|
name: string;
|
|
@@ -11,6 +18,13 @@ export type VariableDefinitionMeta = {
|
|
|
11
18
|
description?: string;
|
|
12
19
|
variableId: string;
|
|
13
20
|
schema?: Record<string, unknown> | string;
|
|
21
|
+
/**
|
|
22
|
+
* Link to documentation explaining how to obtain this value — a provider's
|
|
23
|
+
* API-key page, a setup guide, an internal runbook. Surfaced by consoles and
|
|
24
|
+
* deploy UIs so a user facing a missing value has somewhere to go instead of
|
|
25
|
+
* an opaque identifier.
|
|
26
|
+
*/
|
|
27
|
+
docsUrl?: string;
|
|
14
28
|
sourceFile?: string;
|
|
15
29
|
};
|
|
16
30
|
export type VariableDefinitionsMeta = Record<string, VariableDefinitionMeta>;
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* DSL (Domain Specific Language) workflow exports
|
|
3
3
|
*/
|
|
4
4
|
export { addWorkflow } from './workflow-runner.js';
|
|
5
|
-
export type { WorkflowStepOptions, WorkflowWireDoRPC, WorkflowWireDoInline, WorkflowWireSleep, WorkflowWireSuspend, InputSource, OutputBinding, RpcStepMeta, SimpleCondition, Condition, BranchStepMeta, ParallelGroupStepMeta, FanoutStepMeta, ReturnStepMeta, InlineStepMeta, SleepStepMeta, CancelStepMeta, SuspendStepMeta, SwitchCaseMeta, SwitchStepMeta, FilterStepMeta, ArrayPredicateStepMeta, WorkflowStepMeta, WorkflowStepWire, PikkuWorkflowWire, } from './workflow-dsl.types.js';
|
|
5
|
+
export type { WorkflowStepOptions, WorkflowWireDoRPC, WorkflowWireDoInline, WorkflowWireSleep, WorkflowWireSuspend, WorkflowWireApproval, WorkflowApprovalOptions, ApprovalOutcome, InputSource, OutputBinding, RpcStepMeta, SimpleCondition, Condition, BranchStepMeta, ParallelGroupStepMeta, FanoutStepMeta, ReturnStepMeta, InlineStepMeta, SleepStepMeta, CancelStepMeta, SuspendStepMeta, ApprovalStepMeta, SwitchCaseMeta, SwitchStepMeta, FilterStepMeta, ArrayPredicateStepMeta, WorkflowStepMeta, WorkflowStepWire, PikkuWorkflowWire, } from './workflow-dsl.types.js';
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* DSL (Domain Specific Language) workflow types
|
|
3
3
|
* These types define the step-based workflow format extracted by the inspector
|
|
4
4
|
*/
|
|
5
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
5
6
|
import type { WorkflowRun } from '../workflow.types.js';
|
|
6
7
|
import type { ScenarioActor } from '../../../services/scenario-actors-service.js';
|
|
7
8
|
/**
|
|
@@ -14,6 +15,13 @@ export interface WorkflowStepOptions {
|
|
|
14
15
|
retries?: number;
|
|
15
16
|
/** Delay between retry attempts (e.g., '1s', '2s', '2min') */
|
|
16
17
|
retryDelay?: string | number;
|
|
18
|
+
/**
|
|
19
|
+
* RPC to invoke for compensation when this step fails after exhausting its
|
|
20
|
+
* retries. Mirrors a graph node's `onError`: the handler receives
|
|
21
|
+
* `{ error: { message } }` and the original error is still thrown, so the
|
|
22
|
+
* workflow fails — this is compensation, not recovery.
|
|
23
|
+
*/
|
|
24
|
+
onError?: string;
|
|
17
25
|
/**
|
|
18
26
|
* Run this step as an actor (scenarios). The RPC is sent through the
|
|
19
27
|
* actor's authenticated client over the REAL transport — never dispatched
|
|
@@ -64,6 +72,43 @@ export type WorkflowWireSleep = (stepName: string, duration: string) => Promise<
|
|
|
64
72
|
* loops, like dynamic `do()` step names.
|
|
65
73
|
*/
|
|
66
74
|
export type WorkflowWireSuspend = (reason: string) => Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Options for workflow.approval().
|
|
77
|
+
*/
|
|
78
|
+
export interface WorkflowApprovalOptions<TSchema extends StandardSchemaV1 = StandardSchemaV1> {
|
|
79
|
+
/**
|
|
80
|
+
* Schema the decision payload is validated against. This is a VALUE, not a
|
|
81
|
+
* type generic: the payload arrives from an untrusted caller over the approve
|
|
82
|
+
* wire, and a generic is erased at compile time — it would validate nothing.
|
|
83
|
+
* Any standard-schema library (zod, valibot, arktype) satisfies this.
|
|
84
|
+
*/
|
|
85
|
+
schema: TSchema;
|
|
86
|
+
/**
|
|
87
|
+
* Give up waiting after this long (e.g. '3d'), yielding `{ status: 'expired' }`
|
|
88
|
+
* instead of waiting forever. Evaluated on replay from a recorded deadline, so
|
|
89
|
+
* the answer is correct even if the wake-up timer is never delivered.
|
|
90
|
+
*/
|
|
91
|
+
expiry?: string | number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The result of an approval gate. A union rather than a throw so that callers
|
|
95
|
+
* must handle the deadline case, and so "skip it and carry on" stays trivial.
|
|
96
|
+
* `decided` means a human answered — whether that answer was yes or no is
|
|
97
|
+
* carried in `data` and is the application's business, not the framework's.
|
|
98
|
+
*/
|
|
99
|
+
export type ApprovalOutcome<T> = {
|
|
100
|
+
status: 'decided';
|
|
101
|
+
data: T;
|
|
102
|
+
} | {
|
|
103
|
+
status: 'expired';
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Type signature for workflow.approval() - used by inspector.
|
|
107
|
+
* Like {@link WorkflowWireSuspend}, `reason` is the approval point's stable
|
|
108
|
+
* durable identity. Unlike suspend, the gate stays closed until a decision is
|
|
109
|
+
* recorded against it, and the decision is handed back to the caller.
|
|
110
|
+
*/
|
|
111
|
+
export type WorkflowWireApproval = <TSchema extends StandardSchemaV1>(reason: string, options: WorkflowApprovalOptions<TSchema>) => Promise<ApprovalOutcome<StandardSchemaV1.InferOutput<TSchema>>>;
|
|
67
112
|
/**
|
|
68
113
|
* Input source for step arguments in DSL workflows
|
|
69
114
|
*/
|
|
@@ -176,16 +221,20 @@ export interface ParallelGroupStepMeta {
|
|
|
176
221
|
*/
|
|
177
222
|
export interface FanoutStepMeta {
|
|
178
223
|
type: 'fanout';
|
|
179
|
-
/**
|
|
180
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Step name for this fanout. Optional: a fanout is not itself a cached step,
|
|
226
|
+
* and node ids are step names — borrowing a body step's name would give the
|
|
227
|
+
* loop and that step the same id, collapsing one onto the other.
|
|
228
|
+
*/
|
|
229
|
+
stepName?: string;
|
|
181
230
|
/** Source array variable name */
|
|
182
231
|
sourceVar: string;
|
|
183
232
|
/** Iterator variable name */
|
|
184
233
|
itemVar: string;
|
|
185
234
|
/** Execution mode */
|
|
186
235
|
mode: 'parallel' | 'sequential';
|
|
187
|
-
/**
|
|
188
|
-
|
|
236
|
+
/** Steps to execute inline per iteration, in order */
|
|
237
|
+
body: Array<RpcStepMeta | SleepStepMeta | SuspendStepMeta>;
|
|
189
238
|
/** Time between iterations (sequential mode only) */
|
|
190
239
|
timeBetween?: string;
|
|
191
240
|
}
|
|
@@ -196,6 +245,12 @@ export interface ReturnStepMeta {
|
|
|
196
245
|
type: 'return';
|
|
197
246
|
/** Output bindings */
|
|
198
247
|
outputs: Record<string, OutputBinding>;
|
|
248
|
+
/**
|
|
249
|
+
* Variables spread into the returned object (`return { ...r }`), or the sole
|
|
250
|
+
* returned variable (`return r`). Their fields are not enumerable statically,
|
|
251
|
+
* so they are recorded by name rather than expanded into `outputs`.
|
|
252
|
+
*/
|
|
253
|
+
spread?: string[];
|
|
199
254
|
}
|
|
200
255
|
/**
|
|
201
256
|
* Inline step metadata (legacy support)
|
|
@@ -220,6 +275,13 @@ export interface SleepStepMeta {
|
|
|
220
275
|
stepName: string;
|
|
221
276
|
/** Sleep duration */
|
|
222
277
|
duration: string | number;
|
|
278
|
+
/**
|
|
279
|
+
* Source text of a duration only known at runtime (e.g. a loop variable).
|
|
280
|
+
* The closure evaluates it, so it is legal DSL; it is kept separate from
|
|
281
|
+
* `duration` so regenerated code emits it raw rather than as a string
|
|
282
|
+
* literal, exactly as `expression` does on a set step.
|
|
283
|
+
*/
|
|
284
|
+
expression?: string;
|
|
223
285
|
}
|
|
224
286
|
/**
|
|
225
287
|
* Cancel step metadata
|
|
@@ -238,8 +300,14 @@ export interface SetStepMeta {
|
|
|
238
300
|
type: 'set';
|
|
239
301
|
/** Variable name to set (must be in context) */
|
|
240
302
|
variable: string;
|
|
241
|
-
/**
|
|
242
|
-
value
|
|
303
|
+
/** Literal value to assign. Mutually exclusive with `expression`. */
|
|
304
|
+
value?: unknown;
|
|
305
|
+
/**
|
|
306
|
+
* Source text of a non-literal assignment (e.g. `count + 1`). Kept separate
|
|
307
|
+
* from `value` so regenerated code can emit it raw — a string `value` is a
|
|
308
|
+
* string literal, an `expression` is code.
|
|
309
|
+
*/
|
|
310
|
+
expression?: string;
|
|
243
311
|
}
|
|
244
312
|
/**
|
|
245
313
|
* Switch case metadata
|
|
@@ -272,6 +340,18 @@ export interface SuspendStepMeta {
|
|
|
272
340
|
/** Reason string passed to workflow.suspend() — becomes the durable step key */
|
|
273
341
|
reason: string;
|
|
274
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Approval step metadata (workflow.approval())
|
|
345
|
+
*/
|
|
346
|
+
export interface ApprovalStepMeta {
|
|
347
|
+
type: 'approval';
|
|
348
|
+
/** Reason string passed to workflow.approval() — becomes the durable step key */
|
|
349
|
+
reason: string;
|
|
350
|
+
/** Output variable name (if assigned) */
|
|
351
|
+
outputVar?: string;
|
|
352
|
+
/** Expiry duration, when one was given */
|
|
353
|
+
expiry?: string | number;
|
|
354
|
+
}
|
|
275
355
|
/**
|
|
276
356
|
* Filter step metadata (array.filter)
|
|
277
357
|
*/
|
|
@@ -305,7 +385,7 @@ export interface ArrayPredicateStepMeta {
|
|
|
305
385
|
/**
|
|
306
386
|
* Workflow step metadata (extracted by inspector)
|
|
307
387
|
*/
|
|
308
|
-
export type WorkflowStepMeta = RpcStepMeta | BranchStepMeta | ParallelGroupStepMeta | FanoutStepMeta | ReturnStepMeta | InlineStepMeta | SleepStepMeta | CancelStepMeta | SuspendStepMeta | SwitchStepMeta | FilterStepMeta | ArrayPredicateStepMeta | SetStepMeta;
|
|
388
|
+
export type WorkflowStepMeta = RpcStepMeta | BranchStepMeta | ParallelGroupStepMeta | FanoutStepMeta | ReturnStepMeta | InlineStepMeta | SleepStepMeta | CancelStepMeta | SuspendStepMeta | ApprovalStepMeta | SwitchStepMeta | FilterStepMeta | ArrayPredicateStepMeta | SetStepMeta;
|
|
309
389
|
/**
|
|
310
390
|
* Workflow step wire context for RPC functions
|
|
311
391
|
* Provides step-level metadata including retry attempt tracking
|
|
@@ -355,6 +435,8 @@ export interface PikkuWorkflowWire {
|
|
|
355
435
|
sleep: WorkflowWireSleep;
|
|
356
436
|
/** Suspend workflow until explicitly resumed */
|
|
357
437
|
suspend: WorkflowWireSuspend;
|
|
438
|
+
/** Suspend workflow until a human records a decision against this gate */
|
|
439
|
+
approval: WorkflowWireApproval;
|
|
358
440
|
}
|
|
359
441
|
export interface PikkuScenarioWire extends PikkuWorkflowWire {
|
|
360
442
|
/**
|
|
@@ -93,6 +93,8 @@ type GraphNodeConfigMap<FuncMap extends Record<string, string>, RPCMap extends R
|
|
|
93
93
|
onError?: Extract<keyof FuncMap, string> | Extract<keyof FuncMap, string>[];
|
|
94
94
|
retries?: number;
|
|
95
95
|
retryDelay?: string | number;
|
|
96
|
+
/** Free-text node documentation. Non-semantic — excluded from graphHash. */
|
|
97
|
+
notes?: string;
|
|
96
98
|
};
|
|
97
99
|
};
|
|
98
100
|
/**
|
|
@@ -246,6 +246,9 @@ function resolveTemplate(template, nodeResults) {
|
|
|
246
246
|
}
|
|
247
247
|
function resolveValue(value, nodeResults) {
|
|
248
248
|
if (isDataRef(value)) {
|
|
249
|
+
if (value.$ref === '$item') {
|
|
250
|
+
return value;
|
|
251
|
+
}
|
|
249
252
|
const source = nodeResults[value.$ref];
|
|
250
253
|
return value.path ? getValueAtPath(source, value.path) : source;
|
|
251
254
|
}
|
|
@@ -5,11 +5,17 @@ export interface PikkuWorkflowGraphConfig<FuncMap extends Record<string, string>
|
|
|
5
5
|
tags?: string[];
|
|
6
6
|
nodes: FuncMap;
|
|
7
7
|
config?: T;
|
|
8
|
+
/**
|
|
9
|
+
* Graph-level free-text notes (e.g. imported sticky notes). Non-semantic:
|
|
10
|
+
* excluded from the graph topology hash.
|
|
11
|
+
*/
|
|
12
|
+
notes?: string[];
|
|
8
13
|
}
|
|
9
14
|
export interface PikkuWorkflowGraphResult {
|
|
10
15
|
__type: 'pikkuWorkflowGraph';
|
|
11
16
|
name?: string;
|
|
12
17
|
description?: string;
|
|
13
18
|
tags?: string[];
|
|
19
|
+
notes?: string[];
|
|
14
20
|
}
|
|
15
21
|
export declare function pikkuWorkflowGraph<const FuncMap extends Record<string, string>>(config: PikkuWorkflowGraphConfig<FuncMap, any>): PikkuWorkflowGraphResult;
|
|
@@ -49,6 +49,11 @@ export interface GraphNodeConfig<NodeIds extends string = string> {
|
|
|
49
49
|
retries?: number;
|
|
50
50
|
/** Delay between retries — milliseconds, duration string, or 'exponential' */
|
|
51
51
|
retryDelay?: string | number;
|
|
52
|
+
/**
|
|
53
|
+
* Free-text documentation for this node. Non-semantic: excluded from the
|
|
54
|
+
* graph topology hash, so editing a note never marks the workflow as changed.
|
|
55
|
+
*/
|
|
56
|
+
notes?: string;
|
|
52
57
|
}
|
|
53
58
|
/**
|
|
54
59
|
* Graph wire context - available to functions running in a workflow graph
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow module exports
|
|
3
3
|
*/
|
|
4
|
-
export { PikkuWorkflowService, WorkflowCancelledException, WorkflowSuspendedException, WorkflowDispatchException, WorkflowNotFoundError, WorkflowRunNotFoundError, DEFAULT_STEP_RETRIES, } from './pikku-workflow-service.js';
|
|
4
|
+
export { PikkuWorkflowService, WorkflowCancelledException, WorkflowSuspendedException, WorkflowDispatchException, WorkflowNotFoundError, WorkflowRunNotFoundError, WorkflowApprovalResolvedError, DEFAULT_STEP_RETRIES, } from './pikku-workflow-service.js';
|
|
5
5
|
export { deriveInvocationId, uuidv5 } from './workflow-invocation-id.js';
|
|
6
6
|
export { buildRunTimeline, reconstructStateAt, reconstructFinalState, } from './run-timeline.js';
|
|
7
7
|
export type { RunTimeline, RunTimelineEvent, ReconstructedRunState, ReconstructedStep, RunPhase, } from './run-timeline.js';
|
|
@@ -12,4 +12,4 @@ export { validateWorkflowWiring, computeEntryNodeIds, } from './graph/graph-vali
|
|
|
12
12
|
export { pikkuWorkflowWorkerFunc, pikkuWorkflowOrchestratorFunc, pikkuWorkflowSleeperFunc, } from './workflow-queue-workers.js';
|
|
13
13
|
export type { WorkflowStepInput as WorkflowStepQueueInput, PikkuWorkflowOrchestratorInput, PikkuWorkflowSleeperInput, } from './workflow-queue-workers.js';
|
|
14
14
|
export type { WorkflowService, WorkflowServiceConfig, WorkflowPlannedStep, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, StepStatus, WorkflowRun, WorkflowRunStatus, StepState, WorkflowRunService, WorkflowRunMirror, CoreWorkflow, PikkuWorkflow, ContextVariable, WorkflowContext, WorkflowsMeta, WorkflowRuntimeMeta, WorkflowsRuntimeMeta, WorkflowStepInput, WorkflowOrchestratorInput, WorkflowSleeperInput, } from './workflow.types.js';
|
|
15
|
-
export type { WorkflowStepOptions, WorkflowWireDoRPC, WorkflowWireDoInline, WorkflowWireSleep, WorkflowWireSuspend, InputSource, OutputBinding, RpcStepMeta, SimpleCondition, Condition, BranchCase, BranchStepMeta, ParallelGroupStepMeta, FanoutStepMeta, ReturnStepMeta, InlineStepMeta, SleepStepMeta, CancelStepMeta, SuspendStepMeta, SetStepMeta, SwitchCaseMeta, SwitchStepMeta, FilterStepMeta, ArrayPredicateStepMeta, WorkflowStepMeta, WorkflowStepWire, PikkuWorkflowWire, PikkuScenarioWire, } from './workflow.types.js';
|
|
15
|
+
export type { WorkflowStepOptions, WorkflowWireDoRPC, WorkflowWireDoInline, WorkflowWireSleep, WorkflowWireSuspend, WorkflowWireApproval, WorkflowApprovalOptions, ApprovalOutcome, InputSource, OutputBinding, RpcStepMeta, SimpleCondition, Condition, BranchCase, BranchStepMeta, ParallelGroupStepMeta, FanoutStepMeta, ReturnStepMeta, InlineStepMeta, SleepStepMeta, CancelStepMeta, SuspendStepMeta, ApprovalStepMeta, SetStepMeta, SwitchCaseMeta, SwitchStepMeta, FilterStepMeta, ArrayPredicateStepMeta, WorkflowStepMeta, WorkflowStepWire, PikkuWorkflowWire, PikkuScenarioWire, } from './workflow.types.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow module exports
|
|
3
3
|
*/
|
|
4
|
-
export { PikkuWorkflowService, WorkflowCancelledException, WorkflowSuspendedException, WorkflowDispatchException, WorkflowNotFoundError, WorkflowRunNotFoundError, DEFAULT_STEP_RETRIES, } from './pikku-workflow-service.js';
|
|
4
|
+
export { PikkuWorkflowService, WorkflowCancelledException, WorkflowSuspendedException, WorkflowDispatchException, WorkflowNotFoundError, WorkflowRunNotFoundError, WorkflowApprovalResolvedError, DEFAULT_STEP_RETRIES, } from './pikku-workflow-service.js';
|
|
5
5
|
export { deriveInvocationId, uuidv5 } from './workflow-invocation-id.js';
|
|
6
6
|
// Time-travel: reconstruct run state at any point from durable history
|
|
7
7
|
export { buildRunTimeline, reconstructStateAt, reconstructFinalState, } from './run-timeline.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SerializedError } from '../../types/core.types.js';
|
|
2
|
-
import type { PikkuScenarioWire, StepState, StepStatus, WorkflowPlannedStep, WorkflowRun, WorkflowRunMirror, WorkflowRunStatus, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, WorkflowStepOptions } from './workflow.types.js';
|
|
2
|
+
import type { ApprovalOutcome, PikkuScenarioWire, StepState, StepStatus, WorkflowPlannedStep, WorkflowRun, WorkflowRunMirror, WorkflowRunStatus, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, WorkflowStepOptions } from './workflow.types.js';
|
|
3
3
|
import type { WorkflowService } from '../../services/workflow-service.js';
|
|
4
4
|
import type { ScenarioActors } from '../../services/scenario-actors-service.js';
|
|
5
5
|
import { PikkuError } from '../../errors/error-handler.js';
|
|
@@ -70,6 +70,19 @@ export declare class WorkflowRunFailedError extends PikkuError {
|
|
|
70
70
|
export declare class WorkflowRunCancelledError extends PikkuError {
|
|
71
71
|
constructor();
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* A decision arrived for an approval gate that has already resolved. The gate
|
|
75
|
+
* caches its outcome as the step result and never re-reads run state, so the
|
|
76
|
+
* decision could not take effect — it is rejected rather than accepted and
|
|
77
|
+
* dropped.
|
|
78
|
+
*/
|
|
79
|
+
export declare class WorkflowApprovalResolvedError extends PikkuError {
|
|
80
|
+
payload: {
|
|
81
|
+
reason: string;
|
|
82
|
+
outcome: ApprovalOutcome<unknown>['status'];
|
|
83
|
+
};
|
|
84
|
+
constructor(reason: string, outcome: ApprovalOutcome<unknown>['status']);
|
|
85
|
+
}
|
|
73
86
|
export declare class WorkflowServiceNotInitialized extends Error {
|
|
74
87
|
}
|
|
75
88
|
export declare class WorkflowStepNameNotString extends Error {
|
|
@@ -430,6 +443,14 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
430
443
|
* loop exits immediately without recording a step error or retrying.
|
|
431
444
|
*/
|
|
432
445
|
private runInlineRetryLoop;
|
|
446
|
+
/**
|
|
447
|
+
* Run a failed step's compensation handler as a durable step of its own.
|
|
448
|
+
*
|
|
449
|
+
* Durable rather than a bare invoke so a replay does not compensate twice —
|
|
450
|
+
* a handler is typically a refund or a rollback. `onError` is deliberately
|
|
451
|
+
* not forwarded: a compensation handler cannot itself compensate.
|
|
452
|
+
*/
|
|
453
|
+
private runStepCompensation;
|
|
433
454
|
private rpcStep;
|
|
434
455
|
private inlineStep;
|
|
435
456
|
private sleepStep;
|
|
@@ -446,6 +467,43 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
446
467
|
*/
|
|
447
468
|
private getSuspendStepName;
|
|
448
469
|
private suspendStep;
|
|
470
|
+
/**
|
|
471
|
+
* Wake a run later by enqueuing a delayed orchestrator pass. Deliberately NOT
|
|
472
|
+
* {@link scheduleSleep}: that resolves the step it is given, which for an
|
|
473
|
+
* approval would resolve the gate itself. This only nudges the run to replay
|
|
474
|
+
* and re-evaluate — the gate stays the sole judge of its own outcome.
|
|
475
|
+
*
|
|
476
|
+
* Best-effort by design. Expiry is decided from the recorded deadline on
|
|
477
|
+
* replay, so losing this wake costs liveness (the run sits until something
|
|
478
|
+
* else resumes it), never correctness.
|
|
479
|
+
*/
|
|
480
|
+
private scheduleRunWake;
|
|
481
|
+
/**
|
|
482
|
+
* Durable step name for an approval gate. Namespaced separately from suspend
|
|
483
|
+
* so the two can't collide, and derived from `reason` for the same reason
|
|
484
|
+
* {@link getSuspendStepName} is: it must be stable across replays.
|
|
485
|
+
*/
|
|
486
|
+
private getApprovalStepName;
|
|
487
|
+
/**
|
|
488
|
+
* Run-state key holding an approval gate's record. Hex-encoded because the
|
|
489
|
+
* Mongo backend restricts state keys to `/^[a-zA-Z0-9_]+$/` and a `reason` is
|
|
490
|
+
* arbitrary human text. One key per gate, so two gates resolving concurrently
|
|
491
|
+
* can't clobber each other through a read-modify-write.
|
|
492
|
+
*/
|
|
493
|
+
private approvalStateKey;
|
|
494
|
+
/**
|
|
495
|
+
* Record a decision against an approval gate and wake the run. Called from
|
|
496
|
+
* outside the workflow (an HTTP route, an RPC), so the schema value is NOT in
|
|
497
|
+
* scope here — the payload is stored raw and validated on replay inside the
|
|
498
|
+
* workflow body, which is the only place the schema exists. An invalid payload
|
|
499
|
+
* therefore leaves the gate closed rather than failing the run.
|
|
500
|
+
*
|
|
501
|
+
* `reason` addresses the first reach of that gate. An approval reached more
|
|
502
|
+
* than once under the same reason (e.g. in a loop) gets `#N`-suffixed step
|
|
503
|
+
* rows that this cannot currently target.
|
|
504
|
+
*/
|
|
505
|
+
approveStep(runId: string, reason: string, decision: unknown): Promise<void>;
|
|
506
|
+
private approvalStep;
|
|
449
507
|
createWorkflowWire(name: string, runId: string, rpcService: any, addonNamespace?: string | null): PikkuScenarioWire;
|
|
450
508
|
private verifyStepName;
|
|
451
509
|
private getConfig;
|