@wopr-network/defcon 0.2.0 → 0.2.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.
Files changed (102) hide show
  1. package/dist/src/execution/cli.js +0 -0
  2. package/package.json +3 -2
  3. package/dist/api/router.d.ts +0 -24
  4. package/dist/api/router.js +0 -44
  5. package/dist/api/server.d.ts +0 -13
  6. package/dist/api/server.js +0 -280
  7. package/dist/api/wire-types.d.ts +0 -46
  8. package/dist/api/wire-types.js +0 -5
  9. package/dist/config/db-path.d.ts +0 -1
  10. package/dist/config/db-path.js +0 -1
  11. package/dist/config/exporter.d.ts +0 -3
  12. package/dist/config/exporter.js +0 -87
  13. package/dist/config/index.d.ts +0 -4
  14. package/dist/config/index.js +0 -4
  15. package/dist/config/seed-loader.d.ts +0 -10
  16. package/dist/config/seed-loader.js +0 -108
  17. package/dist/config/zod-schemas.d.ts +0 -165
  18. package/dist/config/zod-schemas.js +0 -283
  19. package/dist/cors.d.ts +0 -8
  20. package/dist/cors.js +0 -21
  21. package/dist/engine/constants.d.ts +0 -1
  22. package/dist/engine/constants.js +0 -1
  23. package/dist/engine/engine.d.ts +0 -69
  24. package/dist/engine/engine.js +0 -485
  25. package/dist/engine/event-emitter.d.ts +0 -9
  26. package/dist/engine/event-emitter.js +0 -19
  27. package/dist/engine/event-types.d.ts +0 -105
  28. package/dist/engine/event-types.js +0 -1
  29. package/dist/engine/flow-spawner.d.ts +0 -8
  30. package/dist/engine/flow-spawner.js +0 -28
  31. package/dist/engine/gate-command-validator.d.ts +0 -6
  32. package/dist/engine/gate-command-validator.js +0 -46
  33. package/dist/engine/gate-evaluator.d.ts +0 -12
  34. package/dist/engine/gate-evaluator.js +0 -233
  35. package/dist/engine/handlebars.d.ts +0 -9
  36. package/dist/engine/handlebars.js +0 -51
  37. package/dist/engine/index.d.ts +0 -12
  38. package/dist/engine/index.js +0 -7
  39. package/dist/engine/invocation-builder.d.ts +0 -18
  40. package/dist/engine/invocation-builder.js +0 -58
  41. package/dist/engine/on-enter.d.ts +0 -8
  42. package/dist/engine/on-enter.js +0 -102
  43. package/dist/engine/ssrf-guard.d.ts +0 -22
  44. package/dist/engine/ssrf-guard.js +0 -159
  45. package/dist/engine/state-machine.d.ts +0 -12
  46. package/dist/engine/state-machine.js +0 -74
  47. package/dist/execution/active-runner.d.ts +0 -45
  48. package/dist/execution/active-runner.js +0 -165
  49. package/dist/execution/admin-schemas.d.ts +0 -116
  50. package/dist/execution/admin-schemas.js +0 -125
  51. package/dist/execution/cli.d.ts +0 -57
  52. package/dist/execution/cli.js +0 -498
  53. package/dist/execution/handlers/admin.d.ts +0 -67
  54. package/dist/execution/handlers/admin.js +0 -200
  55. package/dist/execution/handlers/flow.d.ts +0 -25
  56. package/dist/execution/handlers/flow.js +0 -289
  57. package/dist/execution/handlers/query.d.ts +0 -31
  58. package/dist/execution/handlers/query.js +0 -64
  59. package/dist/execution/index.d.ts +0 -4
  60. package/dist/execution/index.js +0 -3
  61. package/dist/execution/mcp-helpers.d.ts +0 -42
  62. package/dist/execution/mcp-helpers.js +0 -23
  63. package/dist/execution/mcp-server.d.ts +0 -33
  64. package/dist/execution/mcp-server.js +0 -1020
  65. package/dist/execution/provision-worktree.d.ts +0 -16
  66. package/dist/execution/provision-worktree.js +0 -123
  67. package/dist/execution/tool-schemas.d.ts +0 -40
  68. package/dist/execution/tool-schemas.js +0 -44
  69. package/dist/logger.d.ts +0 -8
  70. package/dist/logger.js +0 -12
  71. package/dist/main.d.ts +0 -14
  72. package/dist/main.js +0 -28
  73. package/dist/repositories/drizzle/entity.repo.d.ts +0 -27
  74. package/dist/repositories/drizzle/entity.repo.js +0 -190
  75. package/dist/repositories/drizzle/event.repo.d.ts +0 -12
  76. package/dist/repositories/drizzle/event.repo.js +0 -24
  77. package/dist/repositories/drizzle/flow.repo.d.ts +0 -22
  78. package/dist/repositories/drizzle/flow.repo.js +0 -364
  79. package/dist/repositories/drizzle/gate.repo.d.ts +0 -16
  80. package/dist/repositories/drizzle/gate.repo.js +0 -98
  81. package/dist/repositories/drizzle/index.d.ts +0 -6
  82. package/dist/repositories/drizzle/index.js +0 -7
  83. package/dist/repositories/drizzle/invocation.repo.d.ts +0 -23
  84. package/dist/repositories/drizzle/invocation.repo.js +0 -199
  85. package/dist/repositories/drizzle/schema.d.ts +0 -1932
  86. package/dist/repositories/drizzle/schema.js +0 -155
  87. package/dist/repositories/drizzle/transition-log.repo.d.ts +0 -11
  88. package/dist/repositories/drizzle/transition-log.repo.js +0 -42
  89. package/dist/repositories/interfaces.d.ts +0 -321
  90. package/dist/repositories/interfaces.js +0 -2
  91. package/dist/utils/redact.d.ts +0 -2
  92. package/dist/utils/redact.js +0 -62
  93. package/gates/blocking-graph.d.ts +0 -26
  94. package/gates/blocking-graph.js +0 -102
  95. package/gates/test/bad-return-gate.d.ts +0 -1
  96. package/gates/test/bad-return-gate.js +0 -4
  97. package/gates/test/passing-gate.d.ts +0 -2
  98. package/gates/test/passing-gate.js +0 -3
  99. package/gates/test/slow-gate.d.ts +0 -2
  100. package/gates/test/slow-gate.js +0 -5
  101. package/gates/test/throwing-gate.d.ts +0 -1
  102. package/gates/test/throwing-gate.js +0 -3
