@rk0429/agentic-relay 20.1.0 → 21.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/event-log-sink.d.ts +13 -9
- package/dist/application/event-log-sink.js +29 -22
- package/dist/application/event-log-sink.js.map +1 -1
- package/dist/application/housekeeping.js +8 -4
- package/dist/application/housekeeping.js.map +1 -1
- package/dist/application/projection-service.js +6 -3
- package/dist/application/projection-service.js.map +1 -1
- package/dist/application/routine-catalog-service.d.ts +36 -0
- package/dist/application/routine-catalog-service.js +90 -0
- package/dist/application/routine-catalog-service.js.map +1 -0
- package/dist/application/routine-daemon-service.d.ts +48 -0
- package/dist/application/routine-daemon-service.js +176 -0
- package/dist/application/routine-daemon-service.js.map +1 -0
- package/dist/application/routine-event-log-sink.d.ts +42 -0
- package/dist/application/routine-event-log-sink.js +82 -0
- package/dist/application/routine-event-log-sink.js.map +1 -0
- package/dist/application/routine-run-service.d.ts +56 -0
- package/dist/application/routine-run-service.js +370 -0
- package/dist/application/routine-run-service.js.map +1 -0
- package/dist/application/routine-scheduler.d.ts +34 -0
- package/dist/application/routine-scheduler.js +82 -0
- package/dist/application/routine-scheduler.js.map +1 -0
- package/dist/application/routine-status-query-service.d.ts +41 -0
- package/dist/application/routine-status-query-service.js +98 -0
- package/dist/application/routine-status-query-service.js.map +1 -0
- package/dist/application/spawn-agents-service.js +88 -37
- package/dist/application/spawn-agents-service.js.map +1 -1
- package/dist/application/workflow-execution-service.d.ts +5 -1
- package/dist/application/workflow-execution-service.js +82 -23
- package/dist/application/workflow-execution-service.js.map +1 -1
- package/dist/bin/relay.d.ts +58 -1
- package/dist/bin/relay.js +421 -50
- package/dist/bin/relay.js.map +1 -1
- package/dist/core/types.d.ts +8 -1
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -1
- package/dist/domain/loop-execution.d.ts +1 -1
- package/dist/domain/loop-execution.js +8 -4
- package/dist/domain/loop-execution.js.map +1 -1
- package/dist/domain/routine-definition.d.ts +18 -0
- package/dist/domain/routine-definition.js +19 -0
- package/dist/domain/routine-definition.js.map +1 -0
- package/dist/domain/routine-execution-state.d.ts +35 -0
- package/dist/domain/routine-execution-state.js +97 -0
- package/dist/domain/routine-execution-state.js.map +1 -0
- package/dist/domain/routine-firing.d.ts +23 -0
- package/dist/domain/routine-firing.js +47 -0
- package/dist/domain/routine-firing.js.map +1 -0
- package/dist/domain/routine-loader.d.ts +9 -0
- package/dist/domain/routine-loader.js +129 -0
- package/dist/domain/routine-loader.js.map +1 -0
- package/dist/domain/routine-name.d.ts +6 -0
- package/dist/domain/routine-name.js +31 -0
- package/dist/domain/routine-name.js.map +1 -0
- package/dist/domain/routine-schedule.d.ts +24 -0
- package/dist/domain/routine-schedule.js +126 -0
- package/dist/domain/routine-schedule.js.map +1 -0
- package/dist/domain/trigger-config.d.ts +25 -0
- package/dist/domain/trigger-config.js +86 -0
- package/dist/domain/trigger-config.js.map +1 -0
- package/dist/domain/workflow-loader.d.ts +2 -0
- package/dist/domain/workflow-loader.js +12 -2
- package/dist/domain/workflow-loader.js.map +1 -1
- package/dist/domain/workflow-schema.d.ts +20 -1
- package/dist/domain/workflow-schema.js +43 -7
- package/dist/domain/workflow-schema.js.map +1 -1
- package/dist/infrastructure/backends/cli-backend-executor.js +17 -0
- package/dist/infrastructure/backends/cli-backend-executor.js.map +1 -1
- package/dist/infrastructure/command-execution-gateway.d.ts +21 -0
- package/dist/infrastructure/command-execution-gateway.js +24 -0
- package/dist/infrastructure/command-execution-gateway.js.map +1 -0
- package/dist/infrastructure/diagnostics/codex-bootstrap.d.ts +3 -0
- package/dist/infrastructure/diagnostics/codex-bootstrap.js +35 -1
- package/dist/infrastructure/diagnostics/codex-bootstrap.js.map +1 -1
- package/dist/infrastructure/store/file-utils.d.ts +2 -0
- package/dist/infrastructure/store/file-utils.js +23 -0
- package/dist/infrastructure/store/file-utils.js.map +1 -0
- package/dist/infrastructure/store/relay-store.d.ts +1 -0
- package/dist/infrastructure/store/relay-store.js +6 -22
- package/dist/infrastructure/store/relay-store.js.map +1 -1
- package/dist/infrastructure/store/routine-execution-lease-repository.d.ts +31 -0
- package/dist/infrastructure/store/routine-execution-lease-repository.js +191 -0
- package/dist/infrastructure/store/routine-execution-lease-repository.js.map +1 -0
- package/dist/infrastructure/store/routine-runtime-projection-repository.d.ts +25 -0
- package/dist/infrastructure/store/routine-runtime-projection-repository.js +126 -0
- package/dist/infrastructure/store/routine-runtime-projection-repository.js.map +1 -0
- package/dist/infrastructure/store/routine-state-repository.d.ts +21 -0
- package/dist/infrastructure/store/routine-state-repository.js +139 -0
- package/dist/infrastructure/store/routine-state-repository.js.map +1 -0
- package/dist/interfaces/cli/loop-progress-renderer.js +3 -1
- package/dist/interfaces/cli/loop-progress-renderer.js.map +1 -1
- package/dist/interfaces/cli/relay-cli-args.d.ts +18 -2
- package/dist/interfaces/cli/relay-cli-args.js +171 -50
- package/dist/interfaces/cli/relay-cli-args.js.map +1 -1
- package/dist/interfaces/mcp/relay-mcp-server.js +2 -2
- package/dist/interfaces/mcp/relay-mcp-server.js.map +1 -1
- package/dist/interfaces/vscode/extension.js +3 -3
- package/dist/interfaces/vscode/extension.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { parseDocument, stringify } from "yaml";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { ValidationError } from "../core/errors.js";
|
|
5
|
+
import { RoutineDefinition } from "./routine-definition.js";
|
|
6
|
+
import { RoutineName } from "./routine-name.js";
|
|
7
|
+
import { loadWorkflow, } from "./workflow-loader.js";
|
|
8
|
+
import { CatchUpLimit, CronExpression, TriggerConfig, } from "./trigger-config.js";
|
|
9
|
+
const rawTriggerSchema = z.object({
|
|
10
|
+
schedule: z.string().trim().min(1),
|
|
11
|
+
missed_policy: z.enum(["catch_up", "skip"]).default("skip"),
|
|
12
|
+
catch_up_limit: z.number().int().min(1).default(1),
|
|
13
|
+
});
|
|
14
|
+
const routineYamlSchema = z.object({
|
|
15
|
+
name: z.string(),
|
|
16
|
+
description: z.string().trim().min(1).optional(),
|
|
17
|
+
trigger: rawTriggerSchema.optional(),
|
|
18
|
+
loop: z.unknown().optional(),
|
|
19
|
+
});
|
|
20
|
+
export async function loadRoutine(yamlPath, repo, vars = {}) {
|
|
21
|
+
const canonicalPath = resolve(yamlPath);
|
|
22
|
+
if (!(await repo.exists(canonicalPath))) {
|
|
23
|
+
throw new ValidationError(`Routine file does not exist: ${canonicalPath}`, {
|
|
24
|
+
recoveryHint: "Provide a valid routine YAML path.",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const source = await repo.read(canonicalPath);
|
|
28
|
+
const document = parseDocument(source);
|
|
29
|
+
if (document.errors.length > 0) {
|
|
30
|
+
throw new ValidationError(document.errors.map((error) => error.message).join("\n"), {
|
|
31
|
+
causeData: {
|
|
32
|
+
errors: document.errors.map((error) => error.message),
|
|
33
|
+
},
|
|
34
|
+
recoveryHint: "Fix the YAML syntax and try again.",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const rawValue = document.toJS();
|
|
38
|
+
const parsed = validateRoutineYaml(rawValue);
|
|
39
|
+
const routineName = validateRoutineName(parsed.name);
|
|
40
|
+
const trigger = parsed.trigger ? mapTriggerConfig(parsed.trigger) : undefined;
|
|
41
|
+
const hasExplicitLoop = isRecord(rawValue) && "loop" in rawValue;
|
|
42
|
+
const normalizedRoot = parsed.loop === undefined
|
|
43
|
+
? {
|
|
44
|
+
...(isRecord(rawValue) ? rawValue : {}),
|
|
45
|
+
loop: {
|
|
46
|
+
max_iterations: 1,
|
|
47
|
+
exit_conditions: [],
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
: rawValue;
|
|
51
|
+
const workflowRepo = parsed.loop === undefined
|
|
52
|
+
? createNormalizedRootRepo(canonicalPath, stringify(normalizedRoot), repo)
|
|
53
|
+
: repo;
|
|
54
|
+
const loaded = await loadWorkflow(canonicalPath, workflowRepo, undefined, vars);
|
|
55
|
+
return {
|
|
56
|
+
routineDefinition: new RoutineDefinition({
|
|
57
|
+
name: routineName,
|
|
58
|
+
description: parsed.description,
|
|
59
|
+
trigger,
|
|
60
|
+
workflow: loaded.workflow,
|
|
61
|
+
}),
|
|
62
|
+
capabilitySummary: loaded.capabilitySummary,
|
|
63
|
+
workflowLoadResult: loaded,
|
|
64
|
+
hasExplicitLoop,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function validateRoutineYaml(input) {
|
|
68
|
+
const result = routineYamlSchema.safeParse(input);
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
throw new ValidationError(result.error.issues
|
|
71
|
+
.map((issue) => `${formatIssuePath(issue.path)}: ${issue.message}`)
|
|
72
|
+
.join("\n"), {
|
|
73
|
+
causeData: {
|
|
74
|
+
issues: result.error.issues,
|
|
75
|
+
},
|
|
76
|
+
recoveryHint: "Fix the routine definition and try again.",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return result.data;
|
|
80
|
+
}
|
|
81
|
+
function validateRoutineName(value) {
|
|
82
|
+
try {
|
|
83
|
+
return new RoutineName(value);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error instanceof ValidationError) {
|
|
87
|
+
throw new ValidationError(`name: ${error.message}`, {
|
|
88
|
+
causeData: error.causeData,
|
|
89
|
+
recoveryHint: error.recoveryHint,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function mapTriggerConfig(raw) {
|
|
96
|
+
return new TriggerConfig({
|
|
97
|
+
schedule: new CronExpression(raw.schedule),
|
|
98
|
+
missedPolicy: raw.missed_policy,
|
|
99
|
+
catchUpLimit: new CatchUpLimit(raw.catch_up_limit),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function createNormalizedRootRepo(rootPath, normalizedRootSource, repo) {
|
|
103
|
+
return {
|
|
104
|
+
async read(filePath) {
|
|
105
|
+
return resolve(filePath) === rootPath
|
|
106
|
+
? normalizedRootSource
|
|
107
|
+
: repo.read(filePath);
|
|
108
|
+
},
|
|
109
|
+
async exists(filePath) {
|
|
110
|
+
return resolve(filePath) === rootPath ? true : repo.exists(filePath);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function formatIssuePath(path) {
|
|
115
|
+
if (path.length === 0) {
|
|
116
|
+
return "(root)";
|
|
117
|
+
}
|
|
118
|
+
return path.reduce((formatted, segment) => {
|
|
119
|
+
if (typeof segment === "number") {
|
|
120
|
+
return `${formatted}[${segment}]`;
|
|
121
|
+
}
|
|
122
|
+
const value = String(segment);
|
|
123
|
+
return formatted.length === 0 ? value : `${formatted}.${value}`;
|
|
124
|
+
}, "");
|
|
125
|
+
}
|
|
126
|
+
function isRecord(value) {
|
|
127
|
+
return typeof value === "object" && value !== null;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=routine-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routine-loader.js","sourceRoot":"","sources":["../../src/domain/routine-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ValidationError } from "../core/errors.js";
|
|
2
|
+
const ROUTINE_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;
|
|
3
|
+
const MAX_ROUTINE_NAME_LENGTH = 128;
|
|
4
|
+
export class RoutineName {
|
|
5
|
+
value;
|
|
6
|
+
constructor(value) {
|
|
7
|
+
if (typeof value !== "string") {
|
|
8
|
+
throw new ValidationError(`Invalid routine name: ${String(value)}`, {
|
|
9
|
+
recoveryHint: "Routine names must be strings matching [a-z0-9][a-z0-9_-]* and be at most 128 characters long.",
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
if (value.length === 0 || value.length > MAX_ROUTINE_NAME_LENGTH) {
|
|
13
|
+
throw new ValidationError(`Invalid routine name length: ${value.length}`, {
|
|
14
|
+
recoveryHint: "Routine names must be between 1 and 128 characters long.",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (!ROUTINE_NAME_PATTERN.test(value)) {
|
|
18
|
+
throw new ValidationError(`Invalid routine name: ${value}`, {
|
|
19
|
+
recoveryHint: "Routine names must match [a-z0-9][a-z0-9_-]* and contain only lowercase letters, digits, underscores, and hyphens.",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
this.value = value;
|
|
23
|
+
}
|
|
24
|
+
equals(other) {
|
|
25
|
+
return this.value === other.value;
|
|
26
|
+
}
|
|
27
|
+
toString() {
|
|
28
|
+
return this.value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=routine-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routine-name.js","sourceRoot":"","sources":["../../src/domain/routine-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AACrD,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC,MAAM,OAAO,WAAW;IACN,KAAK,CAAS;IAE9B,YAAmB,KAAa;QAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,eAAe,CAAC,yBAAyB,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE;gBAClE,YAAY,EACV,gGAAgG;aACnG,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;YACjE,MAAM,IAAI,eAAe,CAAC,gCAAgC,KAAK,CAAC,MAAM,EAAE,EAAE;gBACxE,YAAY,EACV,0DAA0D;aAC7D,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,eAAe,CAAC,yBAAyB,KAAK,EAAE,EAAE;gBAC1D,YAAY,EACV,oHAAoH;aACvH,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEM,MAAM,CAAC,KAAkB;QAC9B,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC;IACpC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type RoutineRunId, RoutineExecutionState } from "./routine-execution-state.js";
|
|
2
|
+
import { TriggerConfig } from "./trigger-config.js";
|
|
3
|
+
export interface MissedFireEvaluation {
|
|
4
|
+
firesToExecute: Date[];
|
|
5
|
+
skippedSchedules: Date[];
|
|
6
|
+
}
|
|
7
|
+
export declare class RoutineSchedule {
|
|
8
|
+
private readonly triggerConfigValue;
|
|
9
|
+
private executionStateValue;
|
|
10
|
+
private activeFiring;
|
|
11
|
+
constructor(triggerConfigValue: TriggerConfig | null, executionState?: RoutineExecutionState);
|
|
12
|
+
get triggerConfig(): TriggerConfig | null;
|
|
13
|
+
get executionState(): RoutineExecutionState;
|
|
14
|
+
evaluateMissedFires(now: Date): MissedFireEvaluation;
|
|
15
|
+
canFire(): boolean;
|
|
16
|
+
markFiring(runId: RoutineRunId, scheduledTime: Date, options?: {
|
|
17
|
+
isManual?: boolean;
|
|
18
|
+
}): void;
|
|
19
|
+
markCompleted(runId: RoutineRunId, completedAt?: Date): void;
|
|
20
|
+
markFailed(runId: RoutineRunId, failedAt?: Date): void;
|
|
21
|
+
markSkipped(scheduledTime: Date): void;
|
|
22
|
+
private requireActiveRun;
|
|
23
|
+
private advanceScheduleCursor;
|
|
24
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { ValidationError } from "../core/errors.js";
|
|
2
|
+
import { RoutineExecutionState, } from "./routine-execution-state.js";
|
|
3
|
+
export class RoutineSchedule {
|
|
4
|
+
triggerConfigValue;
|
|
5
|
+
executionStateValue;
|
|
6
|
+
activeFiring = null;
|
|
7
|
+
constructor(triggerConfigValue, executionState = RoutineExecutionState.create()) {
|
|
8
|
+
this.triggerConfigValue = triggerConfigValue;
|
|
9
|
+
this.executionStateValue = executionState;
|
|
10
|
+
}
|
|
11
|
+
get triggerConfig() {
|
|
12
|
+
return this.triggerConfigValue;
|
|
13
|
+
}
|
|
14
|
+
get executionState() {
|
|
15
|
+
return this.executionStateValue;
|
|
16
|
+
}
|
|
17
|
+
evaluateMissedFires(now) {
|
|
18
|
+
assertValidDate(now, "now");
|
|
19
|
+
if (this.triggerConfigValue === null) {
|
|
20
|
+
return emptyMissedFireEvaluation();
|
|
21
|
+
}
|
|
22
|
+
const missed = this.executionStateValue.lastScheduledAt === null
|
|
23
|
+
? resolveInitialMissedFire(this.triggerConfigValue, now)
|
|
24
|
+
: this.triggerConfigValue.schedule.allBetween(this.executionStateValue.lastScheduledAt, now);
|
|
25
|
+
if (missed.length === 0) {
|
|
26
|
+
return emptyMissedFireEvaluation();
|
|
27
|
+
}
|
|
28
|
+
if (this.triggerConfigValue.missedPolicy === "skip") {
|
|
29
|
+
return {
|
|
30
|
+
firesToExecute: [],
|
|
31
|
+
skippedSchedules: missed,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const catchUpLimit = this.triggerConfigValue.catchUpLimit;
|
|
35
|
+
if (!catchUpLimit.isEffective() || missed.length <= catchUpLimit.value) {
|
|
36
|
+
return {
|
|
37
|
+
firesToExecute: missed,
|
|
38
|
+
skippedSchedules: [],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
firesToExecute: missed.slice(-catchUpLimit.value),
|
|
43
|
+
skippedSchedules: missed.slice(0, -catchUpLimit.value),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
canFire() {
|
|
47
|
+
return this.activeFiring === null;
|
|
48
|
+
}
|
|
49
|
+
markFiring(runId, scheduledTime, options = {}) {
|
|
50
|
+
assertValidDate(scheduledTime, "scheduledTime");
|
|
51
|
+
if (!this.canFire()) {
|
|
52
|
+
throw new ValidationError("Routine is already executing.", {
|
|
53
|
+
recoveryHint: "Wait for the current run to finish before firing again.",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
this.activeFiring = {
|
|
57
|
+
runId,
|
|
58
|
+
scheduledTime: new Date(scheduledTime.getTime()),
|
|
59
|
+
isManual: options.isManual ?? false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
markCompleted(runId, completedAt = new Date()) {
|
|
63
|
+
assertValidDate(completedAt, "completedAt");
|
|
64
|
+
const firing = this.requireActiveRun(runId);
|
|
65
|
+
this.executionStateValue = this.executionStateValue.with({
|
|
66
|
+
lastExecutedAt: completedAt,
|
|
67
|
+
lastStatus: "completed",
|
|
68
|
+
...(firing.isManual ? {} : this.advanceScheduleCursor(firing.scheduledTime)),
|
|
69
|
+
});
|
|
70
|
+
this.activeFiring = null;
|
|
71
|
+
}
|
|
72
|
+
markFailed(runId, failedAt = new Date()) {
|
|
73
|
+
assertValidDate(failedAt, "failedAt");
|
|
74
|
+
const firing = this.requireActiveRun(runId);
|
|
75
|
+
this.executionStateValue = this.executionStateValue.with({
|
|
76
|
+
lastExecutedAt: failedAt,
|
|
77
|
+
lastStatus: "failed",
|
|
78
|
+
...(firing.isManual ? {} : this.advanceScheduleCursor(firing.scheduledTime)),
|
|
79
|
+
});
|
|
80
|
+
this.activeFiring = null;
|
|
81
|
+
}
|
|
82
|
+
markSkipped(scheduledTime) {
|
|
83
|
+
assertValidDate(scheduledTime, "scheduledTime");
|
|
84
|
+
this.executionStateValue = this.executionStateValue.with({
|
|
85
|
+
...this.advanceScheduleCursor(scheduledTime),
|
|
86
|
+
lastStatus: "skipped",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
requireActiveRun(runId) {
|
|
90
|
+
if (this.activeFiring === null) {
|
|
91
|
+
throw new ValidationError("Routine is not executing.", {
|
|
92
|
+
recoveryHint: "Call markFiring before completing or failing a run.",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (this.activeFiring.runId !== runId) {
|
|
96
|
+
throw new ValidationError("Routine run id does not match the active execution.", {
|
|
97
|
+
recoveryHint: "Pass the same runId returned by markFiring.",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return this.activeFiring;
|
|
101
|
+
}
|
|
102
|
+
advanceScheduleCursor(scheduledTime) {
|
|
103
|
+
return {
|
|
104
|
+
lastScheduledAt: new Date(scheduledTime.getTime()),
|
|
105
|
+
nextScheduledAt: this.triggerConfigValue?.schedule.nextAfter(scheduledTime) ?? null,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function emptyMissedFireEvaluation() {
|
|
110
|
+
return {
|
|
111
|
+
firesToExecute: [],
|
|
112
|
+
skippedSchedules: [],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function resolveInitialMissedFire(triggerConfig, now) {
|
|
116
|
+
const latest = triggerConfig.schedule.latestBefore(now);
|
|
117
|
+
return latest === null ? [] : [latest];
|
|
118
|
+
}
|
|
119
|
+
function assertValidDate(value, field) {
|
|
120
|
+
if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
|
|
121
|
+
throw new ValidationError(`Invalid ${field}: ${String(value)}`, {
|
|
122
|
+
recoveryHint: `${field} must be a valid Date.`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=routine-schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routine-schedule.js","sourceRoot":"","sources":["../../src/domain/routine-schedule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type MissedPolicy = "catch_up" | "skip";
|
|
2
|
+
export declare class CronExpression {
|
|
3
|
+
readonly value: string;
|
|
4
|
+
private readonly cron;
|
|
5
|
+
constructor(value: string);
|
|
6
|
+
nextAfter(from: Date): Date | null;
|
|
7
|
+
latestBefore(from: Date): Date | null;
|
|
8
|
+
allBetween(from: Date, to: Date): Date[];
|
|
9
|
+
toString(): string;
|
|
10
|
+
}
|
|
11
|
+
export declare class CatchUpLimit {
|
|
12
|
+
readonly value: number;
|
|
13
|
+
constructor(value: number);
|
|
14
|
+
isEffective(): boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare class TriggerConfig {
|
|
17
|
+
readonly schedule: CronExpression;
|
|
18
|
+
readonly missedPolicy: MissedPolicy;
|
|
19
|
+
readonly catchUpLimit: CatchUpLimit;
|
|
20
|
+
constructor(options: {
|
|
21
|
+
schedule: CronExpression;
|
|
22
|
+
missedPolicy: MissedPolicy;
|
|
23
|
+
catchUpLimit: CatchUpLimit;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Cron } from "croner";
|
|
2
|
+
import { ValidationError } from "../core/errors.js";
|
|
3
|
+
export class CronExpression {
|
|
4
|
+
value;
|
|
5
|
+
cron;
|
|
6
|
+
constructor(value) {
|
|
7
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
8
|
+
throw new ValidationError(`Invalid cron expression: ${String(value)}`, {
|
|
9
|
+
recoveryHint: "Cron expressions must be non-empty strings in standard 5-field format.",
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
this.cron = new Cron(value, {
|
|
14
|
+
paused: true,
|
|
15
|
+
mode: "5-part",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new ValidationError(`Invalid cron expression: ${value}`, {
|
|
20
|
+
causeData: error,
|
|
21
|
+
recoveryHint: "Use a valid 5-field cron expression such as '*/15 * * * *'.",
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
this.value = value;
|
|
25
|
+
}
|
|
26
|
+
nextAfter(from) {
|
|
27
|
+
assertValidDate(from, "from");
|
|
28
|
+
return this.cron.nextRun(from);
|
|
29
|
+
}
|
|
30
|
+
latestBefore(from) {
|
|
31
|
+
assertValidDate(from, "from");
|
|
32
|
+
return this.cron.previousRuns(1, from)[0] ?? null;
|
|
33
|
+
}
|
|
34
|
+
allBetween(from, to) {
|
|
35
|
+
assertValidDate(from, "from");
|
|
36
|
+
assertValidDate(to, "to");
|
|
37
|
+
if (to.getTime() <= from.getTime()) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const runs = [];
|
|
41
|
+
let cursor = from;
|
|
42
|
+
while (true) {
|
|
43
|
+
const next = this.cron.nextRun(cursor);
|
|
44
|
+
if (next === null || next.getTime() > to.getTime()) {
|
|
45
|
+
return runs;
|
|
46
|
+
}
|
|
47
|
+
runs.push(next);
|
|
48
|
+
cursor = next;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
toString() {
|
|
52
|
+
return this.value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export class CatchUpLimit {
|
|
56
|
+
value;
|
|
57
|
+
constructor(value) {
|
|
58
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
59
|
+
throw new ValidationError(`Invalid catch-up limit: ${value}`, {
|
|
60
|
+
recoveryHint: "catch_up_limit must be a positive integer.",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
this.value = value;
|
|
64
|
+
}
|
|
65
|
+
isEffective() {
|
|
66
|
+
return this.value > 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export class TriggerConfig {
|
|
70
|
+
schedule;
|
|
71
|
+
missedPolicy;
|
|
72
|
+
catchUpLimit;
|
|
73
|
+
constructor(options) {
|
|
74
|
+
this.schedule = options.schedule;
|
|
75
|
+
this.missedPolicy = options.missedPolicy;
|
|
76
|
+
this.catchUpLimit = options.catchUpLimit;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function assertValidDate(value, field) {
|
|
80
|
+
if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
|
|
81
|
+
throw new ValidationError(`Invalid ${field}: ${String(value)}`, {
|
|
82
|
+
recoveryHint: `${field} must be a valid Date.`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=trigger-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-config.js","sourceRoot":"","sources":["../../src/domain/trigger-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ export interface WorkflowCapabilitySummary {
|
|
|
11
11
|
export interface WorkflowLoadResult {
|
|
12
12
|
workflow: WorkflowDefinition;
|
|
13
13
|
capabilitySummary: WorkflowCapabilitySummary;
|
|
14
|
+
workflowPath: string;
|
|
15
|
+
workflowDigest: string;
|
|
14
16
|
}
|
|
15
17
|
export declare function loadWorkflow(rootPath: string, repo: WorkflowFileRepository, nestDepth?: NestDepth, vars?: Record<string, string>): Promise<WorkflowLoadResult>;
|
|
16
18
|
export declare function computeWorkflowDigest(yamlContent: string): string;
|
|
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
3
3
|
import { ValidationError } from "../core/errors.js";
|
|
4
4
|
import { NestDepth } from "./loop-execution.js";
|
|
5
|
-
import { interpolateWorkflowVars, isWorkflowStep, parseWorkflowYaml, } from "./workflow-schema.js";
|
|
5
|
+
import { isCommandStep, interpolateWorkflowVars, isWorkflowStep, parseWorkflowYaml, } from "./workflow-schema.js";
|
|
6
6
|
export async function loadWorkflow(rootPath, repo, nestDepth = new NestDepth(0), vars = {}) {
|
|
7
7
|
const canonicalRootPath = resolve(rootPath);
|
|
8
8
|
const context = {
|
|
@@ -22,12 +22,20 @@ export async function loadWorkflow(rootPath, repo, nestDepth = new NestDepth(0),
|
|
|
22
22
|
recoveryHint: "Fix the workflow definition and try again.",
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
+
const rootFrame = context.cache.get(canonicalRootPath);
|
|
26
|
+
if (!rootFrame) {
|
|
27
|
+
throw new ValidationError(`Workflow file does not exist: ${canonicalRootPath}`, {
|
|
28
|
+
recoveryHint: "Provide a valid workflow YAML path.",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
25
31
|
return {
|
|
26
32
|
workflow,
|
|
27
33
|
capabilitySummary: {
|
|
28
34
|
hasCommandRun: context.commandRunWorkflowPaths.size > 0,
|
|
29
35
|
commandRunWorkflowPaths: [...context.commandRunWorkflowPaths].sort(),
|
|
30
36
|
},
|
|
37
|
+
workflowPath: canonicalRootPath,
|
|
38
|
+
workflowDigest: rootFrame.digest,
|
|
31
39
|
};
|
|
32
40
|
}
|
|
33
41
|
export function computeWorkflowDigest(yamlContent) {
|
|
@@ -103,7 +111,9 @@ function validateWorkflowGraph(workflowPath, workflow, errors) {
|
|
|
103
111
|
}
|
|
104
112
|
}
|
|
105
113
|
function recordCapabilities(workflowPath, workflow, commandRunWorkflowPaths) {
|
|
106
|
-
|
|
114
|
+
const hasCommandRun = workflow.loop.exitConditions?.some((condition) => condition.type === "command") ||
|
|
115
|
+
workflow.steps.some((step) => isCommandStep(step));
|
|
116
|
+
if (hasCommandRun) {
|
|
107
117
|
commandRunWorkflowPaths.add(workflowPath);
|
|
108
118
|
}
|
|
109
119
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-loader.js","sourceRoot":"","sources":["../../src/domain/workflow-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,iBAAiB,GAElB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-loader.js","sourceRoot":"","sources":["../../src/domain/workflow-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,11 +39,23 @@ export interface WorkflowStepDefinition {
|
|
|
39
39
|
id: StepId;
|
|
40
40
|
prompt?: never;
|
|
41
41
|
workflow: string;
|
|
42
|
+
command?: never;
|
|
42
43
|
backend?: never;
|
|
43
44
|
role?: never;
|
|
44
45
|
session?: SessionConfig;
|
|
45
46
|
}
|
|
46
|
-
export
|
|
47
|
+
export interface CommandStepDefinition {
|
|
48
|
+
id: StepId;
|
|
49
|
+
prompt?: never;
|
|
50
|
+
workflow?: never;
|
|
51
|
+
command: {
|
|
52
|
+
run: string;
|
|
53
|
+
};
|
|
54
|
+
backend?: never;
|
|
55
|
+
role?: never;
|
|
56
|
+
session?: SessionConfig;
|
|
57
|
+
}
|
|
58
|
+
export type StepDefinition = PromptStepDefinition | WorkflowStepDefinition | CommandStepDefinition;
|
|
47
59
|
export interface WorkflowDefinition {
|
|
48
60
|
name: string;
|
|
49
61
|
description?: string;
|
|
@@ -111,6 +123,9 @@ export declare const workflowDefinitionSchema: z.ZodPipe<z.ZodObject<{
|
|
|
111
123
|
id: z.ZodString;
|
|
112
124
|
prompt: z.ZodOptional<z.ZodString>;
|
|
113
125
|
workflow: z.ZodOptional<z.ZodString>;
|
|
126
|
+
command: z.ZodOptional<z.ZodObject<{
|
|
127
|
+
run: z.ZodString;
|
|
128
|
+
}, z.core.$strip>>;
|
|
114
129
|
backend: z.ZodOptional<z.ZodEnum<{
|
|
115
130
|
claude: "claude";
|
|
116
131
|
codex: "codex";
|
|
@@ -144,6 +159,9 @@ export declare const workflowDefinitionSchema: z.ZodPipe<z.ZodObject<{
|
|
|
144
159
|
id: string;
|
|
145
160
|
prompt?: string | undefined;
|
|
146
161
|
workflow?: string | undefined;
|
|
162
|
+
command?: {
|
|
163
|
+
run: string;
|
|
164
|
+
} | undefined;
|
|
147
165
|
backend?: "claude" | "codex" | "gemini" | undefined;
|
|
148
166
|
role?: string | undefined;
|
|
149
167
|
session?: {
|
|
@@ -156,5 +174,6 @@ export declare const workflowDefinitionSchema: z.ZodPipe<z.ZodObject<{
|
|
|
156
174
|
export declare function parseWorkflowYaml(source: string): WorkflowDefinition;
|
|
157
175
|
export declare function validateWorkflowDefinition(input: unknown): WorkflowDefinition;
|
|
158
176
|
export declare function isWorkflowStep(step: StepDefinition): step is WorkflowStepDefinition;
|
|
177
|
+
export declare function isCommandStep(step: StepDefinition): step is CommandStepDefinition;
|
|
159
178
|
export declare function formatWorkflowSchemaIssues(error: z.ZodError): string;
|
|
160
179
|
export declare function interpolateWorkflowVars(workflow: WorkflowDefinition, cliVars: Record<string, string>): WorkflowDefinition;
|