@vimhead.dev/norn-cli 0.1.0-tip.35359392805.1 → 0.1.0-tip.35390859630.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/assets/README.md +17 -26
- package/assets/docs/README.md +3 -3
- package/assets/docs/agents.md +12 -1
- package/assets/docs/cli.md +5 -5
- package/assets/docs/composition.md +21 -21
- package/assets/docs/persistence.md +7 -10
- package/assets/docs/projects.md +30 -18
- package/assets/docs/providers.md +1 -1
- package/assets/docs/recovery.md +13 -9
- package/assets/docs/resources.md +4 -19
- package/assets/docs/schemas.md +1 -1
- package/assets/docs/workflows.md +95 -7
- package/assets/examples/agent-then-analysis/README.md +4 -4
- package/assets/examples/agent-then-analysis/input.json +1 -1
- package/assets/examples/agent-then-analysis/norn.project.json +1 -1
- package/assets/examples/agent-then-analysis/plugin.ts +55 -68
- package/assets/examples/caller-selected-continuation/README.md +5 -5
- package/assets/examples/caller-selected-continuation/caller.ts +35 -38
- package/assets/examples/caller-selected-continuation/input.json +2 -2
- package/assets/examples/caller-selected-continuation/norn.project.json +1 -1
- package/assets/examples/caller-selected-continuation/producer.ts +15 -23
- package/assets/examples/coordinating-multiple-agents/README.md +2 -2
- package/assets/examples/coordinating-multiple-agents/input.json +1 -1
- package/assets/examples/coordinating-multiple-agents/norn.project.json +1 -1
- package/assets/examples/coordinating-multiple-agents/plugin.ts +52 -56
- package/assets/examples/coordinating-multiple-agents/queue-adapter.ts +4 -4
- package/assets/examples/getting-started/norn.project.json +1 -1
- package/assets/examples/getting-started/plugin.ts +16 -26
- package/assets/examples/minimal-workflow/README.md +8 -8
- package/assets/examples/minimal-workflow/norn.project.json +1 -1
- package/assets/examples/minimal-workflow/plugin.ts +11 -25
- package/assets/examples/shared-state/README.md +10 -2
- package/assets/examples/shared-state/input.json +1 -1
- package/assets/examples/shared-state/norn.project.json +1 -1
- package/assets/examples/shared-state/plugin.ts +36 -41
- package/assets/examples/shared-state/shared-state.ts +75 -0
- package/assets/{packages/sdk/src → examples/shared-state}/state-adapter.ts +17 -16
- package/assets/examples/worktree-development-loop/README.md +6 -7
- package/assets/examples/worktree-development-loop/norn.project.json +1 -1
- package/assets/examples/worktree-development-loop/plugin.ts +6 -26
- package/assets/examples/worktree-development-loop/scope.ts +4 -0
- package/assets/examples/worktree-development-loop/workflows/development-loop/execute.ts +14 -15
- package/assets/examples/worktree-development-loop/workflows/development-loop/index.ts +3 -4
- package/assets/examples/worktree-development-loop/workflows/development-loop/schema.ts +2 -2
- package/assets/examples/worktree-development-loop/workflows/implementation/execute.ts +34 -33
- package/assets/examples/worktree-development-loop/workflows/implementation/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/implementation/schema.ts +7 -3
- package/assets/examples/worktree-development-loop/workflows/planning/execute.ts +23 -16
- package/assets/examples/worktree-development-loop/workflows/planning/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/planning/schema.ts +4 -2
- package/assets/examples/worktree-development-loop/workflows/review/execute.ts +40 -31
- package/assets/examples/worktree-development-loop/workflows/review/index.ts +3 -4
- package/assets/examples/worktree-development-loop/workflows/review/schema.ts +5 -4
- package/assets/examples/worktree-development-loop/workflows/review-router/execute.ts +49 -44
- package/assets/examples/worktree-development-loop/workflows/review-router/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/review-router/schema.ts +4 -3
- package/assets/package.json +1 -1
- package/assets/packages/cli/src/cli.ts +35 -34
- package/assets/packages/cli/src/client.ts +9 -16
- package/assets/packages/cli/src/documentation-intro.ts +1 -1
- package/assets/packages/cli/src/generated-build-info.ts +2 -2
- package/assets/packages/cli/src/internal/agent-response-tool.ts +3 -3
- package/assets/packages/cli/src/internal/engine.ts +38 -62
- package/assets/packages/cli/src/internal/errors.ts +4 -4
- package/assets/packages/cli/src/internal/launch-request.ts +6 -6
- package/assets/packages/cli/src/internal/run-state.ts +31 -21
- package/assets/packages/cli/src/internal/run.ts +2 -5
- package/assets/packages/cli/src/internal/workflow-registry.ts +114 -111
- package/assets/packages/cli/src/workflow-loader.ts +214 -0
- package/assets/packages/core/src/workflow-transition.ts +2 -2
- package/assets/packages/sdk/src/api.ts +133 -289
- package/assets/packages/sdk/src/index.ts +1 -1
- package/assets/packages/sdk/src/schema.ts +3 -3
- package/assets/tests/workflow-ref.test.ts +50 -51
- package/dist/cli.js +33 -32
- package/dist/client.d.ts +3 -4
- package/dist/client.js +3 -8
- package/dist/documentation-intro.js +1 -1
- package/dist/generated-build-info.d.ts +2 -2
- package/dist/generated-build-info.js +2 -2
- package/dist/internal/agent-response-tool.js +3 -3
- package/dist/internal/engine.d.ts +4 -8
- package/dist/internal/engine.js +36 -49
- package/dist/internal/errors.d.ts +3 -3
- package/dist/internal/errors.js +1 -1
- package/dist/internal/launch-request.d.ts +4 -4
- package/dist/internal/launch-request.js +2 -2
- package/dist/internal/run-state.d.ts +9 -8
- package/dist/internal/run-state.js +29 -20
- package/dist/internal/run.d.ts +1 -3
- package/dist/internal/run.js +3 -5
- package/dist/internal/workflow-registry.d.ts +25 -17
- package/dist/internal/workflow-registry.js +107 -72
- package/dist/{plugin-loader.d.ts → workflow-loader.d.ts} +7 -8
- package/dist/workflow-loader.js +235 -0
- package/package.json +2 -2
- package/assets/examples/worktree-development-loop/manifest.ts +0 -26
- package/assets/examples/worktree-development-loop/state.ts +0 -23
- package/assets/examples/worktree-development-loop/workflows/development-loop/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/implementation/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/planning/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/review/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/review-router/declaration.ts +0 -12
- package/assets/packages/cli/src/internal/run-resources.ts +0 -23
- package/assets/packages/cli/src/internal/state-store.ts +0 -83
- package/assets/packages/cli/src/plugin-loader.ts +0 -400
- package/dist/internal/run-resources.d.ts +0 -6
- package/dist/internal/run-resources.js +0 -26
- package/dist/internal/state-store.d.ts +0 -23
- package/dist/internal/state-store.js +0 -103
- package/dist/plugin-loader.js +0 -341
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { CreateAgentSessionOptions, EventBus, PromptOptions } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { Type, type
|
|
2
|
+
import { Type, type StaticDecode, type StaticEncode, type TCodec, type TSchema } from "typebox";
|
|
3
3
|
import type { TLocalizedValidationError } from "typebox/error";
|
|
4
4
|
import { createWorkflowTransition } from "@vimhead.dev/norn-core/workflow-transition";
|
|
5
5
|
import { Value } from "typebox/value";
|
|
6
|
-
import { isPlainObject, jsonValueSchema } from "./schema.ts";
|
|
6
|
+
import { assertWorkflowMetadata, isPlainObject, jsonValueSchema } from "./schema.ts";
|
|
7
7
|
|
|
8
8
|
const WORKFLOW_DECLARATION_KIND = "norn.workflow";
|
|
9
9
|
|
|
@@ -23,35 +23,42 @@ export type NornWorkflowIsolation<Mode extends NornWorkflowIsolationMode = NornW
|
|
|
23
23
|
|
|
24
24
|
export type NornWorkflowDeclaration<
|
|
25
25
|
Id extends string = string,
|
|
26
|
-
|
|
26
|
+
ArgsSchema extends TSchema = TSchema,
|
|
27
27
|
IsolationMode extends NornWorkflowIsolationMode = NornWorkflowIsolationMode,
|
|
28
|
+
ConfigSchema extends TSchema | undefined = TSchema | undefined,
|
|
29
|
+
Scope extends NornWorkflowScopeInfo | undefined = NornWorkflowScopeInfo | undefined,
|
|
28
30
|
> = {
|
|
29
|
-
(
|
|
31
|
+
(args: StaticEncode<ArgsSchema>): NornRunNext;
|
|
30
32
|
readonly kind: typeof WORKFLOW_DECLARATION_KIND;
|
|
31
33
|
readonly id: Id;
|
|
32
34
|
readonly isEntrypoint: boolean;
|
|
33
35
|
readonly instructions?: string;
|
|
34
|
-
readonly
|
|
35
|
-
readonly gate?:
|
|
36
|
+
readonly args: ArgsSchema;
|
|
37
|
+
readonly gate?: NornWorkflowGate<ArgsSchema> & {
|
|
38
|
+
describe?(context: NornWorkflowContext<ArgsSchema, IsolationMode, ConfigSchema, Scope>): MaybePromise<string>;
|
|
39
|
+
};
|
|
36
40
|
readonly isolation: NornWorkflowIsolation<IsolationMode>;
|
|
41
|
+
readonly config?: ConfigSchema;
|
|
42
|
+
readonly scope: Scope;
|
|
43
|
+
execute(context: NornWorkflowContext<ArgsSchema, IsolationMode, ConfigSchema, Scope>): MaybePromise<WorkflowResult>;
|
|
37
44
|
};
|
|
38
45
|
|
|
39
|
-
export type NornAnyWorkflowDeclaration = Pick<NornWorkflowDeclaration, keyof NornWorkflowDeclaration> & ((
|
|
40
|
-
export type NornWorkflowRefSchemaOptions<
|
|
41
|
-
readonly
|
|
46
|
+
export type NornAnyWorkflowDeclaration = Pick<NornWorkflowDeclaration, keyof NornWorkflowDeclaration> & ((args: never) => NornRunNext);
|
|
47
|
+
export type NornWorkflowRefSchemaOptions<ArgsSchema extends TSchema = TSchema> = {
|
|
48
|
+
readonly args?: ArgsSchema;
|
|
42
49
|
};
|
|
43
50
|
export type NornWorkflowRefInput = StaticEncode<typeof workflowReferenceInputSchema>;
|
|
44
|
-
export type NornWorkflowRefOutput<
|
|
51
|
+
export type NornWorkflowRefOutput<ArgsSchema extends TSchema> = (args: StaticEncode<ArgsSchema> & object) => NornRunNext;
|
|
45
52
|
|
|
46
|
-
export type
|
|
47
|
-
export type
|
|
53
|
+
export type NornWorkflowArgsInput<TWorkflow extends NornAnyWorkflowDeclaration> = StaticEncode<TWorkflow["args"]>;
|
|
54
|
+
export type NornWorkflowArgs<TWorkflow extends NornAnyWorkflowDeclaration> = StaticDecode<TWorkflow["args"]>;
|
|
48
55
|
|
|
49
|
-
export type NornWorkflowGate<
|
|
56
|
+
export type NornWorkflowGate<ArgsSchema extends TSchema> = unknown extends StaticEncode<ArgsSchema>
|
|
50
57
|
? NornWorkflowAnyGate
|
|
51
|
-
: StaticEncode<
|
|
58
|
+
: StaticEncode<ArgsSchema> extends Record<string, unknown>
|
|
52
59
|
? {
|
|
53
60
|
readonly enabled: true;
|
|
54
|
-
readonly fields?: readonly Extract<keyof StaticEncode<
|
|
61
|
+
readonly fields?: readonly Extract<keyof StaticEncode<ArgsSchema>, string>[];
|
|
55
62
|
}
|
|
56
63
|
: {
|
|
57
64
|
readonly enabled: true;
|
|
@@ -62,149 +69,96 @@ type NornWorkflowInstructions =
|
|
|
62
69
|
| { readonly isEntrypoint: true; readonly instructions: string }
|
|
63
70
|
| { readonly isEntrypoint: false; readonly instructions?: string };
|
|
64
71
|
|
|
72
|
+
type RunForIsolation<Mode extends NornWorkflowIsolationMode> = Mode extends "project" ? NornProjectRun : NornRun;
|
|
73
|
+
type WorkflowConfig<Schema extends TSchema | undefined> = Schema extends TSchema ? StaticDecode<Schema> : undefined;
|
|
74
|
+
|
|
75
|
+
export type NornWorkflowContext<
|
|
76
|
+
ArgsSchema extends TSchema = TSchema,
|
|
77
|
+
Mode extends NornWorkflowIsolationMode = NornWorkflowIsolationMode,
|
|
78
|
+
ConfigSchema extends TSchema | undefined = TSchema | undefined,
|
|
79
|
+
Scope extends NornWorkflowScopeInfo | undefined = NornWorkflowScopeInfo | undefined,
|
|
80
|
+
> = {
|
|
81
|
+
readonly args: StaticDecode<ArgsSchema>;
|
|
82
|
+
readonly config: WorkflowConfig<ConfigSchema>;
|
|
83
|
+
readonly run: RunForIsolation<Mode>;
|
|
84
|
+
} & (Scope extends NornWorkflowScopeInfo ? {
|
|
85
|
+
readonly scope: { readonly id: Scope["id"]; readonly config: WorkflowConfig<Scope["config"]> };
|
|
86
|
+
} : {});
|
|
87
|
+
|
|
65
88
|
export type NornWorkflowDefinition<
|
|
66
|
-
Id extends string
|
|
67
|
-
|
|
89
|
+
Id extends string = string,
|
|
90
|
+
ArgsSchema extends TSchema = TSchema,
|
|
68
91
|
IsolationMode extends NornWorkflowIsolationMode = NornWorkflowIsolationMode,
|
|
92
|
+
ConfigSchema extends TSchema | undefined = undefined,
|
|
93
|
+
Scope extends NornWorkflowScopeInfo | undefined = undefined,
|
|
69
94
|
> = {
|
|
70
|
-
readonly id
|
|
71
|
-
readonly
|
|
72
|
-
readonly
|
|
95
|
+
readonly id: Id;
|
|
96
|
+
readonly args: ArgsSchema;
|
|
97
|
+
readonly config?: ConfigSchema;
|
|
73
98
|
readonly isolation?: NornWorkflowIsolation<IsolationMode>;
|
|
99
|
+
readonly gate?: NornWorkflowGate<ArgsSchema> & {
|
|
100
|
+
describe?(context: NornWorkflowContext<ArgsSchema, IsolationMode, ConfigSchema, Scope>): MaybePromise<string>;
|
|
101
|
+
};
|
|
102
|
+
execute(context: NornWorkflowContext<ArgsSchema, IsolationMode, ConfigSchema, Scope>): MaybePromise<WorkflowResult>;
|
|
74
103
|
} & NornWorkflowInstructions;
|
|
75
104
|
|
|
76
|
-
export type
|
|
77
|
-
readonly id
|
|
78
|
-
readonly
|
|
79
|
-
readonly gate?: NornWorkflowAnyGate;
|
|
80
|
-
readonly isolation?: NornWorkflowIsolation;
|
|
81
|
-
} & NornWorkflowInstructions;
|
|
82
|
-
|
|
83
|
-
export type NornWorkflowStateDefinition<Schema extends TSchema = TSchema, Id extends string = string> = {
|
|
84
|
-
readonly id: Id;
|
|
85
|
-
readonly description?: string;
|
|
86
|
-
readonly schema: Schema;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export type NornWorkflowStateDefinitionInput<Schema extends TSchema = TSchema, Id extends string | undefined = string | undefined> = {
|
|
90
|
-
readonly id?: Id;
|
|
91
|
-
readonly description?: string;
|
|
92
|
-
readonly schema: Schema;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export type NornWorkflowPluginWorkflows = Record<string, NornAnyWorkflowDefinition>;
|
|
96
|
-
export type NornWorkflowPluginStateTree = { readonly [key: string]: NornWorkflowPluginStateTreeNode };
|
|
97
|
-
type NornStateSchema = TSchema & ({ readonly "~kind": string } | { readonly "~unsafe": unknown });
|
|
98
|
-
export type NornWorkflowPluginStateTreeNode = NornStateSchema | NornWorkflowStateDefinitionInput | NornWorkflowPluginStateTree;
|
|
99
|
-
|
|
100
|
-
type JoinPath<Head extends string, Parts extends readonly string[]> = Parts extends readonly []
|
|
101
|
-
? Head
|
|
102
|
-
: Parts extends readonly [infer First extends string, ...infer Rest extends string[]]
|
|
103
|
-
? JoinPath<`${Head}.${First}`, Rest>
|
|
104
|
-
: string;
|
|
105
|
-
|
|
106
|
-
type NornInvalidGateFields<TWorkflow> = TWorkflow extends { readonly params: infer ParamsSchema extends TSchema; readonly gate: { readonly fields: infer Fields extends readonly string[] } }
|
|
107
|
-
? Exclude<Fields[number], Extract<keyof StaticEncode<ParamsSchema>, string>>
|
|
108
|
-
: never;
|
|
109
|
-
|
|
110
|
-
type NornValidatedWorkflowGate<TWorkflow> = [NornInvalidGateFields<TWorkflow>] extends [never]
|
|
111
|
-
? unknown
|
|
112
|
-
: { readonly gate: { readonly fields: readonly Extract<keyof StaticEncode<TWorkflow extends { readonly params: infer ParamsSchema extends TSchema } ? ParamsSchema : TSchema>, string>[] } };
|
|
113
|
-
|
|
114
|
-
export type NornValidatedWorkflowGates<Workflows> = {
|
|
115
|
-
readonly [Key in keyof Workflows]: NornValidatedWorkflowGate<Workflows[Key]>;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export type NornQualifiedPluginWorkflow<
|
|
119
|
-
PluginId extends string,
|
|
120
|
-
WorkflowKey extends string,
|
|
121
|
-
TWorkflow extends NornAnyWorkflowDefinition,
|
|
122
|
-
> = TWorkflow extends { readonly params: infer ParamsSchema extends TSchema }
|
|
123
|
-
? NornWorkflowDeclaration<
|
|
124
|
-
TWorkflow extends { readonly id: infer ExplicitId extends string } ? ExplicitId : `${PluginId}.${WorkflowKey}`,
|
|
125
|
-
ParamsSchema,
|
|
126
|
-
TWorkflow extends { readonly isolation: { readonly mode: infer IsolationMode extends NornWorkflowIsolationMode } } ? IsolationMode : "runWorkspace"
|
|
127
|
-
>
|
|
128
|
-
: never;
|
|
129
|
-
|
|
130
|
-
export type NornQualifiedPluginWorkflows<PluginId extends string, Workflows extends NornWorkflowPluginWorkflows> = {
|
|
131
|
-
readonly [Key in keyof Workflows]: NornQualifiedPluginWorkflow<PluginId, Key & string, Workflows[Key]>;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export type NornQualifiedPluginStates<PluginId extends string, States, Path extends readonly string[] = []> = {
|
|
135
|
-
readonly [Key in keyof States]: States[Key] extends NornStateSchema
|
|
136
|
-
? NornWorkflowStateDefinition<States[Key], JoinPath<PluginId, [...Path, Key & string]>>
|
|
137
|
-
: States[Key] extends NornWorkflowStateDefinitionInput<infer Schema extends NornStateSchema>
|
|
138
|
-
? NornWorkflowStateDefinition<Schema, States[Key] extends { readonly id: infer Id extends string } ? Id : JoinPath<PluginId, [...Path, Key & string]>>
|
|
139
|
-
: States[Key] extends NornWorkflowPluginStateTree
|
|
140
|
-
? NornQualifiedPluginStates<PluginId, States[Key], [...Path, Key & string]>
|
|
141
|
-
: never;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
export type NornWorkflowPluginManifest<
|
|
145
|
-
PluginId extends string = string,
|
|
146
|
-
ConfigSchema extends TSchema | undefined = TSchema | undefined,
|
|
147
|
-
Workflows extends Record<string, NornAnyWorkflowDeclaration> = Record<string, NornAnyWorkflowDeclaration>,
|
|
148
|
-
States = undefined,
|
|
149
|
-
> = {
|
|
150
|
-
readonly id: PluginId;
|
|
151
|
-
readonly config?: ConfigSchema;
|
|
152
|
-
readonly workflows: Workflows;
|
|
153
|
-
readonly states: States;
|
|
105
|
+
export type NornWorkflowScopeInfo = {
|
|
106
|
+
readonly id: string;
|
|
107
|
+
readonly config?: TSchema;
|
|
154
108
|
};
|
|
155
109
|
|
|
156
|
-
export type
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
110
|
+
export type NornWorkflowScope<Id extends string, ConfigSchema extends TSchema | undefined> = {
|
|
111
|
+
readonly id: Id;
|
|
112
|
+
readonly config: ConfigSchema;
|
|
113
|
+
workflow<const LocalId extends string, ArgsSchema extends TSchema, const Mode extends NornWorkflowIsolationMode = "runWorkspace", LocalConfig extends TSchema | undefined = undefined>(
|
|
114
|
+
definition: NornWorkflowDefinition<LocalId, ArgsSchema, Mode, LocalConfig, { readonly id: Id; readonly config: ConfigSchema }>,
|
|
115
|
+
): NornWorkflowDeclaration<`${Id}.${LocalId}`, ArgsSchema, Mode, LocalConfig, { readonly id: Id; readonly config: ConfigSchema }>;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export function workflow<
|
|
119
|
+
const Id extends string,
|
|
120
|
+
ArgsSchema extends TSchema,
|
|
121
|
+
const Mode extends NornWorkflowIsolationMode = "runWorkspace",
|
|
122
|
+
ConfigSchema extends TSchema | undefined = undefined,
|
|
123
|
+
>(definition: NornWorkflowDefinition<Id, ArgsSchema, Mode, ConfigSchema>): NornWorkflowDeclaration<Id, ArgsSchema, Mode, ConfigSchema, undefined> {
|
|
124
|
+
return createWorkflow({ definition, scope: undefined });
|
|
125
|
+
}
|
|
161
126
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
127
|
+
function createWorkflow<Id extends string, ArgsSchema extends TSchema, Mode extends NornWorkflowIsolationMode, ConfigSchema extends TSchema | undefined, Scope extends NornWorkflowScopeInfo | undefined>(
|
|
128
|
+
input: { readonly definition: NornWorkflowDefinition<Id, ArgsSchema, Mode, ConfigSchema, Scope>; readonly scope: Scope },
|
|
129
|
+
): NornWorkflowDeclaration<Id, ArgsSchema, Mode, ConfigSchema, Scope> {
|
|
130
|
+
const { definition, scope } = input;
|
|
131
|
+
assertDeclarationId(definition.id);
|
|
132
|
+
const callable = (args: StaticEncode<ArgsSchema>): NornRunNext => createWorkflowTransition({ workflowId: definition.id, args });
|
|
133
|
+
const result = Object.assign(callable, definition, {
|
|
134
|
+
kind: WORKFLOW_DECLARATION_KIND,
|
|
135
|
+
scope,
|
|
136
|
+
isolation: definition.isolation ?? { mode: "runWorkspace" },
|
|
137
|
+
}) as NornWorkflowDeclaration<Id, ArgsSchema, Mode, ConfigSchema, Scope>;
|
|
138
|
+
if (!isWorkflowDeclaration(result)) throw new Error(`Invalid workflow definition: ${definition.id}`);
|
|
139
|
+
assertWorkflowMetadata(result);
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
165
142
|
|
|
166
|
-
export
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
> = {
|
|
172
|
-
readonly id: PluginId;
|
|
173
|
-
readonly config?: ConfigSchema;
|
|
174
|
-
readonly workflows: Workflows & NornValidatedWorkflowGates<Workflows>;
|
|
175
|
-
readonly states?: States;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export function definePluginManifest<
|
|
179
|
-
const PluginId extends string,
|
|
180
|
-
const ConfigSchema extends TSchema | undefined = undefined,
|
|
181
|
-
const Workflows extends NornWorkflowPluginWorkflows = NornWorkflowPluginWorkflows,
|
|
182
|
-
const States extends NornWorkflowPluginStateTree | undefined = undefined,
|
|
183
|
-
>(
|
|
184
|
-
input: NornDefinePluginManifestInput<PluginId, ConfigSchema, Workflows, States>,
|
|
185
|
-
): NornWorkflowPluginManifest<
|
|
186
|
-
PluginId,
|
|
187
|
-
ConfigSchema,
|
|
188
|
-
NornQualifiedPluginWorkflows<PluginId, Workflows>,
|
|
189
|
-
States extends NornWorkflowPluginStateTree ? NornQualifiedPluginStates<PluginId, States> : undefined
|
|
190
|
-
> {
|
|
191
|
-
assertLocalDeclarationId(input.id, "plugin");
|
|
192
|
-
const declaredIds = new Set<string>();
|
|
193
|
-
const workflows = Object.fromEntries(
|
|
194
|
-
Object.entries(input.workflows).map(([key, workflow]) => [key, qualifyWorkflow(input.id, key, workflow, declaredIds)]),
|
|
195
|
-
) as NornQualifiedPluginWorkflows<PluginId, Workflows>;
|
|
143
|
+
export function workflowScope<const Id extends string, ConfigSchema extends TSchema | undefined = undefined>(
|
|
144
|
+
input: { readonly id: Id; readonly config?: ConfigSchema },
|
|
145
|
+
): NornWorkflowScope<Id, ConfigSchema> {
|
|
146
|
+
assertDeclarationId(input.id);
|
|
147
|
+
const scope = { id: input.id, config: input.config as ConfigSchema };
|
|
196
148
|
return {
|
|
197
149
|
id: input.id,
|
|
198
|
-
config: input.config,
|
|
199
|
-
|
|
200
|
-
|
|
150
|
+
config: input.config as ConfigSchema,
|
|
151
|
+
workflow(definition) {
|
|
152
|
+
assertDeclarationId(definition.id);
|
|
153
|
+
return createWorkflow({ definition: { ...definition, id: `${input.id}.${definition.id}` }, scope });
|
|
154
|
+
},
|
|
201
155
|
};
|
|
202
156
|
}
|
|
203
157
|
|
|
204
158
|
export type NornRunNext = {
|
|
205
159
|
readonly type: "next";
|
|
206
160
|
readonly workflowId: string;
|
|
207
|
-
readonly
|
|
161
|
+
readonly args: unknown;
|
|
208
162
|
};
|
|
209
163
|
|
|
210
164
|
export type NornRunOutcomeMetadata = {
|
|
@@ -224,29 +178,12 @@ export type NornRunFail = {
|
|
|
224
178
|
readonly metadata: NornRunOutcomeMetadata & { readonly summary: string };
|
|
225
179
|
};
|
|
226
180
|
|
|
227
|
-
export type
|
|
181
|
+
export type WorkflowResult = NornRunNext | NornRunComplete | NornRunFail;
|
|
228
182
|
|
|
229
183
|
export type NornRunFor<TWorkflow extends NornAnyWorkflowDeclaration> = TWorkflow extends { readonly isolation: { readonly mode: "project" } }
|
|
230
184
|
? NornProjectRun
|
|
231
185
|
: NornRun;
|
|
232
186
|
|
|
233
|
-
export type NornWorkflowGateImplementation<TWorkflow extends NornAnyWorkflowDeclaration, TConfig> = {
|
|
234
|
-
describe(
|
|
235
|
-
run: NornRunFor<TWorkflow>,
|
|
236
|
-
params: NornWorkflowParams<TWorkflow>,
|
|
237
|
-
config: TConfig,
|
|
238
|
-
): MaybePromise<string>;
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
export type NornWorkflowImplementation<TWorkflow extends NornAnyWorkflowDeclaration, TConfig = unknown> = {
|
|
242
|
-
readonly gate?: NornWorkflowGateImplementation<TWorkflow, TConfig>;
|
|
243
|
-
execute(
|
|
244
|
-
run: NornRunFor<TWorkflow>,
|
|
245
|
-
params: NornWorkflowParams<TWorkflow>,
|
|
246
|
-
config: TConfig,
|
|
247
|
-
): MaybePromise<NornWorkflowExecutionResult>;
|
|
248
|
-
};
|
|
249
|
-
|
|
250
187
|
export type NornRunStartOptions = {
|
|
251
188
|
readonly id?: string;
|
|
252
189
|
readonly name?: string;
|
|
@@ -294,7 +231,7 @@ export type NornStoppedRunResult = {
|
|
|
294
231
|
|
|
295
232
|
export type NornRunInterruption = {
|
|
296
233
|
readonly workflowId: string;
|
|
297
|
-
readonly
|
|
234
|
+
readonly args: unknown;
|
|
298
235
|
readonly description: string;
|
|
299
236
|
readonly fields?: readonly string[];
|
|
300
237
|
};
|
|
@@ -358,46 +295,6 @@ export type NornRunCheckpoint = {
|
|
|
358
295
|
readonly createdAt: string;
|
|
359
296
|
};
|
|
360
297
|
|
|
361
|
-
export type NornWorkflowStateReader = {
|
|
362
|
-
get<Schema extends TSchema>(state: NornWorkflowStateDefinition<Schema>): Promise<Static<Schema>>;
|
|
363
|
-
getOptional<Schema extends TSchema>(state: NornWorkflowStateDefinition<Schema>): Promise<Static<Schema> | undefined>;
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
export type NornWorkflowState = NornWorkflowStateReader & {
|
|
367
|
-
set<Schema extends TSchema>(state: NornWorkflowStateDefinition<Schema>, value: NoInfer<Static<Schema>>): Promise<void>;
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
export type NornWorkflowPluginContext = {
|
|
371
|
-
readonly cwd: string;
|
|
372
|
-
readonly state: NornWorkflowState;
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
export type NornWorkflowPluginImplementation<TManifest extends NornAnyWorkflowPluginManifest> = {
|
|
376
|
-
readonly workflows: {
|
|
377
|
-
readonly [Key in keyof TManifest["workflows"]]: NornWorkflowImplementation<TManifest["workflows"][Key], NornWorkflowPluginConfig<TManifest>>;
|
|
378
|
-
};
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
export type NornWorkflowPluginImplementationFactory<TManifest extends NornAnyWorkflowPluginManifest> = (
|
|
382
|
-
context: NornWorkflowPluginContext,
|
|
383
|
-
) => NornWorkflowPluginImplementation<TManifest>;
|
|
384
|
-
|
|
385
|
-
export type NornWorkflowPluginImplementationInput<TManifest extends NornAnyWorkflowPluginManifest> =
|
|
386
|
-
| NornWorkflowPluginImplementation<TManifest>
|
|
387
|
-
| NornWorkflowPluginImplementationFactory<TManifest>;
|
|
388
|
-
|
|
389
|
-
export type NornWorkflowPlugin<TManifest extends NornAnyWorkflowPluginManifest = NornAnyWorkflowPluginManifest> = {
|
|
390
|
-
readonly manifest: TManifest;
|
|
391
|
-
readonly implementation: NornWorkflowPluginImplementationInput<TManifest>;
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
export function definePlugin<TManifest extends NornAnyWorkflowPluginManifest>(
|
|
395
|
-
manifest: TManifest,
|
|
396
|
-
implementation: NornWorkflowPluginImplementationInput<TManifest>,
|
|
397
|
-
): NornWorkflowPlugin<TManifest> {
|
|
398
|
-
return { manifest, implementation };
|
|
399
|
-
}
|
|
400
|
-
|
|
401
298
|
export type NornCommandRunInput = {
|
|
402
299
|
readonly label: string;
|
|
403
300
|
readonly command: string | readonly [string, ...string[]];
|
|
@@ -412,24 +309,24 @@ export const artifactRefSchema = Type.Object({
|
|
|
412
309
|
|
|
413
310
|
export type NornArtifactRef = StaticDecode<typeof artifactRefSchema>;
|
|
414
311
|
|
|
415
|
-
const
|
|
312
|
+
const emptyWorkflowRefArgsSchema = Type.Object({});
|
|
416
313
|
const workflowReferenceInputSchema = Type.Union([
|
|
417
314
|
Type.String({ minLength: 1 }),
|
|
418
|
-
Type.Object({ workflow: Type.String({ minLength: 1 }),
|
|
315
|
+
Type.Object({ workflow: Type.String({ minLength: 1 }), forwardArgs: Type.Record(Type.String(), Type.Unknown()) }),
|
|
419
316
|
]);
|
|
420
317
|
|
|
421
|
-
export function workflowRefSchema<
|
|
422
|
-
const contributionSchema = options?.
|
|
318
|
+
export function workflowRefSchema<ArgsSchema extends TSchema = typeof emptyWorkflowRefArgsSchema>(options?: NornWorkflowRefSchemaOptions<ArgsSchema>): TCodec<typeof workflowReferenceInputSchema, NornWorkflowRefOutput<ArgsSchema>> {
|
|
319
|
+
const contributionSchema = options?.args ?? emptyWorkflowRefArgsSchema;
|
|
423
320
|
return Type.With(Type.Decode(workflowReferenceInputSchema, reference => {
|
|
424
321
|
const workflowId = typeof reference === "string" ? reference : reference.workflow;
|
|
425
|
-
const
|
|
426
|
-
return (
|
|
427
|
-
Value.Assert(contributionSchema,
|
|
428
|
-
if (!isPlainObject(
|
|
429
|
-
Value.Assert(jsonValueSchema,
|
|
430
|
-
return createWorkflowTransition({ workflowId,
|
|
322
|
+
const forwardArgs = typeof reference === "string" ? {} : reference.forwardArgs;
|
|
323
|
+
return (args: StaticEncode<ArgsSchema> & object): NornRunNext => {
|
|
324
|
+
Value.Assert(contributionSchema, args);
|
|
325
|
+
if (!isPlainObject(args)) throw new Error("Workflow reference contributions must be objects");
|
|
326
|
+
Value.Assert(jsonValueSchema, args);
|
|
327
|
+
return createWorkflowTransition({ workflowId, args: { ...forwardArgs, ...args } });
|
|
431
328
|
};
|
|
432
|
-
}), { "x-norn-workflow-ref": {
|
|
329
|
+
}), { "x-norn-workflow-ref": { contributedArgsSchema: contributionSchema } });
|
|
433
330
|
}
|
|
434
331
|
|
|
435
332
|
export type NornLogRef = {
|
|
@@ -592,11 +489,10 @@ type NornRunBase = {
|
|
|
592
489
|
workspace: string;
|
|
593
490
|
cwd: string;
|
|
594
491
|
path(relativePath: string): string;
|
|
595
|
-
next(workflowId: string,
|
|
492
|
+
next(workflowId: string, args: unknown): NornRunNext;
|
|
596
493
|
complete(metadata?: NornRunOutcomeMetadata): NornRunComplete;
|
|
597
494
|
fail(metadata: NornRunOutcomeMetadata & { readonly summary: string }): NornRunFail;
|
|
598
495
|
resources: import("./resources.ts").NornResources;
|
|
599
|
-
state: NornWorkflowState;
|
|
600
496
|
artifacts: {
|
|
601
497
|
write(path: string, content: string): Promise<NornArtifactRef>;
|
|
602
498
|
read(ref: NornArtifactRef): Promise<string>;
|
|
@@ -613,10 +509,9 @@ type NornRunBase = {
|
|
|
613
509
|
};
|
|
614
510
|
};
|
|
615
511
|
|
|
616
|
-
export type
|
|
617
|
-
readonly
|
|
618
|
-
readonly
|
|
619
|
-
readonly configPath?: string;
|
|
512
|
+
export type NornWorkflowSource = {
|
|
513
|
+
readonly path: string;
|
|
514
|
+
readonly configPath: string;
|
|
620
515
|
};
|
|
621
516
|
|
|
622
517
|
export type NornJsonSchema = Record<string, unknown>;
|
|
@@ -631,27 +526,31 @@ export type NornRegisteredWorkflowInfo = {
|
|
|
631
526
|
readonly instructions?: string;
|
|
632
527
|
readonly isEntrypoint: boolean;
|
|
633
528
|
readonly isolation: NornWorkflowIsolation;
|
|
634
|
-
readonly
|
|
529
|
+
readonly scope?: { readonly id: string };
|
|
530
|
+
readonly source?: NornWorkflowSource;
|
|
531
|
+
readonly configKey: string;
|
|
635
532
|
};
|
|
636
533
|
|
|
637
534
|
export type NornInspectedWorkflowInfo = NornRegisteredWorkflowInfo & {
|
|
638
|
-
readonly
|
|
535
|
+
readonly scope?: { readonly id: string; readonly configKey: string; readonly configSchema: NornJsonSchema | null };
|
|
536
|
+
readonly argsSchema: NornJsonSchema;
|
|
537
|
+
readonly configSchema: NornJsonSchema | null;
|
|
639
538
|
readonly gate: NornWorkflowGateInfo | null;
|
|
640
539
|
};
|
|
641
540
|
|
|
642
|
-
export type
|
|
541
|
+
export type NornWorkflowDiagnostic = {
|
|
643
542
|
readonly configPath: string;
|
|
644
|
-
readonly
|
|
645
|
-
readonly
|
|
543
|
+
readonly modulePath: string;
|
|
544
|
+
readonly scopeId: string | null;
|
|
646
545
|
readonly workflowId: string | null;
|
|
647
|
-
readonly stage: "import" | "declaration" | "config" | "
|
|
546
|
+
readonly stage: "import" | "declaration" | "config" | "duplicate" | "schema";
|
|
648
547
|
readonly message: string;
|
|
649
548
|
readonly issues: readonly TLocalizedValidationError[];
|
|
650
549
|
};
|
|
651
550
|
|
|
652
551
|
export type NornProjectLoadStatus = {
|
|
653
552
|
readonly isComplete: boolean;
|
|
654
|
-
readonly diagnostics: readonly
|
|
553
|
+
readonly diagnostics: readonly NornWorkflowDiagnostic[];
|
|
655
554
|
};
|
|
656
555
|
|
|
657
556
|
export type NornWorkflowCatalogInfo = NornProjectLoadStatus & {
|
|
@@ -666,7 +565,9 @@ export type NornProjectInspection = NornProjectLoadStatus & {
|
|
|
666
565
|
readonly project: NornProjectInfo;
|
|
667
566
|
};
|
|
668
567
|
|
|
669
|
-
export type
|
|
568
|
+
export type NornProjectConfigurationInfo = {
|
|
569
|
+
readonly key: string;
|
|
570
|
+
readonly scopeId: string | null;
|
|
670
571
|
readonly configSchema: NornJsonSchema | null;
|
|
671
572
|
readonly config: unknown;
|
|
672
573
|
};
|
|
@@ -678,89 +579,32 @@ export type NornProjectInfo = {
|
|
|
678
579
|
readonly configPath: string;
|
|
679
580
|
readonly configRoot: string;
|
|
680
581
|
readonly configFiles: readonly string[];
|
|
681
|
-
readonly
|
|
582
|
+
readonly configurations: readonly NornProjectConfigurationInfo[];
|
|
583
|
+
readonly modules: readonly NornWorkflowSource[];
|
|
682
584
|
};
|
|
683
585
|
|
|
684
|
-
function
|
|
685
|
-
if (id.length === 0) throw new Error(`
|
|
686
|
-
if (id.includes(".")) throw new Error(`Workflow ${kind} id must not contain dots: ${id}`);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
function resolveDeclarationId(pluginId: string, path: readonly string[], explicitId: string | undefined, kind: "workflow" | "state", declaredIds: Set<string>): string {
|
|
690
|
-
for (const segment of path) assertLocalDeclarationId(segment, kind);
|
|
691
|
-
const id = explicitId ?? [pluginId, ...path].join(".");
|
|
692
|
-
if (explicitId !== undefined) assertPluginQualifiedId(pluginId, explicitId, kind);
|
|
693
|
-
if (declaredIds.has(id)) throw new Error(`Duplicate Norn ${kind} id: ${id}`);
|
|
694
|
-
declaredIds.add(id);
|
|
695
|
-
return id;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
function assertPluginQualifiedId(pluginId: string, id: string, kind: "workflow" | "state"): void {
|
|
699
|
-
if (!id.startsWith(`${pluginId}.`)) throw new Error(`Explicit Norn ${kind} id must start with ${pluginId}.: ${id}`);
|
|
700
|
-
if (id.length === pluginId.length + 1) throw new Error(`Explicit Norn ${kind} id must not be empty after ${pluginId}.`);
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
function qualifyWorkflow<PluginId extends string, TWorkflow extends NornAnyWorkflowDefinition>(
|
|
704
|
-
pluginId: PluginId,
|
|
705
|
-
key: string,
|
|
706
|
-
workflow: TWorkflow,
|
|
707
|
-
declaredIds: Set<string>,
|
|
708
|
-
): NornQualifiedPluginWorkflow<PluginId, string, TWorkflow> {
|
|
709
|
-
const id = resolveDeclarationId(pluginId, [key], workflow.id, "workflow", declaredIds);
|
|
710
|
-
const declaration = (params: unknown): NornRunNext => createWorkflowTransition({ workflowId: id, params });
|
|
711
|
-
return Object.assign(declaration, { ...workflow, kind: WORKFLOW_DECLARATION_KIND, id, isolation: workflow.isolation ?? { mode: "runWorkspace" } }) as unknown as NornQualifiedPluginWorkflow<PluginId, string, TWorkflow>;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
function qualifyStateTree(pluginId: string, node: unknown, path: readonly string[], declaredIds: Set<string>): unknown {
|
|
715
|
-
if (node === undefined) return undefined;
|
|
716
|
-
if (isTypeboxSchema(node)) return { id: resolveDeclarationId(pluginId, path, undefined, "state", declaredIds), schema: node };
|
|
717
|
-
if (path.length > 0 && isWorkflowStateDefinitionInput(node)) {
|
|
718
|
-
return { ...node, id: resolveDeclarationId(pluginId, path, node.id, "state", declaredIds) };
|
|
719
|
-
}
|
|
720
|
-
if (!isPlainObject(node)) throw new Error(`Invalid state declaration: ${[pluginId, ...path].join(".")}`);
|
|
721
|
-
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, qualifyStateTree(pluginId, child, [...path, key], declaredIds)]));
|
|
586
|
+
function assertDeclarationId(id: string): void {
|
|
587
|
+
if (typeof id !== "string" || id.trim().length === 0 || id.split(".").some(segment => segment.length === 0)) throw new Error(`Invalid workflow or scope id: ${id}`);
|
|
722
588
|
}
|
|
723
589
|
|
|
724
590
|
export function isWorkflowDeclaration(value: unknown): value is NornAnyWorkflowDeclaration {
|
|
725
591
|
if (typeof value !== "function") return false;
|
|
726
|
-
const candidate = value as { kind?: unknown; id?: unknown; instructions?: unknown; isEntrypoint?: unknown;
|
|
592
|
+
const candidate = value as { kind?: unknown; id?: unknown; instructions?: unknown; isEntrypoint?: unknown; args?: unknown; execute?: unknown; isolation?: { mode?: unknown } };
|
|
727
593
|
return (
|
|
728
594
|
candidate.kind === WORKFLOW_DECLARATION_KIND &&
|
|
729
595
|
typeof candidate.id === "string" &&
|
|
730
596
|
candidate.id.length > 0 &&
|
|
731
597
|
(candidate.instructions === undefined || typeof candidate.instructions === "string") &&
|
|
732
598
|
typeof candidate.isEntrypoint === "boolean" &&
|
|
733
|
-
Boolean(candidate.
|
|
599
|
+
Boolean(candidate.args) &&
|
|
600
|
+
typeof candidate.execute === "function" &&
|
|
734
601
|
(candidate.isolation?.mode === "runWorkspace" || candidate.isolation?.mode === "project")
|
|
735
602
|
);
|
|
736
603
|
}
|
|
737
604
|
|
|
738
|
-
function isTypeboxSchema(value: unknown): value is NornStateSchema {
|
|
739
|
-
return Type.IsUnsafe(value) || Boolean(value && typeof value === "object" && "~kind" in value && typeof value["~kind"] === "string");
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
function isWorkflowStateDefinitionInput(value: unknown): value is NornWorkflowStateDefinitionInput {
|
|
743
|
-
if (!isPlainObject(value)) return false;
|
|
744
|
-
return (value.id === undefined || typeof value.id === "string") && isTypeboxSchema(value.schema);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
export function isWorkflowPlugin(value: unknown): value is NornWorkflowPlugin {
|
|
748
|
-
if (!value || typeof value !== "object") return false;
|
|
749
|
-
const candidate = value as { manifest?: unknown; implementation?: unknown };
|
|
750
|
-
return isWorkflowPluginManifest(candidate.manifest) && Boolean(candidate.implementation);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
export function isWorkflowPluginManifest(value: unknown): value is NornAnyWorkflowPluginManifest {
|
|
754
|
-
if (!value || typeof value !== "object") return false;
|
|
755
|
-
const candidate = value as { id?: unknown; workflows?: unknown };
|
|
756
|
-
if (typeof candidate.id !== "string" || candidate.id.length === 0) return false;
|
|
757
|
-
if (!candidate.workflows || typeof candidate.workflows !== "object") return false;
|
|
758
|
-
return Object.values(candidate.workflows).every(isWorkflowDeclaration);
|
|
759
|
-
}
|
|
760
|
-
|
|
761
605
|
export function isWorkflowNext(value: unknown): value is NornRunNext {
|
|
762
606
|
if (!value || typeof value !== "object") return false;
|
|
763
|
-
const candidate = value as { type?: unknown; workflowId?: unknown;
|
|
607
|
+
const candidate = value as { type?: unknown; workflowId?: unknown; args?: unknown };
|
|
764
608
|
return candidate.type === "next" && typeof candidate.workflowId === "string" && candidate.workflowId.length > 0;
|
|
765
609
|
}
|
|
766
610
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export type { CreateAgentSessionOptions, EventBus, PromptOptions, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
1
2
|
export * from "./api.ts";
|
|
2
3
|
export { NornFileCoordinator } from "./files.ts";
|
|
3
4
|
export * from "./resources.ts";
|
|
4
5
|
export * from "./agent-resource-adapter.ts";
|
|
5
|
-
export * from "./state-adapter.ts";
|
|
@@ -25,9 +25,9 @@ function assertWorkflowReferenceAnnotations(schema: unknown): void {
|
|
|
25
25
|
if (!isPlainObject(schema)) return;
|
|
26
26
|
if (Object.hasOwn(schema, "x-norn-workflow-ref")) {
|
|
27
27
|
const annotation = schema["x-norn-workflow-ref"];
|
|
28
|
-
if (!isPlainObject(annotation) || !Object.hasOwn(annotation, "
|
|
29
|
-
Value.Assert(Meta["https://json-schema.org/draft/2020-12/schema"], annotation.
|
|
30
|
-
assertWorkflowReferenceAnnotations(annotation.
|
|
28
|
+
if (!isPlainObject(annotation) || !Object.hasOwn(annotation, "contributedArgsSchema")) throw new Error("Invalid workflow reference annotation");
|
|
29
|
+
Value.Assert(Meta["https://json-schema.org/draft/2020-12/schema"], annotation.contributedArgsSchema);
|
|
30
|
+
assertWorkflowReferenceAnnotations(annotation.contributedArgsSchema);
|
|
31
31
|
}
|
|
32
32
|
for (const keyword of ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"]) {
|
|
33
33
|
const schemas = schema[keyword];
|