@@ -1,165 +0,0 @@
1
- import { z } from "zod/v4";
2
- export declare const FlowDefinitionSchema: z.ZodObject<{
3
- name: z.ZodString;
4
- description: z.ZodOptional<z.ZodString>;
5
- entitySchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
6
- initialState: z.ZodString;
7
- maxConcurrent: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
8
- maxConcurrentPerRepo: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
9
- affinityWindowMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
10
- gateTimeoutMs: z.ZodOptional<z.ZodNumber>;
11
- version: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
12
- createdBy: z.ZodOptional<z.ZodString>;
13
- discipline: z.ZodString;
14
- defaultModelTier: z.ZodOptional<z.ZodString>;
15
- timeoutPrompt: z.ZodOptional<z.ZodString>;
16
- }, z.core.$strip>;
17
- export declare const OnEnterSchema: z.ZodObject<{
18
- command: z.ZodString;
19
- artifacts: z.ZodArray<z.ZodString>;
20
- timeout_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
21
- }, z.core.$strip>;
22
- export declare const StateDefinitionSchema: z.ZodObject<{
23
- name: z.ZodString;
24
- flowName: z.ZodString;
25
- modelTier: z.ZodOptional<z.ZodString>;
26
- mode: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
27
- passive: "passive";
28
- active: "active";
29
- }>>>;
30
- promptTemplate: z.ZodOptional<z.ZodString>;
31
- constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
32
- onEnter: z.ZodOptional<z.ZodObject<{
33
- command: z.ZodString;
34
- artifacts: z.ZodArray<z.ZodString>;
35
- timeout_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
36
- }, z.core.$strip>>;
37
- }, z.core.$strip>;
38
- export declare const CommandGateSchema: z.ZodObject<{
39
- name: z.ZodString;
40
- timeoutMs: z.ZodOptional<z.ZodNumber>;
41
- failurePrompt: z.ZodOptional<z.ZodString>;
42
- timeoutPrompt: z.ZodOptional<z.ZodString>;
43
- type: z.ZodLiteral<"command">;
44
- command: z.ZodString;
45
- }, z.core.$strip>;
46
- export declare const FunctionGateSchema: z.ZodObject<{
47
- name: z.ZodString;
48
- timeoutMs: z.ZodOptional<z.ZodNumber>;
49
- failurePrompt: z.ZodOptional<z.ZodString>;
50
- timeoutPrompt: z.ZodOptional<z.ZodString>;
51
- type: z.ZodLiteral<"function">;
52
- functionRef: z.ZodString;
53
- }, z.core.$strip>;
54
- export declare const ApiGateSchema: z.ZodObject<{
55
- name: z.ZodString;
56
- timeoutMs: z.ZodOptional<z.ZodNumber>;
57
- failurePrompt: z.ZodOptional<z.ZodString>;
58
- timeoutPrompt: z.ZodOptional<z.ZodString>;
59
- type: z.ZodLiteral<"api">;
60
- apiConfig: z.ZodRecord<z.ZodString, z.ZodUnknown>;
61
- }, z.core.$strip>;
62
- export declare const GateDefinitionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
63
- name: z.ZodString;
64
- timeoutMs: z.ZodOptional<z.ZodNumber>;
65
- failurePrompt: z.ZodOptional<z.ZodString>;
66
- timeoutPrompt: z.ZodOptional<z.ZodString>;
67
- type: z.ZodLiteral<"command">;
68
- command: z.ZodString;
69
- }, z.core.$strip>, z.ZodObject<{
70
- name: z.ZodString;
71
- timeoutMs: z.ZodOptional<z.ZodNumber>;
72
- failurePrompt: z.ZodOptional<z.ZodString>;
73
- timeoutPrompt: z.ZodOptional<z.ZodString>;
74
- type: z.ZodLiteral<"function">;
75
- functionRef: z.ZodString;
76
- }, z.core.$strip>, z.ZodObject<{
77
- name: z.ZodString;
78
- timeoutMs: z.ZodOptional<z.ZodNumber>;
79
- failurePrompt: z.ZodOptional<z.ZodString>;
80
- timeoutPrompt: z.ZodOptional<z.ZodString>;
81
- type: z.ZodLiteral<"api">;
82
- apiConfig: z.ZodRecord<z.ZodString, z.ZodUnknown>;
83
- }, z.core.$strip>], "type">;
84
- export declare const TransitionRuleSchema: z.ZodObject<{
85
- flowName: z.ZodString;
86
- fromState: z.ZodString;
87
- toState: z.ZodString;
88
- trigger: z.ZodString;
89
- gateName: z.ZodOptional<z.ZodString>;
90
- condition: z.ZodOptional<z.ZodString>;
91
- priority: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
92
- spawnFlow: z.ZodOptional<z.ZodString>;
93
- spawnTemplate: z.ZodOptional<z.ZodString>;
94
- }, z.core.$strip>;
95
- export declare const SeedFileSchema: z.ZodObject<{
96
- flows: z.ZodArray<z.ZodObject<{
97
- name: z.ZodString;
98
- description: z.ZodOptional<z.ZodString>;
99
- entitySchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
100
- initialState: z.ZodString;
101
- maxConcurrent: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
102
- maxConcurrentPerRepo: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
103
- affinityWindowMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
104
- gateTimeoutMs: z.ZodOptional<z.ZodNumber>;
105
- version: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
106
- createdBy: z.ZodOptional<z.ZodString>;
107
- discipline: z.ZodString;
108
- defaultModelTier: z.ZodOptional<z.ZodString>;
109
- timeoutPrompt: z.ZodOptional<z.ZodString>;
110
- }, z.core.$strip>>;
111
- states: z.ZodArray<z.ZodObject<{
112
- name: z.ZodString;
113
- flowName: z.ZodString;
114
- modelTier: z.ZodOptional<z.ZodString>;
115
- mode: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
116
- passive: "passive";
117
- active: "active";
118
- }>>>;
119
- promptTemplate: z.ZodOptional<z.ZodString>;
120
- constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
121
- onEnter: z.ZodOptional<z.ZodObject<{
122
- command: z.ZodString;
123
- artifacts: z.ZodArray<z.ZodString>;
124
- timeout_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
125
- }, z.core.$strip>>;
126
- }, z.core.$strip>>;
127
- gates: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
128
- name: z.ZodString;
129
- timeoutMs: z.ZodOptional<z.ZodNumber>;
130
- failurePrompt: z.ZodOptional<z.ZodString>;
131
- timeoutPrompt: z.ZodOptional<z.ZodString>;
132
- type: z.ZodLiteral<"command">;
133
- command: z.ZodString;
134
- }, z.core.$strip>, z.ZodObject<{
135
- name: z.ZodString;
136
- timeoutMs: z.ZodOptional<z.ZodNumber>;
137
- failurePrompt: z.ZodOptional<z.ZodString>;
138
- timeoutPrompt: z.ZodOptional<z.ZodString>;
139
- type: z.ZodLiteral<"function">;
140
- functionRef: z.ZodString;
141
- }, z.core.$strip>, z.ZodObject<{
142
- name: z.ZodString;
143
- timeoutMs: z.ZodOptional<z.ZodNumber>;
144
- failurePrompt: z.ZodOptional<z.ZodString>;
145
- timeoutPrompt: z.ZodOptional<z.ZodString>;
146
- type: z.ZodLiteral<"api">;
147
- apiConfig: z.ZodRecord<z.ZodString, z.ZodUnknown>;
148
- }, z.core.$strip>], "type">>>>;
149
- transitions: z.ZodArray<z.ZodObject<{
150
- flowName: z.ZodString;
151
- fromState: z.ZodString;
152
- toState: z.ZodString;
153
- trigger: z.ZodString;
154
- gateName: z.ZodOptional<z.ZodString>;
155
- condition: z.ZodOptional<z.ZodString>;
156
- priority: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
157
- spawnFlow: z.ZodOptional<z.ZodString>;
158
- spawnTemplate: z.ZodOptional<z.ZodString>;
159
- }, z.core.$strip>>;
160
- }, z.core.$strict>;
161
- export type FlowDefinition = z.infer<typeof FlowDefinitionSchema>;
162
- export type StateDefinition = z.infer<typeof StateDefinitionSchema>;
163
- export type GateDefinition = z.infer<typeof GateDefinitionSchema>;
164
- export type TransitionRule = z.infer<typeof TransitionRuleSchema>;
165
- export type SeedFile = z.infer<typeof SeedFileSchema>;
@@ -1,283 +0,0 @@
1
- import { z } from "zod/v4";
2
- import { validateGateCommand } from "../engine/gate-command-validator.js";
3
- import { validateTemplate } from "../engine/handlebars.js";
4
- // ─── Leaf Schemas ───
5
- export const FlowDefinitionSchema = z.object({
6
- name: z.string().min(1),
7
- description: z.string().optional(),
8
- entitySchema: z.record(z.string(), z.unknown()).optional(),
9
- initialState: z.string().min(1),
10
- maxConcurrent: z.number().int().min(0).optional().default(0),
11
- maxConcurrentPerRepo: z.number().int().min(0).optional().default(0),
12
- affinityWindowMs: z.number().int().min(0).optional().default(300000),
13
- gateTimeoutMs: z.number().int().min(1).optional(),
14
- version: z.number().int().min(1).optional().default(1),
15
- createdBy: z.string().optional(),
16
- discipline: z.string().min(1),
17
- defaultModelTier: z.string().min(1).optional(),
18
- timeoutPrompt: z
19
- .string()
20
- .min(1)
21
- .refine((val) => validateTemplate(val), {
22
- message: "timeoutPrompt contains disallowed Handlebars expressions",
23
- })
24
- .optional(),
25
- });
26
- export const OnEnterSchema = z.object({
27
- command: z
28
- .string()
29
- .min(1)
30
- .refine((val) => validateTemplate(val), {
31
- message: "onEnter command contains disallowed Handlebars expressions",
32
- }),
33
- artifacts: z.array(z.string().min(1)).min(1),
34
- timeout_ms: z.number().int().min(0).optional().default(30000),
35
- });
36
- export const StateDefinitionSchema = z.object({
37
- name: z.string().min(1),
38
- flowName: z.string().min(1),
39
- modelTier: z.string().optional(),
40
- mode: z.enum(["passive", "active"]).optional().default("passive"),
41
- promptTemplate: z
42
- .string()
43
- .min(1)
44
- .refine((val) => validateTemplate(val), {
45
- message: "promptTemplate contains disallowed Handlebars expressions",
46
- })
47
- .optional(),
48
- constraints: z.record(z.string(), z.unknown()).optional(),
49
- onEnter: OnEnterSchema.optional(),
50
- });
51
- // Gate: discriminated union on `type`
52
- const BaseGateSchema = z.object({
53
- name: z.string().min(1),
54
- timeoutMs: z.number().int().min(1).optional(),
55
- failurePrompt: z.string().optional(),
56
- timeoutPrompt: z.string().min(1).optional(),
57
- });
58
- export const CommandGateSchema = BaseGateSchema.extend({
59
- type: z.literal("command"),
60
- command: z
61
- .string()
62
- .min(1)
63
- .superRefine((cmd, ctx) => {
64
- const result = validateGateCommand(cmd);
65
- if (!result.valid) {
66
- ctx.addIssue({ code: "custom", message: result.error ?? "Gate command not allowed" });
67
- }
68
- }),
69
- });
70
- export const FunctionGateSchema = BaseGateSchema.extend({
71
- type: z.literal("function"),
72
- functionRef: z.string().regex(/^[^:]+:[^:]+$/, "functionRef must be in 'path:exportName' format"),
73
- });
74
- export const ApiGateSchema = BaseGateSchema.extend({
75
- type: z.literal("api"),
76
- apiConfig: z.record(z.string(), z.unknown()),
77
- });
78
- export const GateDefinitionSchema = z.discriminatedUnion("type", [
79
- CommandGateSchema,
80
- FunctionGateSchema,
81
- ApiGateSchema,
82
- ]);
83
- export const TransitionRuleSchema = z.object({
84
- flowName: z.string().min(1),
85
- fromState: z.string().min(1),
86
- toState: z.string().min(1),
87
- trigger: z.string().min(1),
88
- gateName: z.string().optional(),
89
- condition: z
90
- .string()
91
- .refine((val) => validateTemplate(val), {
92
- message: "condition contains disallowed Handlebars expressions",
93
- })
94
- .optional(),
95
- priority: z.number().int().min(0).optional().default(0),
96
- spawnFlow: z.string().optional(),
97
- spawnTemplate: z
98
- .string()
99
- .refine((val) => validateTemplate(val), {
100
- message: "spawnTemplate contains disallowed Handlebars expressions",
101
- })
102
- .optional(),
103
- });
104
- // ─── Seed File Schema (with cross-reference validation) ───
105
- export const SeedFileSchema = z
106
- .object({
107
- flows: z.array(FlowDefinitionSchema).min(1),
108
- states: z.array(StateDefinitionSchema).min(1),
109
- gates: z.array(GateDefinitionSchema).optional().default([]),
110
- transitions: z.array(TransitionRuleSchema).min(1),
111
- })
112
- .strict()
113
- .superRefine((seed, ctx) => {
114
- // Bug 2 fix: detect duplicate flow names explicitly before building the Set
115
- const flowNames = new Set();
116
- for (let i = 0; i < seed.flows.length; i++) {
117
- const name = seed.flows[i].name;
118
- if (flowNames.has(name)) {
119
- ctx.addIssue({
120
- code: "custom",
121
- message: `Duplicate flow name "${name}"`,
122
- path: ["flows", i, "name"],
123
- });
124
- }
125
- else {
126
- flowNames.add(name);
127
- }
128
- }
129
- // Bug 2 fix: detect duplicate gate names explicitly before building the Set
130
- const gateNames = new Set();
131
- for (let i = 0; i < seed.gates.length; i++) {
132
- const name = seed.gates[i].name;
133
- if (gateNames.has(name)) {
134
- ctx.addIssue({
135
- code: "custom",
136
- message: `Duplicate gate name "${name}"`,
137
- path: ["gates", i, "name"],
138
- });
139
- }
140
- else {
141
- gateNames.add(name);
142
- }
143
- }
144
- // Detect duplicate state names within a flow
145
- const stateNamesByFlow = new Map();
146
- for (let i = 0; i < seed.states.length; i++) {
147
- const s = seed.states[i];
148
- if (!stateNamesByFlow.has(s.flowName)) {
149
- stateNamesByFlow.set(s.flowName, new Set());
150
- }
151
- const seen = stateNamesByFlow.get(s.flowName);
152
- if (seen?.has(s.name)) {
153
- ctx.addIssue({
154
- code: "custom",
155
- message: `Duplicate state name '${s.name}' in flow '${s.flowName}'`,
156
- path: ["states", i, "name"],
157
- });
158
- }
159
- else {
160
- seen?.add(s.name);
161
- }
162
- }
163
- // Bug 1 fix: only populate statesByFlow for flows that actually exist,
164
- // so that transitions referencing unknown flows don't find stale state data.
165
- const statesByFlow = new Map();
166
- for (const s of seed.states) {
167
- if (!flowNames.has(s.flowName))
168
- continue;
169
- if (!statesByFlow.has(s.flowName)) {
170
- statesByFlow.set(s.flowName, new Set());
171
- }
172
- statesByFlow.get(s.flowName)?.add(s.name);
173
- }
174
- // Validate states reference existing flows
175
- for (let i = 0; i < seed.states.length; i++) {
176
- const s = seed.states[i];
177
- if (!flowNames.has(s.flowName)) {
178
- ctx.addIssue({
179
- code: "custom",
180
- message: `State "${s.name}" references unknown flow "${s.flowName}"`,
181
- path: ["states", i, "flowName"],
182
- });
183
- }
184
- }
185
- // Validate each flow's initialState is a defined state
186
- for (let i = 0; i < seed.flows.length; i++) {
187
- const f = seed.flows[i];
188
- const flowStates = statesByFlow.get(f.name);
189
- if (!flowStates || !flowStates.has(f.initialState)) {
190
- ctx.addIssue({
191
- code: "custom",
192
- message: `Flow "${f.name}" has initialState "${f.initialState}" which is not a defined state`,
193
- path: ["flows", i, "initialState"],
194
- });
195
- }
196
- }
197
- // Validate transitions
198
- for (let i = 0; i < seed.transitions.length; i++) {
199
- const t = seed.transitions[i];
200
- if (!flowNames.has(t.flowName)) {
201
- ctx.addIssue({
202
- code: "custom",
203
- message: `Transition references unknown flow "${t.flowName}"`,
204
- path: ["transitions", i, "flowName"],
205
- });
206
- }
207
- else {
208
- // Bug 3 fix: flow exists — check fromState/toState even if the flow has
209
- // zero states (statesByFlow entry will be missing or empty in that case).
210
- const flowStates = statesByFlow.get(t.flowName) ?? new Set();
211
- if (!flowStates.has(t.fromState)) {
212
- ctx.addIssue({
213
- code: "custom",
214
- message: `Transition fromState "${t.fromState}" not defined in flow "${t.flowName}"`,
215
- path: ["transitions", i, "fromState"],
216
- });
217
- }
218
- if (!flowStates.has(t.toState)) {
219
- ctx.addIssue({
220
- code: "custom",
221
- message: `Transition toState "${t.toState}" not defined in flow "${t.flowName}"`,
222
- path: ["transitions", i, "toState"],
223
- });
224
- }
225
- }
226
- if (t.gateName && !gateNames.has(t.gateName)) {
227
- ctx.addIssue({
228
- code: "custom",
229
- message: `Transition references unknown gate "${t.gateName}"`,
230
- path: ["transitions", i, "gateName"],
231
- });
232
- }
233
- if (t.spawnFlow && !flowNames.has(t.spawnFlow)) {
234
- ctx.addIssue({
235
- code: "custom",
236
- message: `Transition spawnFlow "${t.spawnFlow}" references unknown flow`,
237
- path: ["transitions", i, "spawnFlow"],
238
- });
239
- }
240
- }
241
- // Detect circular spawnFlow chains via DFS
242
- const spawnAdj = new Map();
243
- for (const t of seed.transitions) {
244
- if (t.spawnFlow && flowNames.has(t.flowName) && flowNames.has(t.spawnFlow)) {
245
- if (!spawnAdj.has(t.flowName))
246
- spawnAdj.set(t.flowName, new Set());
247
- spawnAdj.get(t.flowName)?.add(t.spawnFlow);
248
- }
249
- }
250
- const visited = new Set();
251
- const inStack = new Set();
252
- function dfs(node, path) {
253
- if (inStack.has(node))
254
- return [...path, node];
255
- if (visited.has(node))
256
- return null;
257
- visited.add(node);
258
- inStack.add(node);
259
- for (const neighbor of spawnAdj.get(node) ?? []) {
260
- const cycle = dfs(neighbor, [...path, node]);
261
- if (cycle)
262
- return cycle;
263
- }
264
- inStack.delete(node);
265
- return null;
266
- }
267
- for (const flowName of spawnAdj.keys()) {
268
- if (visited.has(flowName))
269
- continue;
270
- const cycle = dfs(flowName, []);
271
- if (cycle) {
272
- const cycleStart = cycle[cycle.length - 1];
273
- const cycleStartIdx = cycle.indexOf(cycleStart);
274
- const cyclePath = cycle.slice(cycleStartIdx);
275
- ctx.addIssue({
276
- code: "custom",
277
- message: `Circular spawnFlow chain detected: ${cyclePath.join(" -> ")}`,
278
- path: ["transitions"],
279
- });
280
- break;
281
- }
282
- }
283
- });
package/dist/cors.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export interface CorsOriginResult {
2
- /** Explicit allowed origin, or null meaning "loopback-only default pattern" */
3
- origin: string | null;
4
- }
5
- export declare function resolveCorsOrigin(opts: {
6
- host: string;
7
- corsEnv: string | undefined;
8
- }): CorsOriginResult;
package/dist/cors.js DELETED
@@ -1,21 +0,0 @@
1
- const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1"]);
2
- export function resolveCorsOrigin(opts) {
3
- const corsValue = opts.corsEnv?.trim() || undefined;
4
- const isLoopback = LOOPBACK_HOSTS.has(opts.host);
5
- // If explicit origin provided, validate and use it
6
- if (corsValue) {
7
- if (!/^https?:\/\/[^/]+$/.test(corsValue)) {
8
- throw new Error(`DEFCON_CORS_ORIGIN must be a bare origin like https://app.example.com, not ${corsValue}. ` +
9
- "Remove any path component or trailing slash.");
10
- }
11
- return { origin: corsValue };
12
- }
13
- // Non-loopback without explicit origin — refuse to start
14
- if (!isLoopback) {
15
- throw new Error(`DEFCON_CORS_ORIGIN must be set when binding to non-loopback address "${opts.host}". ` +
16
- "Without an explicit CORS origin, any website on the network can make cross-origin requests to this server. " +
17
- 'Set DEFCON_CORS_ORIGIN to the allowed origin (e.g. "https://my-app.example.com") or use a loopback address.');
18
- }
19
- // Loopback without explicit origin — use default pattern
20
- return { origin: null };
21
- }
@@ -1 +0,0 @@
1
- export declare const DEFAULT_TIMEOUT_PROMPT = "Your report was received. The gate is still evaluating \u2014 this is not an error. Call flow.claim to reclaim the entity, then call flow.report again with the same arguments after a short wait.";
@@ -1 +0,0 @@
1
- export const DEFAULT_TIMEOUT_PROMPT = "Your report was received. The gate is still evaluating — this is not an error. Call flow.claim to reclaim the entity, then call flow.report again with the same arguments after a short wait.";
@@ -1,69 +0,0 @@
1
- import type { Logger } from "../logger.js";
2
- import type { Artifacts, Entity, IEntityRepository, IFlowRepository, IGateRepository, IInvocationRepository, ITransitionLogRepository } from "../repositories/interfaces.js";
3
- import type { IEventBusAdapter } from "./event-types.js";
4
- export interface ProcessSignalResult {
5
- newState?: string;
6
- /** Names (not IDs) of gates that evaluated and passed during this transition. */
7
- gatesPassed: string[];
8
- gated: boolean;
9
- gateTimedOut?: boolean;
10
- gateOutput?: string;
11
- gateName?: string;
12
- failurePrompt?: string;
13
- timeoutPrompt?: string;
14
- onEnterFailed?: boolean;
15
- invocationId?: string;
16
- spawned?: string[];
17
- terminal: boolean;
18
- }
19
- export interface ClaimWorkResult {
20
- entityId: string;
21
- invocationId: string;
22
- prompt: string;
23
- context: Record<string, unknown> | null;
24
- }
25
- export interface EngineStatus {
26
- flows: Record<string, Record<string, number>>;
27
- activeInvocations: number;
28
- pendingClaims: number;
29
- }
30
- export interface EngineDeps {
31
- entityRepo: IEntityRepository;
32
- flowRepo: IFlowRepository;
33
- invocationRepo: IInvocationRepository;
34
- gateRepo: IGateRepository;
35
- transitionLogRepo: ITransitionLogRepository;
36
- adapters: Map<string, unknown>;
37
- eventEmitter: IEventBusAdapter;
38
- logger?: Logger;
39
- }
40
- export declare class Engine {
41
- private entityRepo;
42
- private flowRepo;
43
- private invocationRepo;
44
- private gateRepo;
45
- private transitionLogRepo;
46
- readonly adapters: Map<string, unknown>;
47
- private eventEmitter;
48
- private readonly logger;
49
- constructor(deps: EngineDeps);
50
- processSignal(entityId: string, signal: string, artifacts?: Artifacts, triggeringInvocationId?: string): Promise<ProcessSignalResult>;
51
- createEntity(flowName: string, refs?: Record<string, {
52
- adapter: string;
53
- id: string;
54
- [key: string]: unknown;
55
- }>): Promise<Entity>;
56
- claimWork(role: string, flowName?: string, worker_id?: string): Promise<ClaimWorkResult | null>;
57
- /**
58
- * Try to claim an existing unclaimed invocation for an already-claimed entity.
59
- * Handles the race condition where another worker claims the invocation first
60
- * (releases the entity claim and returns null so the caller can try the next candidate).
61
- */
62
- private tryClaimInvocation;
63
- private setAffinityIfNeeded;
64
- private buildPrompt;
65
- private emitAndReturn;
66
- getStatus(): Promise<EngineStatus>;
67
- startReaper(intervalMs: number, entityTtlMs?: number): () => Promise<void>;
68
- private checkConcurrency;
69
- }