@kitman-sh/cli 0.0.0-stage → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-3j7sewn0.js +4618 -0
- package/dist/chunk-6h8ghah0.js +14 -0
- package/dist/chunk-brp7cekg.js +13 -0
- package/dist/chunk-dsefng1v.js +1085 -0
- package/dist/chunk-fc0v325q.js +75 -0
- package/dist/chunk-h8ctzn91.js +241 -0
- package/dist/chunk-hrvcz0m4.js +211 -0
- package/dist/chunk-hw7qkap1.js +1517 -0
- package/dist/chunk-n32jhswz.js +964 -0
- package/dist/chunk-tfr74ays.js +7060 -0
- package/dist/chunk-txyq8r41.js +25537 -0
- package/dist/chunk-xdk488qp.js +364 -0
- package/dist/egress-proxy.ts +107 -0
- package/dist/index.js +5738 -0
- package/package.json +16 -4
- package/README.md +0 -3
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
dual,
|
|
4
|
+
hasProperty,
|
|
5
|
+
Prototype,
|
|
6
|
+
isNone,
|
|
7
|
+
Service2,
|
|
8
|
+
empty,
|
|
9
|
+
add,
|
|
10
|
+
getOrUndefined2,
|
|
11
|
+
get,
|
|
12
|
+
merge,
|
|
13
|
+
Reference,
|
|
14
|
+
fromInputUnsafe,
|
|
15
|
+
toMillis,
|
|
16
|
+
TaggedClass,
|
|
17
|
+
hasInterruptsOnly,
|
|
18
|
+
combine,
|
|
19
|
+
squash,
|
|
20
|
+
hasInterrupts,
|
|
21
|
+
isSuccess2,
|
|
22
|
+
addFinalizerExit,
|
|
23
|
+
effectDiscard,
|
|
24
|
+
min,
|
|
25
|
+
exponential,
|
|
26
|
+
spaced,
|
|
27
|
+
while_,
|
|
28
|
+
setInputType,
|
|
29
|
+
promise,
|
|
30
|
+
succeed5,
|
|
31
|
+
suspend,
|
|
32
|
+
sync,
|
|
33
|
+
void_2,
|
|
34
|
+
callback,
|
|
35
|
+
gen,
|
|
36
|
+
fail4,
|
|
37
|
+
failCause2,
|
|
38
|
+
die3,
|
|
39
|
+
try_,
|
|
40
|
+
yieldNow,
|
|
41
|
+
flatMap,
|
|
42
|
+
andThen,
|
|
43
|
+
tap,
|
|
44
|
+
map3,
|
|
45
|
+
catch_,
|
|
46
|
+
mapError,
|
|
47
|
+
orDie,
|
|
48
|
+
retry,
|
|
49
|
+
sandbox,
|
|
50
|
+
matchEffect,
|
|
51
|
+
context,
|
|
52
|
+
contextWith,
|
|
53
|
+
provideContext,
|
|
54
|
+
provideService,
|
|
55
|
+
acquireUseRelease,
|
|
56
|
+
onExit,
|
|
57
|
+
interruptible,
|
|
58
|
+
uninterruptibleMask,
|
|
59
|
+
annotateCurrentSpan,
|
|
60
|
+
withSpan,
|
|
61
|
+
fnUntraced,
|
|
62
|
+
getCurrent,
|
|
63
|
+
encode2,
|
|
64
|
+
transform,
|
|
65
|
+
encodeBase64Url,
|
|
66
|
+
decodeBase64UrlString,
|
|
67
|
+
decodeUnknownEffect,
|
|
68
|
+
decodeEffect,
|
|
69
|
+
decodeSync,
|
|
70
|
+
encodeUnknownEffect,
|
|
71
|
+
encodeEffect,
|
|
72
|
+
encodeSync,
|
|
73
|
+
isSchema,
|
|
74
|
+
optionalKey,
|
|
75
|
+
optional,
|
|
76
|
+
Literal,
|
|
77
|
+
Never,
|
|
78
|
+
Unknown,
|
|
79
|
+
String2,
|
|
80
|
+
Boolean2,
|
|
81
|
+
Void,
|
|
82
|
+
Struct,
|
|
83
|
+
Record,
|
|
84
|
+
Tuple,
|
|
85
|
+
ArraySchema,
|
|
86
|
+
Union,
|
|
87
|
+
Literals,
|
|
88
|
+
decodeTo,
|
|
89
|
+
tag,
|
|
90
|
+
makeFilter,
|
|
91
|
+
Finite,
|
|
92
|
+
Int,
|
|
93
|
+
Defect,
|
|
94
|
+
fromJsonString,
|
|
95
|
+
Cause,
|
|
96
|
+
Exit,
|
|
97
|
+
Class,
|
|
98
|
+
TaggedError2,
|
|
99
|
+
toJsonSchemaDocument,
|
|
100
|
+
toCodecJson,
|
|
101
|
+
Json
|
|
102
|
+
} from "./chunk-txyq8r41.js";
|
|
103
|
+
import {
|
|
104
|
+
LoopCapabilities
|
|
105
|
+
} from "./chunk-hrvcz0m4.js";
|
|
106
|
+
|
|
107
|
+
// packages/sdk/src/loop/define.ts
|
|
108
|
+
var LoopOutcome = Literals(["feature", "bug", "refactor", "investigation", "docs", "migration"]);
|
|
109
|
+
var defineLoop = (definition) => definition;
|
|
110
|
+
|
|
111
|
+
class ManifestInvalid extends TaggedError2()("ManifestInvalid", {
|
|
112
|
+
loop: String2,
|
|
113
|
+
message: String2
|
|
114
|
+
}) {
|
|
115
|
+
}
|
|
116
|
+
var jsonSchemaOf = (loop, schema) => try_({
|
|
117
|
+
try: () => toJsonSchemaDocument(schema),
|
|
118
|
+
catch: (error) => new ManifestInvalid({ loop, message: `Schema has no JSON Schema: ${String(error)}` })
|
|
119
|
+
}).pipe(flatMap((document) => decodeUnknownEffect(JsonObjectSchema)({ ...document.schema, $defs: document.definitions }).pipe(mapError((error) => new ManifestInvalid({ loop, message: error.message })))));
|
|
120
|
+
var JsonObjectSchema = Record(String2, Json);
|
|
121
|
+
// node_modules/.bun/effect@4.0.4/node_modules/effect/dist/workflow/internal/crypto.js
|
|
122
|
+
var makeHashDigest = (original) => map3(promise(() => crypto.subtle.digest("SHA-256", new TextEncoder().encode(original))), (buffer) => {
|
|
123
|
+
const data = new Uint8Array(buffer);
|
|
124
|
+
let hexString = "";
|
|
125
|
+
for (let i = 0;i < 16; i++) {
|
|
126
|
+
hexString += data[i].toString(16).padStart(2, "0");
|
|
127
|
+
}
|
|
128
|
+
return hexString;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// node_modules/.bun/effect@4.0.4/node_modules/effect/dist/workflow/Workflow.js
|
|
132
|
+
var TypeId = "~effect/workflow/Workflow";
|
|
133
|
+
var EngineTag = /* @__PURE__ */ Service2("effect/workflow/WorkflowEngine");
|
|
134
|
+
var InstanceTag = /* @__PURE__ */ Service2("effect/workflow/WorkflowEngine/WorkflowInstance");
|
|
135
|
+
var makeExecutionIdFromPayload = (self, payload) => makeHashDigest(`${self._tag.length}:${self._tag}:${self.idempotencyKey(payload)}`);
|
|
136
|
+
var Proto = {
|
|
137
|
+
[TypeId]: TypeId,
|
|
138
|
+
annotate(tag, value) {
|
|
139
|
+
return makeProto({
|
|
140
|
+
_tag: this._tag,
|
|
141
|
+
payloadSchema: this.payloadSchema,
|
|
142
|
+
successSchema: this.successSchema,
|
|
143
|
+
errorSchema: this.errorSchema,
|
|
144
|
+
annotations: add(this.annotations, tag, value),
|
|
145
|
+
idempotencyKey: this.idempotencyKey,
|
|
146
|
+
suspendedRetrySchedule: this.suspendedRetrySchedule
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
annotateMerge(context) {
|
|
150
|
+
return makeProto({
|
|
151
|
+
_tag: this._tag,
|
|
152
|
+
payloadSchema: this.payloadSchema,
|
|
153
|
+
successSchema: this.successSchema,
|
|
154
|
+
errorSchema: this.errorSchema,
|
|
155
|
+
annotations: merge(this.annotations, context),
|
|
156
|
+
idempotencyKey: this.idempotencyKey,
|
|
157
|
+
suspendedRetrySchedule: this.suspendedRetrySchedule
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
execute(fields, opts) {
|
|
161
|
+
return suspend(() => {
|
|
162
|
+
const payload = this.payloadSchema.make(fields);
|
|
163
|
+
const run = flatMap(EngineTag, (engine) => flatMap(makeExecutionIdFromPayload(this, payload), (executionId) => andThen(annotateCurrentSpan({
|
|
164
|
+
executionId
|
|
165
|
+
}), engine.execute(this, {
|
|
166
|
+
executionId,
|
|
167
|
+
payload,
|
|
168
|
+
discard: opts?.discard,
|
|
169
|
+
suspendedRetrySchedule: this.suspendedRetrySchedule
|
|
170
|
+
}))));
|
|
171
|
+
return opts?.discard ? run : withPendingActivity(run);
|
|
172
|
+
}).pipe(withSpan(`${this._tag}.execute`, {}, {
|
|
173
|
+
captureStackTrace: false
|
|
174
|
+
}));
|
|
175
|
+
},
|
|
176
|
+
poll(executionId) {
|
|
177
|
+
return flatMap(EngineTag, (engine) => engine.poll(this, executionId)).pipe(withSpan(`${this._tag}.poll`, {
|
|
178
|
+
attributes: {
|
|
179
|
+
executionId
|
|
180
|
+
}
|
|
181
|
+
}, {
|
|
182
|
+
captureStackTrace: false
|
|
183
|
+
}));
|
|
184
|
+
},
|
|
185
|
+
interrupt(executionId) {
|
|
186
|
+
return flatMap(EngineTag, (engine) => engine.interrupt(this, executionId)).pipe(withSpan(`${this._tag}.interrupt`, {
|
|
187
|
+
attributes: {
|
|
188
|
+
executionId
|
|
189
|
+
}
|
|
190
|
+
}, {
|
|
191
|
+
captureStackTrace: false
|
|
192
|
+
}));
|
|
193
|
+
},
|
|
194
|
+
resume(executionId) {
|
|
195
|
+
return flatMap(EngineTag, (engine) => engine.resume(this, executionId)).pipe(withSpan(`${this._tag}.resume`, {
|
|
196
|
+
attributes: {
|
|
197
|
+
executionId
|
|
198
|
+
}
|
|
199
|
+
}, {
|
|
200
|
+
captureStackTrace: false
|
|
201
|
+
}));
|
|
202
|
+
},
|
|
203
|
+
toLayer(execute) {
|
|
204
|
+
return effectDiscard(flatMap(EngineTag, (engine) => engine.register(this, execute)));
|
|
205
|
+
},
|
|
206
|
+
executionId(payload) {
|
|
207
|
+
return flatMap(orDie(this.payloadSchema.makeEffect(payload)), (payload) => makeExecutionIdFromPayload(this, payload));
|
|
208
|
+
},
|
|
209
|
+
withCompensation: (...args) => withCompensation(...args)
|
|
210
|
+
};
|
|
211
|
+
var makeProto = (options) => {
|
|
212
|
+
function Workflow() {}
|
|
213
|
+
Object.setPrototypeOf(Workflow, Proto);
|
|
214
|
+
Object.assign(Workflow, options);
|
|
215
|
+
return Workflow;
|
|
216
|
+
};
|
|
217
|
+
var make = (tag, options) => makeProto({
|
|
218
|
+
_tag: tag,
|
|
219
|
+
payloadSchema: isSchema(options.payload) ? options.payload : Struct(options.payload),
|
|
220
|
+
successSchema: options.success ?? Void,
|
|
221
|
+
errorSchema: options.error ?? Never,
|
|
222
|
+
annotations: options.annotations ?? empty(),
|
|
223
|
+
idempotencyKey: options.idempotencyKey,
|
|
224
|
+
suspendedRetrySchedule: options.suspendedRetrySchedule
|
|
225
|
+
});
|
|
226
|
+
var ResultTypeId = "~effect/workflow/Workflow/Result";
|
|
227
|
+
var isResult = (u) => hasProperty(u, ResultTypeId);
|
|
228
|
+
class Suspended extends (/* @__PURE__ */ Class("effect/workflow/Workflow/Suspended")({
|
|
229
|
+
_tag: /* @__PURE__ */ tag("Suspended"),
|
|
230
|
+
cause: /* @__PURE__ */ optional(/* @__PURE__ */ Cause(Never, /* @__PURE__ */ Defect()))
|
|
231
|
+
})) {
|
|
232
|
+
[ResultTypeId] = ResultTypeId;
|
|
233
|
+
}
|
|
234
|
+
var wrapActivityResult = (effect, isSuspend) => contextWith((context) => {
|
|
235
|
+
const instance = get(context, InstanceTag);
|
|
236
|
+
return acquireUseRelease(sync(() => adoptActivityUnsafe(context, instance) ?? registerActivityUnsafe(instance)), () => effect, (registration, exit) => {
|
|
237
|
+
releaseActivityUnsafe(registration);
|
|
238
|
+
const isSuspended = isSuccess2(exit) && isSuspend(exit.value);
|
|
239
|
+
if (isSuccess2(exit) && isResult(exit.value) && exit.value._tag === "Suspended" && exit.value.cause) {
|
|
240
|
+
instance.cause = instance.cause ? combine(instance.cause, exit.value.cause) : exit.value.cause;
|
|
241
|
+
}
|
|
242
|
+
return isSuspended && instance.activityState.count > 0 ? waitForZero(instance) : void_2;
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
var PendingActivityRegistration = /* @__PURE__ */ Service2("effect/workflow/Workflow/PendingActivityRegistration");
|
|
246
|
+
var registerActivityUnsafe = (instance) => {
|
|
247
|
+
const state = instance.activityState;
|
|
248
|
+
if (state.count === 0)
|
|
249
|
+
state.latch.closeUnsafe();
|
|
250
|
+
state.count++;
|
|
251
|
+
return {
|
|
252
|
+
instance,
|
|
253
|
+
state: "pending"
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
var adoptActivityUnsafe = (context, instance) => {
|
|
257
|
+
const pending = getOrUndefined2(context, PendingActivityRegistration);
|
|
258
|
+
if (!pending || pending.instance !== instance) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (pending.state !== "pending") {
|
|
262
|
+
throw new Error("Workflow.wrapActivityResult: pending child registration has already been consumed");
|
|
263
|
+
}
|
|
264
|
+
pending.state = "adopted";
|
|
265
|
+
return pending;
|
|
266
|
+
};
|
|
267
|
+
var releaseActivityUnsafe = (registration) => {
|
|
268
|
+
if (registration.state === "released")
|
|
269
|
+
return;
|
|
270
|
+
registration.state = "released";
|
|
271
|
+
const state = registration.instance.activityState;
|
|
272
|
+
state.count--;
|
|
273
|
+
if (state.count === 0)
|
|
274
|
+
state.latch.openUnsafe();
|
|
275
|
+
};
|
|
276
|
+
var withPendingActivity = (effect) => contextWith((context) => {
|
|
277
|
+
const instance = getOrUndefined2(context, InstanceTag);
|
|
278
|
+
if (!instance)
|
|
279
|
+
return effect;
|
|
280
|
+
return acquireUseRelease(sync(() => registerActivityUnsafe(instance)), (registration) => provideService(effect, PendingActivityRegistration, registration), (registration) => sync(() => releaseActivityUnsafe(registration)));
|
|
281
|
+
});
|
|
282
|
+
var waitForZero = /* @__PURE__ */ fnUntraced(function* (instance) {
|
|
283
|
+
const state = instance.activityState;
|
|
284
|
+
while (true) {
|
|
285
|
+
if (state.count > 0) {
|
|
286
|
+
yield* state.latch.await;
|
|
287
|
+
yield* yieldNow;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
yield* yieldNow;
|
|
291
|
+
if (state.count === 0)
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
var addFinalizer = /* @__PURE__ */ fnUntraced(function* (f) {
|
|
296
|
+
const instance = yield* InstanceTag;
|
|
297
|
+
const services = yield* context();
|
|
298
|
+
yield* addFinalizerExit(instance.scope, (exit) => instance.abandoned ? void_2 : provideContext(f(exit), services));
|
|
299
|
+
});
|
|
300
|
+
var withCompensation = /* @__PURE__ */ dual(2, (effect, compensation) => uninterruptibleMask((restore) => tap(restore(effect), (value) => addFinalizer((exit) => isSuccess2(exit) ? void_2 : compensation(value, exit.cause)))));
|
|
301
|
+
var suspend2 = (instance) => interruptible(callback(() => {
|
|
302
|
+
instance.suspended = true;
|
|
303
|
+
const fiber = getCurrent();
|
|
304
|
+
fiber.interruptUnsafe(fiber.id);
|
|
305
|
+
}));
|
|
306
|
+
|
|
307
|
+
// node_modules/.bun/effect@4.0.4/node_modules/effect/dist/workflow/DurableDeferred.js
|
|
308
|
+
var TypeId2 = "~effect/workflow/DurableDeferred";
|
|
309
|
+
var make2 = (name, options) => {
|
|
310
|
+
const successSchema = options?.success ?? Void;
|
|
311
|
+
const errorSchema = options?.error ?? Never;
|
|
312
|
+
return {
|
|
313
|
+
[TypeId2]: TypeId2,
|
|
314
|
+
name,
|
|
315
|
+
successSchema,
|
|
316
|
+
errorSchema,
|
|
317
|
+
exitSchema: Exit(toCodecJson(successSchema), toCodecJson(errorSchema), toCodecJson(Defect())),
|
|
318
|
+
withActivityAttempt: gen(function* () {
|
|
319
|
+
const attempt = yield* CurrentAttempt;
|
|
320
|
+
return make2(`${name}/${attempt}`, {
|
|
321
|
+
success: successSchema,
|
|
322
|
+
error: errorSchema
|
|
323
|
+
});
|
|
324
|
+
})
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
var EngineTag2 = /* @__PURE__ */ Service2("effect/workflow/WorkflowEngine");
|
|
328
|
+
var InstanceTag2 = /* @__PURE__ */ Service2("effect/workflow/WorkflowEngine/WorkflowInstance");
|
|
329
|
+
var CurrentAttempt = /* @__PURE__ */ Reference("effect/workflow/Activity/CurrentAttempt", {
|
|
330
|
+
defaultValue: () => 1
|
|
331
|
+
});
|
|
332
|
+
var awaitOwners = /* @__PURE__ */ new WeakMap;
|
|
333
|
+
var registerAwait = (instance, name) => {
|
|
334
|
+
instance.awaitedDeferreds.set(name, (instance.awaitedDeferreds.get(name) ?? 0) + 1);
|
|
335
|
+
awaitOwners.get(instance)?.push(name);
|
|
336
|
+
};
|
|
337
|
+
var await_ = /* @__PURE__ */ fnUntraced(function* (self) {
|
|
338
|
+
const engine = yield* EngineTag2;
|
|
339
|
+
const instance = yield* InstanceTag2;
|
|
340
|
+
registerAwait(instance, self.name);
|
|
341
|
+
const exit = yield* wrapActivityResult(engine.deferredResult(self), isNone);
|
|
342
|
+
if (isNone(exit)) {
|
|
343
|
+
return yield* suspend2(instance);
|
|
344
|
+
}
|
|
345
|
+
return yield* exit.value;
|
|
346
|
+
});
|
|
347
|
+
class TokenParsed extends (/* @__PURE__ */ Class("effect/workflow/DurableDeferred/TokenParsed")({
|
|
348
|
+
workflowName: String2,
|
|
349
|
+
executionId: String2,
|
|
350
|
+
deferredName: String2
|
|
351
|
+
})) {
|
|
352
|
+
get asToken() {
|
|
353
|
+
return encode2(JSON.stringify([this.workflowName, this.executionId, this.deferredName]));
|
|
354
|
+
}
|
|
355
|
+
static FromString = /* @__PURE__ */ String2.pipe(/* @__PURE__ */ decodeTo(/* @__PURE__ */ fromJsonString(/* @__PURE__ */ Tuple([String2, String2, String2])), {
|
|
356
|
+
decode: /* @__PURE__ */ decodeBase64UrlString(),
|
|
357
|
+
encode: /* @__PURE__ */ encodeBase64Url()
|
|
358
|
+
}), /* @__PURE__ */ decodeTo(TokenParsed, {
|
|
359
|
+
decode: /* @__PURE__ */ transform(([workflowName, executionId, deferredName]) => new TokenParsed({
|
|
360
|
+
workflowName,
|
|
361
|
+
executionId,
|
|
362
|
+
deferredName
|
|
363
|
+
})),
|
|
364
|
+
encode: /* @__PURE__ */ transform((parsed) => [parsed.workflowName, parsed.executionId, parsed.deferredName])
|
|
365
|
+
}));
|
|
366
|
+
static fromString = /* @__PURE__ */ decodeSync(TokenParsed.FromString);
|
|
367
|
+
static encode = /* @__PURE__ */ encodeSync(TokenParsed.FromString);
|
|
368
|
+
}
|
|
369
|
+
var token = /* @__PURE__ */ fnUntraced(function* (self) {
|
|
370
|
+
const instance = yield* InstanceTag2;
|
|
371
|
+
return tokenFromExecutionId(self, instance);
|
|
372
|
+
});
|
|
373
|
+
var tokenFromExecutionId = /* @__PURE__ */ dual(2, (self, options) => new TokenParsed({
|
|
374
|
+
workflowName: options.workflow._tag,
|
|
375
|
+
executionId: options.executionId,
|
|
376
|
+
deferredName: self.name
|
|
377
|
+
}).asToken);
|
|
378
|
+
|
|
379
|
+
// node_modules/.bun/effect@4.0.4/node_modules/effect/dist/workflow/Activity.js
|
|
380
|
+
var TypeId3 = "~effect/workflow/Activity";
|
|
381
|
+
var make3 = (options) => {
|
|
382
|
+
const successSchema = options.success ?? Void;
|
|
383
|
+
const errorSchema = options.error ?? Never;
|
|
384
|
+
const successSchemaJson = toCodecJson(successSchema);
|
|
385
|
+
const errorSchemaJson = toCodecJson(errorSchema);
|
|
386
|
+
let execute;
|
|
387
|
+
const executeWithoutInterrupt = retryOnInterrupt(options.name, options.interruptRetryPolicy)(options.execute);
|
|
388
|
+
const self = {
|
|
389
|
+
...Prototype({
|
|
390
|
+
label: "Activity",
|
|
391
|
+
evaluate(_) {
|
|
392
|
+
return execute;
|
|
393
|
+
}
|
|
394
|
+
}),
|
|
395
|
+
[TypeId3]: TypeId3,
|
|
396
|
+
name: options.name,
|
|
397
|
+
successSchema,
|
|
398
|
+
errorSchema,
|
|
399
|
+
exitSchema: Exit(successSchemaJson, errorSchemaJson, Defect()),
|
|
400
|
+
exitSchemaPartial: Exit(successSchemaJson, errorSchemaJson, Unknown),
|
|
401
|
+
annotations: options.annotations ?? empty(),
|
|
402
|
+
annotate(tag, value) {
|
|
403
|
+
return make3({
|
|
404
|
+
...options,
|
|
405
|
+
annotations: add(self.annotations, tag, value)
|
|
406
|
+
});
|
|
407
|
+
},
|
|
408
|
+
annotateMerge(context) {
|
|
409
|
+
return make3({
|
|
410
|
+
...options,
|
|
411
|
+
annotations: merge(self.annotations, context)
|
|
412
|
+
});
|
|
413
|
+
},
|
|
414
|
+
execute: executeWithoutInterrupt,
|
|
415
|
+
executeEncoded: matchEffect(executeWithoutInterrupt, {
|
|
416
|
+
onFailure: (error) => flatMap(orDie(encodeEffect(errorSchemaJson)(error)), fail4),
|
|
417
|
+
onSuccess: (value) => orDie(encodeEffect(successSchemaJson)(value))
|
|
418
|
+
})
|
|
419
|
+
};
|
|
420
|
+
execute = makeExecute(self);
|
|
421
|
+
return self;
|
|
422
|
+
};
|
|
423
|
+
var interruptRetryPolicy = /* @__PURE__ */ min([exponential(400, 1.5), spaced("10 seconds")]).pipe(/* @__PURE__ */ setInputType(), /* @__PURE__ */ while_((meta) => meta.attempt <= 10 && hasInterrupts(meta.input)));
|
|
424
|
+
var retryOnInterrupt = (name, policy = interruptRetryPolicy) => (effect) => flatMap(InstanceTag3, (instance) => effect.pipe(sandbox, retry({
|
|
425
|
+
schedule: policy,
|
|
426
|
+
while: () => !instance.suspended
|
|
427
|
+
}), catch_((cause) => hasInterrupts(cause) && !instance.suspended ? die3(`Activity "${name}" interrupted and retry attempts exhausted`) : failCause2(cause))));
|
|
428
|
+
var CurrentAttempt2 = /* @__PURE__ */ Reference("effect/workflow/Activity/CurrentAttempt", {
|
|
429
|
+
defaultValue: () => 1
|
|
430
|
+
});
|
|
431
|
+
var EngineTag3 = /* @__PURE__ */ Service2("effect/workflow/WorkflowEngine");
|
|
432
|
+
var InstanceTag3 = /* @__PURE__ */ Service2("effect/workflow/WorkflowEngine/WorkflowInstance");
|
|
433
|
+
var makeExecute = /* @__PURE__ */ fnUntraced(function* (activity) {
|
|
434
|
+
const engine = yield* EngineTag3;
|
|
435
|
+
const instance = yield* InstanceTag3;
|
|
436
|
+
const attempt = yield* CurrentAttempt2;
|
|
437
|
+
yield* annotateCurrentSpan({
|
|
438
|
+
executionId: instance.executionId
|
|
439
|
+
});
|
|
440
|
+
const result = yield* wrapActivityResult(engine.activityExecute(activity, attempt), (_) => _._tag === "Suspended");
|
|
441
|
+
if (result._tag === "Suspended") {
|
|
442
|
+
return yield* suspend2(instance);
|
|
443
|
+
}
|
|
444
|
+
return yield* result.exit;
|
|
445
|
+
}, (effect, activity) => withSpan(effect, activity.name, {
|
|
446
|
+
captureStackTrace: false
|
|
447
|
+
}));
|
|
448
|
+
// packages/sdk/src/loop/evidence.ts
|
|
449
|
+
var EvidenceCheck = Struct({
|
|
450
|
+
name: String2,
|
|
451
|
+
command: String2,
|
|
452
|
+
status: Literals(["passed", "failed"]),
|
|
453
|
+
preExisting: Boolean2,
|
|
454
|
+
durationMs: Finite,
|
|
455
|
+
evidenceId: String2
|
|
456
|
+
});
|
|
457
|
+
var VerifyResult = Struct({
|
|
458
|
+
revision: String2,
|
|
459
|
+
tree: String2,
|
|
460
|
+
passed: Boolean2,
|
|
461
|
+
checks: ArraySchema(EvidenceCheck)
|
|
462
|
+
});
|
|
463
|
+
var verdict = (reasons) => reasons.length === 0 ? { settled: true } : { settled: false, reasons };
|
|
464
|
+
var missing = (side) => `No verification evidence for the ${side}`;
|
|
465
|
+
var allPass = (side, result) => {
|
|
466
|
+
if (result === undefined)
|
|
467
|
+
return [missing(side)];
|
|
468
|
+
if (result.checks.length === 0)
|
|
469
|
+
return [`No approved verification ran on the ${side} tree ${result.tree}`];
|
|
470
|
+
return result.checks.filter((check) => check.status === "failed" && !check.preExisting).map((check) => `${check.name} fails on the ${side} tree ${result.tree}`);
|
|
471
|
+
};
|
|
472
|
+
var checkOn = (side, result, name) => {
|
|
473
|
+
if (result === undefined)
|
|
474
|
+
return { reason: missing(side) };
|
|
475
|
+
if (name === undefined)
|
|
476
|
+
return { reason: `No check was named for the ${side}` };
|
|
477
|
+
const found = result.checks.find((check) => check.name === name);
|
|
478
|
+
return found === undefined ? { reason: `No evidence for ${name} on the ${side} tree ${result.tree}` } : { found };
|
|
479
|
+
};
|
|
480
|
+
var passesOnHead = (head, name) => {
|
|
481
|
+
const { found, reason } = checkOn("head", head, name);
|
|
482
|
+
if (found === undefined)
|
|
483
|
+
return [reason];
|
|
484
|
+
return found.status === "passed" ? [] : [`${found.name} fails on the head tree ${head?.tree}`];
|
|
485
|
+
};
|
|
486
|
+
var bugReasons = (input) => {
|
|
487
|
+
const base = checkOn("base", input.base, input.reproducing);
|
|
488
|
+
const head = checkOn("head", input.head, input.reproducing);
|
|
489
|
+
return [
|
|
490
|
+
...base.found === undefined ? [base.reason] : base.found.status === "failed" ? [] : [`${base.found.name} does not fail on the base tree ${input.base?.tree}, so the bug is not reproduced`],
|
|
491
|
+
...head.found === undefined ? [head.reason] : head.found.status === "passed" ? [] : [`${head.found.name} fails on the head tree ${input.head?.tree}`]
|
|
492
|
+
];
|
|
493
|
+
};
|
|
494
|
+
var conclusionReasons = (conclusion) => {
|
|
495
|
+
if (conclusion === undefined || conclusion.text.trim() === "")
|
|
496
|
+
return ["No conclusion was given"];
|
|
497
|
+
return conclusion.sources.length === 0 ? ["The conclusion names no sources"] : [];
|
|
498
|
+
};
|
|
499
|
+
var scopeReasons = (scope) => {
|
|
500
|
+
if (scope === undefined)
|
|
501
|
+
return ["Review has not judged the scope"];
|
|
502
|
+
if (scope.met)
|
|
503
|
+
return [];
|
|
504
|
+
return scope.unmet.length === 0 ? ["Review found the scope unmet"] : scope.unmet.map((item) => `Review found the scope unmet: ${item}`);
|
|
505
|
+
};
|
|
506
|
+
var evidenceGate = (input) => {
|
|
507
|
+
switch (input.outcome) {
|
|
508
|
+
case "feature":
|
|
509
|
+
return verdict([...allPass("head", input.head), ...scopeReasons(input.review)]);
|
|
510
|
+
case "bug":
|
|
511
|
+
return verdict(bugReasons(input));
|
|
512
|
+
case "refactor":
|
|
513
|
+
return verdict([...allPass("base", input.base), ...allPass("head", input.head)]);
|
|
514
|
+
case "investigation":
|
|
515
|
+
return verdict(conclusionReasons(input.conclusion));
|
|
516
|
+
case "docs":
|
|
517
|
+
return verdict((input.documented ?? []).length === 0 ? ["No documented command was named"] : (input.documented ?? []).flatMap((name) => passesOnHead(input.head, name)));
|
|
518
|
+
case "migration":
|
|
519
|
+
return verdict(passesOnHead(input.head, input.rollback));
|
|
520
|
+
default:
|
|
521
|
+
return verdict(allPass("head", input.head));
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// packages/sdk/src/loop/steps.ts
|
|
526
|
+
class StepFailed extends TaggedError2()("StepFailed", {
|
|
527
|
+
step: String2,
|
|
528
|
+
reason: String2
|
|
529
|
+
}) {
|
|
530
|
+
get message() {
|
|
531
|
+
return `Step "${this.step}" failed: ${this.reason}`;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
class OutputInvalid extends TaggedError2()("OutputInvalid", {
|
|
536
|
+
step: String2,
|
|
537
|
+
message: String2
|
|
538
|
+
}) {
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
class QuestionRefused extends TaggedError2()("QuestionRefused", {
|
|
542
|
+
step: String2,
|
|
543
|
+
answer: String2,
|
|
544
|
+
options: ArraySchema(String2)
|
|
545
|
+
}) {
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
class WaitTimedOut extends TaggedError2()("WaitTimedOut", {
|
|
549
|
+
step: String2,
|
|
550
|
+
event: String2
|
|
551
|
+
}) {
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
class ChildFailed extends TaggedError2()("ChildFailed", {
|
|
555
|
+
step: String2,
|
|
556
|
+
loop: String2,
|
|
557
|
+
reason: String2
|
|
558
|
+
}) {
|
|
559
|
+
get message() {
|
|
560
|
+
return `Child Run of "${this.loop}" for Step "${this.step}" failed: ${this.reason}`;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
class CapabilityDenied extends TaggedError2()("CapabilityDenied", {
|
|
565
|
+
step: String2,
|
|
566
|
+
capability: Literals(LoopCapabilities),
|
|
567
|
+
secret: optionalKey(String2)
|
|
568
|
+
}) {
|
|
569
|
+
get message() {
|
|
570
|
+
return this.secret === undefined ? `Step "${this.step}" needs the "${this.capability}" capability, which this Run was not granted` : `Step "${this.step}" names the Secret "${this.secret}", which its Loop does not declare`;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
class DuplicateStep extends TaggedError2()("DuplicateStep", {
|
|
575
|
+
step: String2
|
|
576
|
+
}) {
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
class InputInvalid extends TaggedError2()("InputInvalid", {
|
|
580
|
+
loop: String2,
|
|
581
|
+
message: String2
|
|
582
|
+
}) {
|
|
583
|
+
}
|
|
584
|
+
var LoopEvent = Struct({ type: String2, payload: Record(String2, Json) });
|
|
585
|
+
|
|
586
|
+
class LoopRun extends Service2()("@kitman-sh/sdk/loop/LoopRun") {
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
class LoopHost extends Service2()("@kitman-sh/sdk/loop/LoopHost") {
|
|
590
|
+
}
|
|
591
|
+
var agentWorkDeferred = (step) => make2(`agent_work/${step}`, { success: Json, error: StepFailed });
|
|
592
|
+
var answerDeferred = (step) => make2(`ask/${step}`, { success: String2, error: StepFailed });
|
|
593
|
+
var childDeferred = (step) => make2(`call/${step}`, { success: Json, error: ChildFailed });
|
|
594
|
+
var eventDeferred = (step) => make2(`wait_for/${step}`, { success: LoopEvent, error: WaitTimedOut });
|
|
595
|
+
var verifyDeferred = (step) => make2(`verify/${step}`, { success: VerifyResult, error: StepFailed });
|
|
596
|
+
var recordStep = (name, kind, exit) => {
|
|
597
|
+
if (isSuccess2(exit))
|
|
598
|
+
return { name, kind, status: "succeeded", result: exit.value };
|
|
599
|
+
if (hasInterruptsOnly(exit.cause))
|
|
600
|
+
return;
|
|
601
|
+
return { name, kind, status: "failed", error: squash(exit.cause) };
|
|
602
|
+
};
|
|
603
|
+
var takeStep = (name, kind, capability, body) => gen(function* () {
|
|
604
|
+
const run = yield* LoopRun;
|
|
605
|
+
if (run.names.has(name))
|
|
606
|
+
return yield* new DuplicateStep({ step: name });
|
|
607
|
+
if (capability !== undefined && !run.granted.has(capability))
|
|
608
|
+
return yield* new CapabilityDenied({ step: name, capability });
|
|
609
|
+
run.names.add(name);
|
|
610
|
+
return yield* body.pipe(onExit((exit) => sync(() => {
|
|
611
|
+
const record = recordStep(name, kind, exit);
|
|
612
|
+
if (record !== undefined)
|
|
613
|
+
run.steps.push(record);
|
|
614
|
+
})));
|
|
615
|
+
});
|
|
616
|
+
var launch = (deferred, start) => make3({
|
|
617
|
+
name: deferred.name,
|
|
618
|
+
error: StepFailed,
|
|
619
|
+
execute: gen(function* () {
|
|
620
|
+
return yield* start(yield* LoopHost, yield* token(deferred));
|
|
621
|
+
})
|
|
622
|
+
});
|
|
623
|
+
var toJson = (step, schema, value) => encodeUnknownEffect(toCodecJson(schema))(value).pipe(flatMap(decodeUnknownEffect(Json)), mapError((error) => new StepFailed({ step, reason: error.message })));
|
|
624
|
+
var agentWork = (name, options) => takeStep(name, "agent_work", "agent_work", gen(function* () {
|
|
625
|
+
const run = yield* LoopRun;
|
|
626
|
+
const agent = run.agents[options.agent];
|
|
627
|
+
const undeclared = options.secrets?.find((secret) => !run.secrets.has(secret));
|
|
628
|
+
if (undeclared !== undefined)
|
|
629
|
+
return yield* new CapabilityDenied({ step: name, capability: "agent_work", secret: undeclared });
|
|
630
|
+
if (agent === undefined)
|
|
631
|
+
return yield* new StepFailed({ step: name, reason: `Agent role "${options.agent}" is not declared` });
|
|
632
|
+
const deferred = agentWorkDeferred(name);
|
|
633
|
+
const output = yield* jsonSchemaOf(run.loop, options.output).pipe(mapError((error) => new StepFailed({ step: name, reason: error.message })));
|
|
634
|
+
yield* launch(deferred, (host, token2) => host.startAgentWork({
|
|
635
|
+
step: name,
|
|
636
|
+
role: options.agent,
|
|
637
|
+
agent,
|
|
638
|
+
prompt: options.prompt,
|
|
639
|
+
output,
|
|
640
|
+
...options.secrets === undefined ? undefined : { secrets: options.secrets },
|
|
641
|
+
token: token2
|
|
642
|
+
}));
|
|
643
|
+
const submitted = yield* await_(deferred);
|
|
644
|
+
return yield* decodeEffect(toCodecJson(options.output))(submitted).pipe(mapError((error) => new OutputInvalid({ step: name, message: error.message })));
|
|
645
|
+
}));
|
|
646
|
+
var ask = (name, question) => takeStep(name, "ask", "ask", gen(function* () {
|
|
647
|
+
const deferred = answerDeferred(name);
|
|
648
|
+
const options = "options" in question ? question.options : undefined;
|
|
649
|
+
yield* launch(deferred, (host, token2) => host.putQuestion({
|
|
650
|
+
step: name,
|
|
651
|
+
prompt: question.prompt,
|
|
652
|
+
...options === undefined ? undefined : { options },
|
|
653
|
+
token: token2
|
|
654
|
+
}));
|
|
655
|
+
const answer = yield* await_(deferred);
|
|
656
|
+
if (options === undefined)
|
|
657
|
+
return answer;
|
|
658
|
+
const offered = options.find((option) => option === answer);
|
|
659
|
+
if (offered === undefined)
|
|
660
|
+
return yield* new QuestionRefused({ step: name, answer, options });
|
|
661
|
+
return offered;
|
|
662
|
+
}));
|
|
663
|
+
var call = (name, loop, input) => takeStep(name, "call", "call", gen(function* () {
|
|
664
|
+
const deferred = childDeferred(name);
|
|
665
|
+
const encoded = yield* toJson(name, loop.input, input);
|
|
666
|
+
yield* launch(deferred, (host, token2) => host.admitChild({ step: name, loop: loop.id, input: encoded, token: token2 }));
|
|
667
|
+
const result = yield* await_(deferred);
|
|
668
|
+
return yield* decodeEffect(toCodecJson(loop.output))(result).pipe(mapError((error) => new ChildFailed({ step: name, loop: loop.id, reason: error.message })));
|
|
669
|
+
}));
|
|
670
|
+
var waitFor = (name, wait) => takeStep(name, "wait_for", undefined, gen(function* () {
|
|
671
|
+
const deferred = eventDeferred(name);
|
|
672
|
+
const timeoutMillis = toMillis(fromInputUnsafe(wait.timeout));
|
|
673
|
+
yield* launch(deferred, (host, token2) => host.awaitEvent({
|
|
674
|
+
step: name,
|
|
675
|
+
event: wait.event,
|
|
676
|
+
...wait.filter === undefined ? undefined : { filter: wait.filter },
|
|
677
|
+
timeoutMillis,
|
|
678
|
+
token: token2
|
|
679
|
+
}));
|
|
680
|
+
return yield* await_(deferred);
|
|
681
|
+
}));
|
|
682
|
+
var verify = (name, request) => takeStep(name, "verify", "verify", gen(function* () {
|
|
683
|
+
const deferred = verifyDeferred(name);
|
|
684
|
+
yield* launch(deferred, (host, token2) => host.startVerification({
|
|
685
|
+
step: name,
|
|
686
|
+
...request.revision === undefined ? undefined : { revision: request.revision },
|
|
687
|
+
...request.checks === undefined ? undefined : { checks: request.checks },
|
|
688
|
+
token: token2
|
|
689
|
+
}));
|
|
690
|
+
return yield* await_(deferred);
|
|
691
|
+
}));
|
|
692
|
+
// packages/sdk/src/loop/plan.ts
|
|
693
|
+
var PlanTicket = Struct({
|
|
694
|
+
key: String2,
|
|
695
|
+
title: String2,
|
|
696
|
+
body: String2,
|
|
697
|
+
acceptanceCriteria: ArraySchema(String2),
|
|
698
|
+
repoBindingId: optional(String2),
|
|
699
|
+
blockedBy: ArraySchema(String2),
|
|
700
|
+
outcome: optional(LoopOutcome)
|
|
701
|
+
});
|
|
702
|
+
var cycleMessage = (keys) => `These tickets block each other in a cycle, so none can start: ${keys.join(", ")}`;
|
|
703
|
+
var ticketsProblem = (tickets) => {
|
|
704
|
+
const keys = new Set;
|
|
705
|
+
for (const ticket of tickets) {
|
|
706
|
+
if (keys.has(ticket.key))
|
|
707
|
+
return `Two tickets have the key "${ticket.key}"`;
|
|
708
|
+
keys.add(ticket.key);
|
|
709
|
+
}
|
|
710
|
+
for (const ticket of tickets)
|
|
711
|
+
for (const blocker of ticket.blockedBy)
|
|
712
|
+
if (!keys.has(blocker))
|
|
713
|
+
return `Ticket "${ticket.key}" is blocked by "${blocker}", which is not a ticket`;
|
|
714
|
+
const { blocked } = wavesOf(tickets);
|
|
715
|
+
return blocked.length === 0 ? undefined : cycleMessage(blocked);
|
|
716
|
+
};
|
|
717
|
+
var PlanTickets = ArraySchema(PlanTicket).check(makeFilter((tickets) => ticketsProblem(tickets) ?? true));
|
|
718
|
+
|
|
719
|
+
class BlockingCycle extends TaggedError2()("BlockingCycle", {
|
|
720
|
+
tickets: ArraySchema(String2)
|
|
721
|
+
}) {
|
|
722
|
+
get message() {
|
|
723
|
+
return cycleMessage(this.tickets);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
var byRepoBinding = (left, right) => (left.repoBindingId ?? "").localeCompare(right.repoBindingId ?? "");
|
|
727
|
+
function wavesOf(tickets) {
|
|
728
|
+
const placed = new Set;
|
|
729
|
+
const waves = [];
|
|
730
|
+
let left = tickets;
|
|
731
|
+
while (left.length > 0) {
|
|
732
|
+
const ready = left.filter((ticket) => ticket.blockedBy.every((blocker) => placed.has(blocker)));
|
|
733
|
+
if (ready.length === 0)
|
|
734
|
+
break;
|
|
735
|
+
for (const ticket of ready)
|
|
736
|
+
placed.add(ticket.key);
|
|
737
|
+
waves.push(ready.toSorted(byRepoBinding));
|
|
738
|
+
left = left.filter((ticket) => !placed.has(ticket.key));
|
|
739
|
+
}
|
|
740
|
+
return { waves, blocked: left.map((ticket) => ticket.key) };
|
|
741
|
+
}
|
|
742
|
+
var planWaves = (tickets) => suspend(() => {
|
|
743
|
+
const { waves, blocked } = wavesOf(tickets);
|
|
744
|
+
return blocked.length === 0 ? succeed5(waves) : fail4(new BlockingCycle({ tickets: blocked }));
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
// packages/sdk/src/loop/activities.ts
|
|
748
|
+
var ChangeRequestRequest = Struct({
|
|
749
|
+
title: String2,
|
|
750
|
+
body: String2,
|
|
751
|
+
integration: optional(String2)
|
|
752
|
+
});
|
|
753
|
+
var ChangeRequestResult = Struct({ id: String2, number: String2, url: String2 });
|
|
754
|
+
var WriteBackMilestones = ["started", "change_request_opened", "merged", "failed"];
|
|
755
|
+
var WriteBackRequest = Struct({
|
|
756
|
+
milestone: optional(Literals(WriteBackMilestones)),
|
|
757
|
+
changeRequestUrl: optional(String2)
|
|
758
|
+
});
|
|
759
|
+
var ArtifactRequest = Struct({
|
|
760
|
+
kind: String2,
|
|
761
|
+
title: String2,
|
|
762
|
+
text: String2,
|
|
763
|
+
data: optional(Json)
|
|
764
|
+
});
|
|
765
|
+
var ArtifactResult = Struct({ artifactId: String2 });
|
|
766
|
+
var NoteRequest = Struct({ text: String2, artifactId: optional(String2) });
|
|
767
|
+
var CreateTasksRequest = Struct({ tickets: ArraySchema(PlanTicket) });
|
|
768
|
+
var CreateTasksResult = Struct({
|
|
769
|
+
tasks: ArraySchema(Struct({ key: String2, taskId: String2 }))
|
|
770
|
+
});
|
|
771
|
+
var IntegrationBranchRequest = Struct({ repoBindingId: optional(String2) });
|
|
772
|
+
var IntegrationBranch = Struct({
|
|
773
|
+
repoBindingId: String2,
|
|
774
|
+
branch: String2,
|
|
775
|
+
revision: String2
|
|
776
|
+
});
|
|
777
|
+
var MergeChangeRequestRequest = Struct({ changeRequestId: String2 });
|
|
778
|
+
var MergeResult = Union([
|
|
779
|
+
Struct({ status: Literal("merged"), revision: String2 }),
|
|
780
|
+
Struct({ status: Literal("conflict") })
|
|
781
|
+
]);
|
|
782
|
+
var CommentRequest = Struct({ changeRequestId: String2, body: String2 });
|
|
783
|
+
var ReleaseRequest = Struct({
|
|
784
|
+
tag: String2,
|
|
785
|
+
revision: optional(String2),
|
|
786
|
+
title: String2,
|
|
787
|
+
notes: String2
|
|
788
|
+
});
|
|
789
|
+
var ReleaseResult = Struct({ tag: String2, revision: String2, url: String2 });
|
|
790
|
+
|
|
791
|
+
class ChangeRequestActivity extends Service2()("@kitman-sh/sdk/loop/ChangeRequestActivity") {
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
class WriteBackActivity extends Service2()("@kitman-sh/sdk/loop/WriteBackActivity") {
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
class ArtifactActivity extends Service2()("@kitman-sh/sdk/loop/ArtifactActivity") {
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
class NoteActivity extends Service2()("@kitman-sh/sdk/loop/NoteActivity") {
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
class CommentActivity extends Service2()("@kitman-sh/sdk/loop/CommentActivity") {
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
class CreateTasksActivity extends Service2()("@kitman-sh/sdk/loop/CreateTasksActivity") {
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
class IntegrationBranchActivity extends Service2()("@kitman-sh/sdk/loop/IntegrationBranchActivity") {
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
class MergeChangeRequestActivity extends Service2()("@kitman-sh/sdk/loop/MergeChangeRequestActivity") {
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
class ReleaseActivity extends Service2()("@kitman-sh/sdk/loop/ReleaseActivity") {
|
|
816
|
+
}
|
|
817
|
+
var hostActivity = (name, kind, capability, success, execute) => takeStep(name, kind, capability, make3({ name: `${kind}/${name}`, success, error: StepFailed, execute }));
|
|
818
|
+
var changeRequest = (name, request) => hostActivity(name, "change_request", "change_request", ChangeRequestResult, gen(function* () {
|
|
819
|
+
return yield* (yield* ChangeRequestActivity).run(request, name);
|
|
820
|
+
}));
|
|
821
|
+
var writeBack = (name, request) => hostActivity(name, "write_back", "write_back", Void, gen(function* () {
|
|
822
|
+
return yield* (yield* WriteBackActivity).run(request, name);
|
|
823
|
+
}));
|
|
824
|
+
var artifact = (name, request) => hostActivity(name, "artifact", undefined, ArtifactResult, gen(function* () {
|
|
825
|
+
return yield* (yield* ArtifactActivity).run(request, name);
|
|
826
|
+
}));
|
|
827
|
+
var note = (name, request) => hostActivity(name, "note", undefined, Void, gen(function* () {
|
|
828
|
+
return yield* (yield* NoteActivity).run(request, name);
|
|
829
|
+
}));
|
|
830
|
+
var comment = (name, request) => hostActivity(name, "comment", "post_comment", Void, gen(function* () {
|
|
831
|
+
return yield* (yield* CommentActivity).run(request, name);
|
|
832
|
+
}));
|
|
833
|
+
var createTasks = (name, request) => hostActivity(name, "create_tasks", "create_tasks", CreateTasksResult, gen(function* () {
|
|
834
|
+
return yield* (yield* CreateTasksActivity).run(request, name);
|
|
835
|
+
}));
|
|
836
|
+
var integrationBranch = (name, request) => hostActivity(name, "integration_branch", "merge_change_request", IntegrationBranch, gen(function* () {
|
|
837
|
+
return yield* (yield* IntegrationBranchActivity).run(request, name);
|
|
838
|
+
}));
|
|
839
|
+
var mergeChangeRequest = (name, request) => hostActivity(name, "merge_change_request", "merge_change_request", MergeResult, gen(function* () {
|
|
840
|
+
return yield* (yield* MergeChangeRequestActivity).run(request, name);
|
|
841
|
+
}));
|
|
842
|
+
var release2 = (name, request) => hostActivity(name, "release", "publish_release", ReleaseResult, gen(function* () {
|
|
843
|
+
return yield* (yield* ReleaseActivity).run(request, name);
|
|
844
|
+
}));
|
|
845
|
+
// packages/sdk/src/loop/test-loop.ts
|
|
846
|
+
var LoopJournal = Struct({
|
|
847
|
+
activities: Record(String2, Json),
|
|
848
|
+
deferreds: Record(String2, Json)
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
class ScriptedFailure extends TaggedClass("ScriptedFailure") {
|
|
852
|
+
}
|
|
853
|
+
// packages/sdk/src/loop/review.ts
|
|
854
|
+
var Severity = Literals(["blocker", "major", "minor"]);
|
|
855
|
+
var Finding = Struct({
|
|
856
|
+
severity: Severity,
|
|
857
|
+
file: String2,
|
|
858
|
+
line: Int,
|
|
859
|
+
detail: String2
|
|
860
|
+
});
|
|
861
|
+
var MergedFinding = Struct({
|
|
862
|
+
id: String2,
|
|
863
|
+
...Finding.fields,
|
|
864
|
+
seats: ArraySchema(String2)
|
|
865
|
+
});
|
|
866
|
+
var Rebuttal = Struct({ findingId: String2, reason: String2 });
|
|
867
|
+
var RebuttalVerdict = Struct({ findingId: String2, accepted: Boolean2 });
|
|
868
|
+
var ScopeJudgement = Struct({ met: Boolean2, unmet: ArraySchema(String2) });
|
|
869
|
+
var rank = { blocker: 0, major: 1, minor: 2 };
|
|
870
|
+
var isBlocking = (finding) => finding.severity !== "minor";
|
|
871
|
+
var mergeFindings = (bySeat) => {
|
|
872
|
+
const merged = new Map;
|
|
873
|
+
for (const [seat, findings] of Object.entries(bySeat))
|
|
874
|
+
for (const finding of findings) {
|
|
875
|
+
const id = `${finding.file}:${finding.line}`;
|
|
876
|
+
const known = merged.get(id);
|
|
877
|
+
const seats = [...new Set([...known?.seats ?? [], seat])];
|
|
878
|
+
const worst = known === undefined || rank[finding.severity] < rank[known.severity] ? finding : known;
|
|
879
|
+
merged.set(id, { id, severity: worst.severity, file: worst.file, line: worst.line, detail: worst.detail, seats });
|
|
880
|
+
}
|
|
881
|
+
return [...merged.values()].toSorted((left, right) => rank[left.severity] - rank[right.severity]);
|
|
882
|
+
};
|
|
883
|
+
var splitDisputed = (findings, rebuttals) => {
|
|
884
|
+
const disputed = [];
|
|
885
|
+
const undisputed = [];
|
|
886
|
+
for (const finding of findings) {
|
|
887
|
+
const rebuttal = rebuttals.find((entry) => entry.findingId === finding.id);
|
|
888
|
+
if (rebuttal === undefined)
|
|
889
|
+
undisputed.push(finding);
|
|
890
|
+
else
|
|
891
|
+
disputed.push({ finding, rebuttal });
|
|
892
|
+
}
|
|
893
|
+
return { disputed, undisputed };
|
|
894
|
+
};
|
|
895
|
+
var settleRound = (round) => {
|
|
896
|
+
const { disputed, undisputed } = splitDisputed(round.findings, round.rebuttals);
|
|
897
|
+
const accepted = (entry) => {
|
|
898
|
+
const verdicts = round.verdicts.filter((verdict) => verdict.findingId === entry.finding.id);
|
|
899
|
+
return verdicts.length > 0 && verdicts.every((verdict) => verdict.accepted);
|
|
900
|
+
};
|
|
901
|
+
return {
|
|
902
|
+
open: undisputed,
|
|
903
|
+
withdrawn: disputed.filter(accepted),
|
|
904
|
+
standing: disputed.filter((entry) => !accepted(entry))
|
|
905
|
+
};
|
|
906
|
+
};
|
|
907
|
+
var rallyStop = (input) => {
|
|
908
|
+
const open = input.settled.open.filter(isBlocking).map((finding) => finding.id);
|
|
909
|
+
const standing = input.settled.standing.flatMap((entry) => isBlocking(entry.finding) ? [entry.finding.id] : []);
|
|
910
|
+
const unsettled = [...open, ...standing];
|
|
911
|
+
const stop = (reason) => ({ stop: true, reason, unsettled });
|
|
912
|
+
if (unsettled.length === 0)
|
|
913
|
+
return stop("settled");
|
|
914
|
+
if (standing.length > 0)
|
|
915
|
+
return stop("dispute_stands");
|
|
916
|
+
if (input.previous !== undefined && sameIds(input.previous, unsettled))
|
|
917
|
+
return stop("findings_returned");
|
|
918
|
+
return input.round >= input.maxRounds ? stop("round_cap") : { stop: false };
|
|
919
|
+
};
|
|
920
|
+
var sameIds = (left, right) => left.length === right.length && left.every((id) => right.includes(id));
|
|
921
|
+
// packages/sdk/src/loop/check.ts
|
|
922
|
+
class CheckFailed extends TaggedError2()("CheckFailed", {
|
|
923
|
+
loop: String2,
|
|
924
|
+
check: String2,
|
|
925
|
+
reason: String2
|
|
926
|
+
}) {
|
|
927
|
+
get detail() {
|
|
928
|
+
return `Check "${this.check}": ${this.reason}`;
|
|
929
|
+
}
|
|
930
|
+
get message() {
|
|
931
|
+
return `Loop "${this.loop}": ${this.detail}`;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
class StepNamedTwice extends TaggedError2()("StepNamedTwice", {
|
|
936
|
+
loop: String2,
|
|
937
|
+
check: String2,
|
|
938
|
+
step: String2
|
|
939
|
+
}) {
|
|
940
|
+
get detail() {
|
|
941
|
+
return `Check "${this.check}": Step "${this.step}" is named twice`;
|
|
942
|
+
}
|
|
943
|
+
get message() {
|
|
944
|
+
return `Loop "${this.loop}": ${this.detail}`;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
class ReplayDiverged extends TaggedError2()("ReplayDiverged", {
|
|
949
|
+
loop: String2,
|
|
950
|
+
check: String2,
|
|
951
|
+
first: ArraySchema(String2),
|
|
952
|
+
replay: ArraySchema(String2),
|
|
953
|
+
rerun: ArraySchema(String2)
|
|
954
|
+
}) {
|
|
955
|
+
get detail() {
|
|
956
|
+
const steps = (names) => names.join(", ") || "no Steps";
|
|
957
|
+
return `Check "${this.check}": its replay from the journal diverged; it took ${steps(this.first)} and then ${steps(this.replay)}${this.rerun.length > 0 ? `, running ${this.rerun.join(", ")} again` : ""}. Keep effects and randomness inside Activities.`;
|
|
958
|
+
}
|
|
959
|
+
get message() {
|
|
960
|
+
return `Loop "${this.loop}": ${this.detail}`;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
var LoopCheckError = Union([CheckFailed, StepNamedTwice, ReplayDiverged]);
|
|
964
|
+
export { LoopOutcome, defineLoop, ManifestInvalid, make, Suspended, make2, await_, make3, evidenceGate, ChildFailed, agentWork, ask, call, waitFor, verify, PlanTickets, planWaves, ChangeRequestResult, CreateTasksResult, changeRequest, writeBack, artifact, note, comment, createTasks, integrationBranch, mergeChangeRequest, release2, Finding, MergedFinding, Rebuttal, RebuttalVerdict, ScopeJudgement, isBlocking, mergeFindings, settleRound, rallyStop, LoopCheckError };
|