@oisincoveney/pipeline 3.19.4 → 3.19.6
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/argo-submit.d.ts +2 -0
- package/dist/argo-submit.js +27 -16
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.js +2 -2
- package/dist/cli/format.js +1 -1
- package/dist/cli/program.d.ts +1 -1
- package/dist/cli/run-command.d.ts +1 -1
- package/dist/cli/run-resolver.d.ts +1 -1
- package/dist/cli/run-service.d.ts +1 -1
- package/dist/cli/submit-options.js +22 -5
- package/dist/commands/pipeline-command.js +1 -1
- package/dist/commands/ticket/shared.d.ts +1 -1
- package/dist/commands/ticket-command.d.ts +2 -1
- package/dist/config/schemas.d.ts +1 -1
- package/dist/context/repo-map.js +2 -2
- package/dist/credentials/broker.d.ts +1 -1
- package/dist/install-commands/opencode.js +1 -1
- package/dist/install-commands/planner.js +1 -1
- package/dist/install-hooks.js +1 -1
- package/dist/loop/argo-poll.js +2 -2
- package/dist/loop/loop-command.js +1 -1
- package/dist/loop/merge.js +1 -1
- package/dist/moka-global-config.d.ts +1 -0
- package/dist/moka-global-config.js +1 -0
- package/dist/moka-submit.d.ts +5 -0
- package/dist/moka-submit.js +1 -0
- package/dist/planning/generate.js +1 -1
- package/dist/remote/submit/argo-submission.d.ts +1 -0
- package/dist/remote/submit/argo-submission.js +1 -0
- package/dist/remote/submit/io.js +2 -2
- package/dist/run-control/contracts.d.ts +1 -1
- package/dist/run-control/contracts.js +1 -1
- package/dist/run-control/detach.js +1 -1
- package/dist/run-control/next-node.js +1 -1
- package/dist/run-control/postgres/postgres-run-control-store.js +4 -5
- package/dist/run-control/run-artifacts-command.js +1 -1
- package/dist/run-control/run-command-domain.js +2 -2
- package/dist/run-control/run-control-store.js +5 -1
- package/dist/run-control/runtime-reporter.js +1 -1
- package/dist/run-control/store-paths.js +1 -1
- package/dist/run-control/submit-result.js +1 -1
- package/dist/run-control/supervisor.js +2 -2
- package/dist/run-state/git-refs.js +1 -1
- package/dist/runner-command/run.js +1 -1
- package/dist/runtime/actor-ids.d.ts +1 -1
- package/dist/runtime/agent-node/index.js +2 -2
- package/dist/runtime/builtins/index.js +2 -2
- package/dist/runtime/changed-files/changed-files.js +1 -1
- package/dist/runtime/changed-files/index.js +2 -2
- package/dist/runtime/command-executor/index.js +2 -2
- package/dist/runtime/context/index.js +2 -2
- package/dist/runtime/contracts/index.d.ts +2 -1
- package/dist/runtime/drain-merge/index.js +2 -2
- package/dist/runtime/durable-store/acquisition.js +2 -1
- package/dist/runtime/durable-store/postgres/migrate-substrate.js +29 -0
- package/dist/runtime/durable-store/postgres/postgres-store.js +2 -4
- package/dist/runtime/events/events.js +2 -2
- package/dist/runtime/events/index.js +2 -2
- package/dist/runtime/gates/index.js +5 -5
- package/dist/runtime/gates/kinds/acceptance/acceptance.js +1 -1
- package/dist/runtime/hooks/command-hook.js +1 -1
- package/dist/runtime/hooks/index.js +2 -2
- package/dist/runtime/json-validation/index.js +2 -2
- package/dist/runtime/node-protocol/node-protocol.js +1 -1
- package/dist/runtime/node-state-store.js +1 -1
- package/dist/runtime/open-pull-request/index.js +2 -2
- package/dist/runtime/opencode-session-executor.js +1 -1
- package/dist/runtime/parallel-node/index.js +2 -2
- package/dist/runtime/retry.js +1 -1
- package/dist/runtime/scheduler.js +1 -1
- package/dist/runtime/services/backlog-service.d.ts +1 -1
- package/dist/runtime/services/backlog-service.js +1 -1
- package/dist/runtime/services/drain-merge-git-service.js +2 -2
- package/dist/runtime/services/kubernetes-argo-service.js +5 -1
- package/dist/runtime/services/run-journal-file-service.js +1 -1
- package/dist/tickets/backlog-task-store.js +1 -1
- package/dist/tickets/completion/complete-ticket.js +1 -1
- package/dist/tickets/ticket-graph.js +2 -2
- package/dist/tickets/ticket-plan.d.ts +1 -1
- package/docs/adr-two-stage-submit-scheduling.md +112 -0
- package/package.json +6 -1
package/dist/argo-submit.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ declare const submitRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
26
26
|
Never: "Never";
|
|
27
27
|
}>>;
|
|
28
28
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
29
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
29
30
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
30
31
|
mcpGatewayAuth: z.ZodOptional<z.ZodObject<{
|
|
31
32
|
secretKey: z.ZodDefault<z.ZodString>;
|
|
@@ -59,6 +60,7 @@ declare const submitDynamicRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
59
60
|
Never: "Never";
|
|
60
61
|
}>>;
|
|
61
62
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
63
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
62
64
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
63
65
|
mcpGatewayAuth: z.ZodOptional<z.ZodObject<{
|
|
64
66
|
secretKey: z.ZodDefault<z.ZodString>;
|
package/dist/argo-submit.js
CHANGED
|
@@ -43,6 +43,7 @@ const submitRunnerArgoWorkflowBaseOptionShape = {
|
|
|
43
43
|
"Never"
|
|
44
44
|
]).optional(),
|
|
45
45
|
imagePullSecretName: z.string().min(1).optional(),
|
|
46
|
+
kubeContext: z.string().min(1).optional(),
|
|
46
47
|
kubeconfigPath: z.string().min(1).optional(),
|
|
47
48
|
mcpGatewayAuth: mcpGatewayAuthOptionSchema.optional(),
|
|
48
49
|
name: z.string().min(1).optional(),
|
|
@@ -166,16 +167,16 @@ function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
|
|
|
166
167
|
namespace: options.namespace,
|
|
167
168
|
options
|
|
168
169
|
});
|
|
169
|
-
return
|
|
170
|
-
body: runnerArgoWorkflowManifestSchema.parse(workflow),
|
|
170
|
+
return yield* submitWorkflowManifest({
|
|
171
171
|
dependencies,
|
|
172
172
|
namespace: options.namespace,
|
|
173
|
-
options
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
options,
|
|
174
|
+
resultExtras: {
|
|
175
|
+
payloadConfigMapName,
|
|
176
|
+
scheduleConfigMapName: scheduleArtifactConfigMapName,
|
|
177
|
+
taskDescriptorConfigMapName
|
|
178
|
+
},
|
|
179
|
+
workflow
|
|
179
180
|
});
|
|
180
181
|
});
|
|
181
182
|
}
|
|
@@ -219,8 +220,7 @@ function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
|
|
|
219
220
|
workflowId: options.workflowId
|
|
220
221
|
});
|
|
221
222
|
return Effect.gen(function* () {
|
|
222
|
-
|
|
223
|
-
yield* service.createConfigMap({
|
|
223
|
+
yield* (yield* KubernetesArgoService).createConfigMap({
|
|
224
224
|
body: configMapSchema.parse({
|
|
225
225
|
apiVersion: "v1",
|
|
226
226
|
data: { "payload.json": payloadJson },
|
|
@@ -235,14 +235,25 @@ function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
|
|
|
235
235
|
namespace: options.namespace,
|
|
236
236
|
options
|
|
237
237
|
});
|
|
238
|
-
return
|
|
239
|
-
body: runnerArgoWorkflowManifestSchema.parse(workflow),
|
|
238
|
+
return yield* submitWorkflowManifest({
|
|
240
239
|
dependencies,
|
|
241
240
|
namespace: options.namespace,
|
|
242
|
-
options
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
241
|
+
options,
|
|
242
|
+
resultExtras: { payloadConfigMapName },
|
|
243
|
+
workflow
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function submitWorkflowManifest(input) {
|
|
248
|
+
return Effect.gen(function* () {
|
|
249
|
+
return workflowSubmitResult(yield* (yield* KubernetesArgoService).createWorkflow({
|
|
250
|
+
body: runnerArgoWorkflowManifestSchema.parse(input.workflow),
|
|
251
|
+
dependencies: input.dependencies,
|
|
252
|
+
namespace: input.namespace,
|
|
253
|
+
options: input.options
|
|
254
|
+
}), input.workflow, {
|
|
255
|
+
namespace: input.namespace,
|
|
256
|
+
...input.resultExtras
|
|
246
257
|
});
|
|
247
258
|
});
|
|
248
259
|
}
|
package/dist/cli/doctor.d.ts
CHANGED
package/dist/cli/doctor.js
CHANGED
|
@@ -9,8 +9,8 @@ import { execa } from "execa";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import matter from "gray-matter";
|
|
11
11
|
//#region src/cli/doctor.ts
|
|
12
|
-
const HEADLESS_AGENT_PERMISSION_VALUES = new Set(["ask"]);
|
|
13
|
-
const RUN_READINESS_CATEGORIES = new Set([
|
|
12
|
+
const HEADLESS_AGENT_PERMISSION_VALUES = /* @__PURE__ */ new Set(["ask"]);
|
|
13
|
+
const RUN_READINESS_CATEGORIES = /* @__PURE__ */ new Set([
|
|
14
14
|
"acceptance",
|
|
15
15
|
"green",
|
|
16
16
|
"intake",
|
package/dist/cli/format.js
CHANGED
|
@@ -137,4 +137,4 @@ function truncateMiddle(text, maxLength) {
|
|
|
137
137
|
return `${text.slice(0, keep)}\n... truncated ...\n${text.slice(-keep)}`;
|
|
138
138
|
}
|
|
139
139
|
//#endregion
|
|
140
|
-
export { createTerminalRuntimeReporter, formatDoctorResult, formatRuntimeFailure, formatRuntimeResult };
|
|
140
|
+
export { createTerminalRuntimeReporter, formatDoctorResult, formatRuntimeFailure, formatRuntimeProgressMessage, formatRuntimeResult };
|
package/dist/cli/program.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ interface CliProgramOptions {
|
|
|
11
11
|
declare function createCliProgram(options?: CliProgramOptions): Command;
|
|
12
12
|
declare function runCli(argv: string[]): Promise<void>;
|
|
13
13
|
//#endregion
|
|
14
|
-
export { createCliProgram, runCli };
|
|
14
|
+
export { CliProgramOptions, createCliProgram, runCli };
|
|
@@ -33,4 +33,4 @@ interface RunResolution {
|
|
|
33
33
|
target: MokaRunTarget;
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
|
-
export { RunResolution, RunResolverFlags };
|
|
36
|
+
export { LocalRuntimeExecution, MOKA_RUN_EFFORTS, MOKA_RUN_TARGETS, MokaRunEffort, MokaRunMode, MokaRunTarget, RemoteSubmitExecution, RunResolution, RunResolverFlags };
|
|
@@ -26,4 +26,4 @@ interface RunControlOptions {
|
|
|
26
26
|
declare function execute(description: string, options?: ExecuteOptions): Promise<void>;
|
|
27
27
|
declare function quick(description: string, options?: Omit<ExecuteOptions, "entrypoint">): Promise<void>;
|
|
28
28
|
//#endregion
|
|
29
|
-
export { execute, quick };
|
|
29
|
+
export { ExecuteOptions, RunControlOptions, RunStoreMode, execute, quick };
|
|
@@ -4,8 +4,16 @@ import { loadMokaGlobalConfig } from "../moka-global-config.js";
|
|
|
4
4
|
import { submitMoka } from "../moka-submit.js";
|
|
5
5
|
import { Option } from "commander";
|
|
6
6
|
//#region src/cli/submit-options.ts
|
|
7
|
+
function resolveOptionalSecretRef(flags, fromGlobalConfig) {
|
|
8
|
+
if (flags.skip) return;
|
|
9
|
+
if (flags.secretName) return {
|
|
10
|
+
secretName: flags.secretName,
|
|
11
|
+
...flags.secretKey ? { secretKey: flags.secretKey } : {}
|
|
12
|
+
};
|
|
13
|
+
return fromGlobalConfig;
|
|
14
|
+
}
|
|
7
15
|
function addMokaSubmitOptions(command) {
|
|
8
|
-
return addRunnerArgoOptions(command.option("--quick", "submit the compact graph").option("--command", "treat input after -- as explicit argv").option("--schedule <path>", "approved schedule YAML to submit").option("--event-url <url>", "runner event sink URL").option("--open-pr", "append an open-pull-request delivery node (preview-labelled PR)").option("--task <text>", "task description for command-mode metadata"), { kubeconfig: true });
|
|
16
|
+
return addRunnerArgoOptions(command.option("--quick", "submit the compact graph").option("--command", "treat input after -- as explicit argv").option("--schedule <path>", "approved schedule YAML to submit").option("--event-url <url>", "runner event sink URL").option("--open-pr", "append an open-pull-request delivery node (preview-labelled PR)").option("--task <text>", "task description for command-mode metadata").option("--db-auth-secret-name <name>", "override momokaya.submit.dbAuth secret name").option("--db-auth-secret-key <key>", "override momokaya.submit.dbAuth secret key").option("--skip-db-auth", "omit MOKA_DB_URL injection regardless of global config").option("--mcp-gateway-auth-secret-name <name>", "override momokaya.submit.mcpGatewayAuth secret name").option("--mcp-gateway-auth-secret-key <key>", "override momokaya.submit.mcpGatewayAuth secret key").option("--skip-mcp-gateway-auth", "omit PIPELINE_MCP_GATEWAY_AUTHORIZATION injection regardless of global config"), { kubeconfig: true });
|
|
9
17
|
}
|
|
10
18
|
function runMokaSubmitFromCli(input, flags) {
|
|
11
19
|
const cwd = process.env.PIPELINE_TARGET_PATH ?? process.cwd();
|
|
@@ -36,8 +44,16 @@ function mokaCommonSubmitOptions(input) {
|
|
|
36
44
|
return {
|
|
37
45
|
brokerAuth: resolveMokaBrokerAuth(input.globalConfig),
|
|
38
46
|
config: input.config,
|
|
39
|
-
dbAuth:
|
|
40
|
-
|
|
47
|
+
dbAuth: resolveOptionalSecretRef({
|
|
48
|
+
secretKey: input.flags.dbAuthSecretKey,
|
|
49
|
+
secretName: input.flags.dbAuthSecretName,
|
|
50
|
+
skip: input.flags.skipDbAuth
|
|
51
|
+
}, momokaya?.submit.dbAuth),
|
|
52
|
+
mcpGatewayAuth: resolveOptionalSecretRef({
|
|
53
|
+
secretKey: input.flags.mcpGatewayAuthSecretKey,
|
|
54
|
+
secretName: input.flags.mcpGatewayAuthSecretName,
|
|
55
|
+
skip: input.flags.skipMcpGatewayAuth
|
|
56
|
+
}, momokaya?.submit.mcpGatewayAuth),
|
|
41
57
|
delivery: { pullRequest: input.flags.openPr === true },
|
|
42
58
|
eventUrl: input.eventUrl,
|
|
43
59
|
eventAuthSecretKey: momokaya?.submit.eventAuthSecretKey,
|
|
@@ -48,6 +64,7 @@ function mokaCommonSubmitOptions(input) {
|
|
|
48
64
|
image: input.flags.image,
|
|
49
65
|
imagePullPolicy: parseImagePullPolicy(input.flags.imagePullPolicy),
|
|
50
66
|
imagePullSecretName: input.flags.imagePullSecret ?? momokaya?.submit.imagePullSecretName,
|
|
67
|
+
kubeContext: input.flags.kubeContext ?? momokaya?.kubernetes.context,
|
|
51
68
|
kubeconfigPath: input.flags.kubeconfig ?? momokaya?.kubernetes.kubeconfig,
|
|
52
69
|
name: input.flags.name,
|
|
53
70
|
namespace: input.flags.namespace ?? momokaya?.kubernetes.namespace,
|
|
@@ -83,7 +100,7 @@ function submitMokaGraphInput(input, flags, commonOptions) {
|
|
|
83
100
|
}
|
|
84
101
|
function addRunnerArgoOptions(command, options = {}) {
|
|
85
102
|
command.option("--name <name>", "Workflow metadata.name").option("--generate-name <prefix>", "Workflow metadata.generateName").option("--namespace <namespace>", "Workflow namespace");
|
|
86
|
-
if (options.kubeconfig) command.option("--kubeconfig <path>", "kubeconfig path");
|
|
103
|
+
if (options.kubeconfig) command.option("--kubeconfig <path>", "kubeconfig path").option("--kube-context <name>", "kubeconfig context to target");
|
|
87
104
|
return command.option("--service-account <name>", "Workflow service account").option("--image <image>", "runner image").addOption(new Option("--image-pull-policy <policy>", "runner image pull policy").choices([
|
|
88
105
|
"Always",
|
|
89
106
|
"IfNotPresent",
|
|
@@ -95,4 +112,4 @@ function parseImagePullPolicy(value) {
|
|
|
95
112
|
return "Always";
|
|
96
113
|
}
|
|
97
114
|
//#endregion
|
|
98
|
-
export { addMokaSubmitOptions, buildMokaSubmitInputFromCli, runMokaSubmitFromCli };
|
|
115
|
+
export { addMokaSubmitOptions, buildMokaSubmitInputFromCli, parseImagePullPolicy, runMokaSubmitFromCli };
|
package/dist/config/schemas.d.ts
CHANGED
|
@@ -583,4 +583,4 @@ interface PipelineConfigValidationOptions {
|
|
|
583
583
|
allowMissingLintFileReferences?: boolean;
|
|
584
584
|
}
|
|
585
585
|
//#endregion
|
|
586
|
-
export { GateKind, HookEvent, McpGatewayBackendLocality, McpGatewayWorkspacePathSource, PipelineConfig, PipelineConfigError, PipelineConfigErrorCode, PipelineConfigIssue, PipelineConfigParts, PipelineConfigValidationOptions, RunnerType, ScheduleBaseline, SchedulingRole, WorkflowNodeKind, workflowSchema };
|
|
586
|
+
export { GateKind, HookEvent, McpGatewayBackendLocality, McpGatewayWorkspacePathSource, PipelineConfig, PipelineConfigError, PipelineConfigErrorCode, PipelineConfigIssue, PipelineConfigParts, PipelineConfigValidationOptions, RunnerType, ScheduleBaseline, SchedulingRole, WorkflowNodeKind, configSchema, workflowSchema };
|
package/dist/context/repo-map.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Query } from "web-tree-sitter";
|
|
|
7
7
|
import Graph from "graphology";
|
|
8
8
|
import pagerank from "graphology-metrics/centrality/pagerank.js";
|
|
9
9
|
//#region src/context/repo-map.ts
|
|
10
|
-
const SOURCE_EXTENSIONS = new Set([
|
|
10
|
+
const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
11
11
|
".cjs",
|
|
12
12
|
".js",
|
|
13
13
|
".jsx",
|
|
@@ -15,7 +15,7 @@ const SOURCE_EXTENSIONS = new Set([
|
|
|
15
15
|
".ts",
|
|
16
16
|
".tsx"
|
|
17
17
|
]);
|
|
18
|
-
const SKIP_DIRS = new Set([
|
|
18
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
19
19
|
"node_modules",
|
|
20
20
|
".git",
|
|
21
21
|
"dist",
|
|
@@ -413,4 +413,4 @@ const opencodeAdapter = {
|
|
|
413
413
|
}
|
|
414
414
|
};
|
|
415
415
|
//#endregion
|
|
416
|
-
export { agentDispatchRoutes, entrypointDispatchBlock, grants, header, markdown, opencodeAdapter, projectAgentsMdDefinition, resolvedHostModel };
|
|
416
|
+
export { agentDispatchRoutes, entrypointDispatchBlock, grants, header, markdown, opencodeAdapter, projectAgentsMdDefinition, resolvedHostModel, shouldEmbedProjectGateway };
|
|
@@ -15,7 +15,7 @@ const ADAPTERS = {
|
|
|
15
15
|
opencode: opencodeAdapter,
|
|
16
16
|
"claude-code": claudeCodeAdapter
|
|
17
17
|
};
|
|
18
|
-
const GLOBAL_EXCLUDED_PATHS = new Set(["AGENTS.md"]);
|
|
18
|
+
const GLOBAL_EXCLUDED_PATHS = /* @__PURE__ */ new Set(["AGENTS.md"]);
|
|
19
19
|
const GENERATED_CONTENT_MARKERS = [
|
|
20
20
|
GENERATED_MARKER,
|
|
21
21
|
GENERATED_TS_MARKER,
|
package/dist/install-hooks.js
CHANGED
|
@@ -20,7 +20,7 @@ const HOST_TARGET_ROOT = {
|
|
|
20
20
|
codex: ".codex",
|
|
21
21
|
opencode: ".opencode"
|
|
22
22
|
};
|
|
23
|
-
const NON_HOOK_OWNED_TARGETS = new Set([".opencode/opencode.json"]);
|
|
23
|
+
const NON_HOOK_OWNED_TARGETS = /* @__PURE__ */ new Set([".opencode/opencode.json"]);
|
|
24
24
|
function hashContent(content) {
|
|
25
25
|
return createHash("sha256").update(content).digest("hex");
|
|
26
26
|
}
|
package/dist/loop/argo-poll.js
CHANGED
|
@@ -2,12 +2,12 @@ import { isRecord } from "../safe-json.js";
|
|
|
2
2
|
import { Duration, Effect } from "effect";
|
|
3
3
|
import { CustomObjectsApi, KubeConfig } from "@kubernetes/client-node";
|
|
4
4
|
//#region src/loop/argo-poll.ts
|
|
5
|
-
const TERMINAL_PHASES = new Set([
|
|
5
|
+
const TERMINAL_PHASES = /* @__PURE__ */ new Set([
|
|
6
6
|
"Succeeded",
|
|
7
7
|
"Failed",
|
|
8
8
|
"Error"
|
|
9
9
|
]);
|
|
10
|
-
const KNOWN_RUNNING_PHASES = new Set([
|
|
10
|
+
const KNOWN_RUNNING_PHASES = /* @__PURE__ */ new Set([
|
|
11
11
|
"Running",
|
|
12
12
|
"Pending",
|
|
13
13
|
""
|
package/dist/loop/merge.js
CHANGED
|
@@ -29,6 +29,7 @@ const mokaSubmitGlobalConfigSchema = z.object({
|
|
|
29
29
|
serviceAccountName: z.string().min(1)
|
|
30
30
|
}).strict();
|
|
31
31
|
const mokaKubernetesGlobalConfigSchema = z.object({
|
|
32
|
+
context: z.string().min(1).optional(),
|
|
32
33
|
kubeconfig: z.string().min(1).optional(),
|
|
33
34
|
namespace: z.string().min(1)
|
|
34
35
|
}).strict();
|
package/dist/moka-submit.d.ts
CHANGED
|
@@ -197,6 +197,7 @@ declare const mokaSubmitBaseOptionsSchema: z.ZodObject<{
|
|
|
197
197
|
Never: "Never";
|
|
198
198
|
}>>;
|
|
199
199
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
200
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
200
201
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
201
202
|
name: z.ZodOptional<z.ZodString>;
|
|
202
203
|
namespace: z.ZodOptional<z.ZodString>;
|
|
@@ -310,6 +311,7 @@ declare const mokaGraphSubmitOptionsSchema: z.ZodObject<{
|
|
|
310
311
|
Never: "Never";
|
|
311
312
|
}>>;
|
|
312
313
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
314
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
313
315
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
314
316
|
name: z.ZodOptional<z.ZodString>;
|
|
315
317
|
namespace: z.ZodOptional<z.ZodString>;
|
|
@@ -440,6 +442,7 @@ declare const mokaCommandSubmitOptionsSchema: z.ZodObject<{
|
|
|
440
442
|
Never: "Never";
|
|
441
443
|
}>>;
|
|
442
444
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
445
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
443
446
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
444
447
|
name: z.ZodOptional<z.ZodString>;
|
|
445
448
|
namespace: z.ZodOptional<z.ZodString>;
|
|
@@ -565,6 +568,7 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
565
568
|
Never: "Never";
|
|
566
569
|
}>>;
|
|
567
570
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
571
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
568
572
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
569
573
|
name: z.ZodOptional<z.ZodString>;
|
|
570
574
|
namespace: z.ZodOptional<z.ZodString>;
|
|
@@ -694,6 +698,7 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
694
698
|
Never: "Never";
|
|
695
699
|
}>>;
|
|
696
700
|
imagePullSecretName: z.ZodOptional<z.ZodString>;
|
|
701
|
+
kubeContext: z.ZodOptional<z.ZodString>;
|
|
697
702
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
698
703
|
name: z.ZodOptional<z.ZodString>;
|
|
699
704
|
namespace: z.ZodOptional<z.ZodString>;
|
package/dist/moka-submit.js
CHANGED
|
@@ -66,6 +66,7 @@ const mokaSubmitBaseOptionsSchema = z.object({
|
|
|
66
66
|
image: z.string().min(1).optional(),
|
|
67
67
|
imagePullPolicy: imagePullPolicySchema,
|
|
68
68
|
imagePullSecretName: z.string().min(1).optional(),
|
|
69
|
+
kubeContext: z.string().min(1).optional(),
|
|
69
70
|
kubeconfigPath: z.string().min(1).optional(),
|
|
70
71
|
name: z.string().min(1).optional(),
|
|
71
72
|
namespace: z.string().min(1).optional(),
|
|
@@ -41,7 +41,7 @@ const SCHEDULE_BUILTINS = [
|
|
|
41
41
|
"test",
|
|
42
42
|
"typecheck"
|
|
43
43
|
];
|
|
44
|
-
const PARALLEL_MERGE_BUILTINS = new Set(["drain-merge"]);
|
|
44
|
+
const PARALLEL_MERGE_BUILTINS = /* @__PURE__ */ new Set(["drain-merge"]);
|
|
45
45
|
const scheduleArtifactSchema = z.object({
|
|
46
46
|
generated_at: z.string().datetime(),
|
|
47
47
|
kind: z.literal(SCHEDULE_KIND),
|
|
@@ -50,6 +50,7 @@ function workflowSubmitOptions(options) {
|
|
|
50
50
|
image: options.image,
|
|
51
51
|
imagePullPolicy: options.imagePullPolicy,
|
|
52
52
|
imagePullSecretName: options.imagePullSecretName,
|
|
53
|
+
kubeContext: options.kubeContext,
|
|
53
54
|
kubeconfigPath: options.kubeconfigPath,
|
|
54
55
|
name: options.name,
|
|
55
56
|
namespace: requireSubmitOption(options.namespace, "namespace"),
|
package/dist/remote/submit/io.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { normalizeRunnerRepositoryForSubmit } from "../../git-remote-url.js";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
-
import { simpleGit } from "simple-git";
|
|
3
|
+
import { simpleGit as simpleGit$1 } from "simple-git";
|
|
4
4
|
import parseGitUrl from "git-url-parse";
|
|
5
5
|
//#region src/remote/submit/io.ts
|
|
6
6
|
function readScheduleFile(dependencies, path) {
|
|
@@ -47,7 +47,7 @@ function runContext(options, git, runId) {
|
|
|
47
47
|
}
|
|
48
48
|
async function resolveGit(worktreePath, dependencies) {
|
|
49
49
|
if (dependencies.resolveGitContext) return dependencies.resolveGitContext(worktreePath);
|
|
50
|
-
const git = simpleGit({ baseDir: worktreePath });
|
|
50
|
+
const git = simpleGit$1({ baseDir: worktreePath });
|
|
51
51
|
const [branchResult, sha, remoteConfig] = await Promise.all([
|
|
52
52
|
git.branch(),
|
|
53
53
|
git.revparse(["HEAD"]),
|
|
@@ -103,4 +103,4 @@ type RunEffort = z.infer<typeof runEffortSchema>;
|
|
|
103
103
|
type RunMode = z.infer<typeof runModeSchema>;
|
|
104
104
|
type MokaRunManifest = z.infer<typeof mokaRunManifestSchema>;
|
|
105
105
|
//#endregion
|
|
106
|
-
export { MokaRunManifest, RunEffort, RunMode, RunTarget };
|
|
106
|
+
export { MokaRunManifest, RunEffort, RunMode, RunTarget, mokaRunManifestSchema, runEffortSchema, runModeSchema, runTargetSchema };
|
|
@@ -127,4 +127,4 @@ function parseMokaRunManifest(input) {
|
|
|
127
127
|
return mokaRunManifestSchema.parse(input);
|
|
128
128
|
}
|
|
129
129
|
//#endregion
|
|
130
|
-
export { DEFAULT_RUN_CONTROL_HEARTBEAT_INTERVAL_MS, DEFAULT_RUN_CONTROL_NODE_STALE_AFTER_MS, DEFAULT_RUN_CONTROL_STALE_DETECTION, mokaNodeStatusSchema, mokaRunStatusSchema, parseMokaNodeStatus, parseMokaRunController, parseMokaRunEvent, parseMokaRunManifest, parseMokaRunStatus, parseRunControlStaleDetection, parseRunEffort, parseRunMode, parseRunTarget };
|
|
130
|
+
export { DEFAULT_RUN_CONTROL_HEARTBEAT_INTERVAL_MS, DEFAULT_RUN_CONTROL_NODE_STALE_AFTER_MS, DEFAULT_RUN_CONTROL_STALE_DETECTION, MOKA_NODE_STATUSES, MOKA_RUN_STATUSES, RUN_EFFORTS, RUN_MODES, RUN_TARGETS, mokaNodeStatusEventSchema, mokaNodeStatusSchema, mokaRunControlEventSchema, mokaRunControllerSchema, mokaRunEventSchema, mokaRunHeartbeatEventSchema, mokaRunManifestSchema, mokaRunStatusEventSchema, mokaRunStatusSchema, parseMokaNodeStatus, parseMokaRunController, parseMokaRunEvent, parseMokaRunManifest, parseMokaRunStatus, parseRunControlStaleDetection, parseRunEffort, parseRunMode, parseRunTarget, runControlStaleDetectionSchema, runEffortSchema, runModeSchema, runTargetSchema };
|
|
@@ -115,4 +115,4 @@ function printNextNodeEnvelopeScoped(runId) {
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
//#endregion
|
|
118
|
-
export { readPersistedScheduleEffect, readyNodeIdsFromRunStore, registerNextNodeSubcommand };
|
|
118
|
+
export { buildNextNodeEnvelope, buildNextNodeEnvelopeFromRunStore, readPersistedScheduleEffect, readyNodeIdsFromRunStore, registerNextNodeSubcommand };
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
import "../../runtime/durable-store/postgres/migrate-substrate.js";
|
|
1
2
|
import { DEFAULT_RUN_CONTROL_STALE_DETECTION, parseMokaNodeStatus, parseMokaRunController, parseMokaRunEvent, parseMokaRunManifest, parseMokaRunStatus, parseRunControlStaleDetection, parseRunEffort, parseRunMode, parseRunTarget } from "../contracts.js";
|
|
2
3
|
import { publishScheduleManifest } from "../store-manifest.js";
|
|
3
4
|
import { runControlEvent, runControlNodeArtifact, runControlNodeSession, runControlRun } from "./schema.js";
|
|
4
5
|
import { Effect } from "effect";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { asc, eq, inArray } from "drizzle-orm";
|
|
7
6
|
import { drizzle } from "drizzle-orm/postgres-js";
|
|
8
|
-
import "drizzle-orm/postgres-js/migrator";
|
|
9
7
|
import postgres from "postgres";
|
|
10
|
-
|
|
8
|
+
import { asc, eq, inArray } from "drizzle-orm";
|
|
9
|
+
//#region src/run-control/postgres/postgres-run-control-store.ts
|
|
11
10
|
function openClient(dbUrl) {
|
|
12
11
|
return postgres(dbUrl, { max: 1 });
|
|
13
12
|
}
|
|
@@ -39,7 +38,7 @@ function createRun(db, input) {
|
|
|
39
38
|
manifest,
|
|
40
39
|
runId: manifest.runId
|
|
41
40
|
}).onConflictDoNothing());
|
|
42
|
-
const existing = yield*
|
|
41
|
+
const existing = yield* loadBaseManifest(db, manifest.runId);
|
|
43
42
|
if (existing === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error(`Run ${manifest.runId} not found after createRun upsert.`));
|
|
44
43
|
return existing;
|
|
45
44
|
});
|
|
@@ -14,7 +14,7 @@ const WATCH_INTERVAL_MS = 1e3;
|
|
|
14
14
|
const SENSITIVE_BASENAME_PARTS = ["prompt", "session"];
|
|
15
15
|
const SENSITIVE_BASENAME_PREFIXES = ["body."];
|
|
16
16
|
const SENSITIVE_PATH_PARTS = ["session-body", "session_body"];
|
|
17
|
-
const SENSITIVE_BASENAMES = new Set(["body"]);
|
|
17
|
+
const SENSITIVE_BASENAMES = /* @__PURE__ */ new Set(["body"]);
|
|
18
18
|
function printLogsEffect(input) {
|
|
19
19
|
return Effect.gen(function* () {
|
|
20
20
|
const run = yield* requireRunEffect(input.store, input.runId);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { parseLogicalSegment } from "./logical-segment.js";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
//#region src/run-control/run-command-domain.ts
|
|
4
|
-
const ACTIVE_RUN_STATUSES = new Set([
|
|
4
|
+
const ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([
|
|
5
5
|
"queued",
|
|
6
6
|
"starting",
|
|
7
7
|
"running",
|
|
8
8
|
"stalled"
|
|
9
9
|
]);
|
|
10
|
-
const ACTIVE_NODE_STATUSES = new Set([
|
|
10
|
+
const ACTIVE_NODE_STATUSES = /* @__PURE__ */ new Set([
|
|
11
11
|
"queued",
|
|
12
12
|
"starting",
|
|
13
13
|
"running",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { loadMokaDbUrl, requireMokaDbUrl } from "../moka-global-config.js";
|
|
2
|
+
import { migratePostgresSubstrate } from "../runtime/durable-store/postgres/migrate-substrate.js";
|
|
2
3
|
import { postgresRunControlStore } from "./postgres/postgres-run-control-store.js";
|
|
3
4
|
import "./store-paths.js";
|
|
4
5
|
import "./store.js";
|
|
@@ -19,7 +20,10 @@ import { Effect } from "effect";
|
|
|
19
20
|
* filesystem store holds no resources, so it is returned directly.
|
|
20
21
|
*/
|
|
21
22
|
function resolveRunControlStore(dbUrl, _workspaceRoot) {
|
|
22
|
-
return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.
|
|
23
|
+
return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.tryPromise({
|
|
24
|
+
catch: (error) => error,
|
|
25
|
+
try: () => migratePostgresSubstrate(requiredDbUrl)
|
|
26
|
+
}).pipe(Effect.flatMap(() => Effect.acquireRelease(Effect.sync(() => postgresRunControlStore(requiredDbUrl)), (store) => Effect.promise(() => store.close()))))));
|
|
23
27
|
}
|
|
24
28
|
/**
|
|
25
29
|
* PIPE-91.14: the single store-lifecycle wrapper shared by every run-control
|
|
@@ -3,7 +3,7 @@ import { createSerializedWriteQueue } from "../serialized-write-queue.js";
|
|
|
3
3
|
import { createRunStoreRuntimeReporter } from "./runtime-reporter.js";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/run-control/supervisor.ts
|
|
6
|
-
const RUNNING_NODE_EVENT_TYPES = new Set([
|
|
6
|
+
const RUNNING_NODE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
7
7
|
"agent.start",
|
|
8
8
|
"artifact.check.start",
|
|
9
9
|
"gate.start",
|
|
@@ -193,4 +193,4 @@ function shouldMarkNodeRunning(event) {
|
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
//#endregion
|
|
196
|
-
export { createRunControlSupervisor };
|
|
196
|
+
export { createRunControlSupervisor, createRunControlSupervisorEffect };
|
|
@@ -347,4 +347,4 @@ function shellQuote(value) {
|
|
|
347
347
|
return `'${value.replaceAll("'", `'\\''`)}'`;
|
|
348
348
|
}
|
|
349
349
|
//#endregion
|
|
350
|
-
export { commitAndPushNodeRef, mergeDependencyRefs, prepareRunnerGitWorkspace, promoteFinalRef, runAuthenticatedGit };
|
|
350
|
+
export { commitAndPushNodeRef, mergeDependencyRefs, prepareRunnerGitWorkspace, promoteFinalRef, runAuthenticatedGit, runnerCommitMessage };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./agent-node.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { executeAgentNode } from "./agent-node.js";
|
|
2
|
+
export { executeAgentNode };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./builtins.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { executeBuiltin } from "./builtins.js";
|
|
2
|
+
export { executeBuiltin };
|
|
@@ -35,7 +35,7 @@ function pathFromPorcelainEntry(entry) {
|
|
|
35
35
|
return path ? [path] : [];
|
|
36
36
|
}
|
|
37
37
|
function diffChangedFiles(before, after, worktreePath) {
|
|
38
|
-
const files = [
|
|
38
|
+
const files = [.../* @__PURE__ */ new Set([...before.files, ...after.files])].filter((file) => !before.files.has(file) || before.fingerprints.get(file) !== (after.fingerprints.get(file) ?? fileFingerprint(worktreePath, file)));
|
|
39
39
|
return {
|
|
40
40
|
files: new Set(files),
|
|
41
41
|
fingerprints: new Map(files.map((file) => [file, after.fingerprints.get(file) ?? fileFingerprint(worktreePath, file)]))
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./changed-files.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { diffChangedFiles, snapshotChangedFiles } from "./changed-files.js";
|
|
2
|
+
export { diffChangedFiles, snapshotChangedFiles };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./command-executor.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { executeCommand } from "./command-executor.js";
|
|
2
|
+
export { executeCommand };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./context.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { createRuntimeContext, generateRuntimeRunId, resolveWorkflowSelection } from "./context.js";
|
|
2
|
+
export { createRuntimeContext, generateRuntimeRunId, resolveWorkflowSelection };
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import { AcceptanceCriterion, HookRuntimePolicy, NodeExecutionState, NodeStatus, PipelineRuntimeEvent, PipelineRuntimeObservabilityLevel, PipelineRuntimeOptions, PipelineRuntimeResult, PipelineTaskContext, RuntimeFailure, RuntimeGateResult, RuntimeNodeResult, RuntimeStructuredOutput, UnmetCriterion } from "./contracts.js";
|
|
1
|
+
import { AcceptanceCriterion, HookRuntimePolicy, NodeExecutionState, NodeStatus, PipelineRuntimeEvent, PipelineRuntimeObservabilityLevel, PipelineRuntimeOptions, PipelineRuntimeResult, PipelineTaskContext, RuntimeFailure, RuntimeGateResult, RuntimeNodeResult, RuntimeStructuredOutput, UnmetCriterion } from "./contracts.js";
|
|
2
|
+
export { AcceptanceCriterion, HookRuntimePolicy, NodeExecutionState, NodeStatus, PipelineRuntimeEvent, PipelineRuntimeObservabilityLevel, PipelineRuntimeOptions, PipelineRuntimeResult, PipelineTaskContext, RuntimeFailure, RuntimeGateResult, RuntimeNodeResult, RuntimeStructuredOutput, UnmetCriterion };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./drain-merge.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { executeDrainMergeBuiltin } from "./drain-merge.js";
|
|
2
|
+
export { executeDrainMergeBuiltin };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { requireMokaDbUrl } from "../../moka-global-config.js";
|
|
2
|
+
import { migratePostgresSubstrate } from "./postgres/migrate-substrate.js";
|
|
2
3
|
import { postgresDurableRunStore } from "./postgres/postgres-store.js";
|
|
3
4
|
import { Effect } from "effect";
|
|
4
5
|
//#region src/runtime/durable-store/acquisition.ts
|
|
5
6
|
function resolveDurableStore(dbUrl, runId) {
|
|
6
|
-
return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.acquireRelease(Effect.tryPromise(() => postgresDurableRunStore(requiredDbUrl, runId)), (store) => Effect.promise(() => store.close()))));
|
|
7
|
+
return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.tryPromise(() => migratePostgresSubstrate(requiredDbUrl)).pipe(Effect.flatMap(() => Effect.acquireRelease(Effect.tryPromise(() => postgresDurableRunStore(requiredDbUrl, runId)), (store) => Effect.promise(() => store.close()))))));
|
|
7
8
|
}
|
|
8
9
|
//#endregion
|
|
9
10
|
export { resolveDurableStore };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { drizzle } from "drizzle-orm/postgres-js";
|
|
3
|
+
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
|
4
|
+
import postgres from "postgres";
|
|
5
|
+
//#region src/runtime/durable-store/postgres/migrate-substrate.ts
|
|
6
|
+
const migrationsFolder = fileURLToPath(new URL("./migrations", import.meta.url));
|
|
7
|
+
const MIGRATION_LOCK_KEY = 8942017;
|
|
8
|
+
/**
|
|
9
|
+
* Apply the Drizzle migrations shared by the run-control and durable stores to
|
|
10
|
+
* `dbUrl`. Idempotent (Drizzle tracks applied migrations in
|
|
11
|
+
* `__drizzle_migrations` by content hash) and safe under concurrent callers
|
|
12
|
+
* (Postgres advisory lock serializes them). Opens and closes its own
|
|
13
|
+
* single-connection client.
|
|
14
|
+
*/
|
|
15
|
+
async function migratePostgresSubstrate(dbUrl) {
|
|
16
|
+
const client = postgres(dbUrl, { max: 1 });
|
|
17
|
+
try {
|
|
18
|
+
await client`select pg_advisory_lock(${MIGRATION_LOCK_KEY}::bigint)`;
|
|
19
|
+
try {
|
|
20
|
+
await migrate(drizzle(client), { migrationsFolder });
|
|
21
|
+
} finally {
|
|
22
|
+
await client`select pg_advisory_unlock(${MIGRATION_LOCK_KEY}::bigint)`;
|
|
23
|
+
}
|
|
24
|
+
} finally {
|
|
25
|
+
await client.end();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { migratePostgresSubstrate };
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
+
import "./migrate-substrate.js";
|
|
1
2
|
import { createSerializedWriteQueue } from "../../../serialized-write-queue.js";
|
|
2
3
|
import { buildRunJournal } from "../../run-journal.js";
|
|
3
4
|
import { durableNodeRecord, durableRun } from "./schema.js";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { eq } from "drizzle-orm";
|
|
6
5
|
import { drizzle } from "drizzle-orm/postgres-js";
|
|
7
|
-
import "drizzle-orm/postgres-js/migrator";
|
|
8
6
|
import postgres from "postgres";
|
|
7
|
+
import { eq } from "drizzle-orm";
|
|
9
8
|
import pino from "pino";
|
|
10
9
|
//#region src/runtime/durable-store/postgres/postgres-store.ts
|
|
11
10
|
const logger = pino({ name: "postgres-durable-store" });
|
|
12
|
-
fileURLToPath(new URL("./migrations", import.meta.url));
|
|
13
11
|
function openClient(dbUrl) {
|
|
14
12
|
return postgres(dbUrl, { max: 1 });
|
|
15
13
|
}
|
|
@@ -3,7 +3,7 @@ import { runtimeActorId } from "../actor-ids.js";
|
|
|
3
3
|
import { parseRuntimeOutput, validateJsonSchemaSource } from "../json-validation/json-validation.js";
|
|
4
4
|
import "../json-validation/index.js";
|
|
5
5
|
//#region src/runtime/events/events.ts
|
|
6
|
-
const warningRuntimeObservabilityTypes = new Set([
|
|
6
|
+
const warningRuntimeObservabilityTypes = /* @__PURE__ */ new Set([
|
|
7
7
|
"runtime.gate.cancelled",
|
|
8
8
|
"runtime.gate.failed",
|
|
9
9
|
"runtime.hook.failed",
|
|
@@ -15,7 +15,7 @@ const primaryRuntimeObservabilityPrefixes = [
|
|
|
15
15
|
"runtime.hook.",
|
|
16
16
|
"runtime.state."
|
|
17
17
|
];
|
|
18
|
-
const structuredOutputFormats = new Set([
|
|
18
|
+
const structuredOutputFormats = /* @__PURE__ */ new Set([
|
|
19
19
|
"json",
|
|
20
20
|
"json_schema",
|
|
21
21
|
"jsonl"
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./events.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { childReporter, createPublicRuntimeObservabilityEmitter, emit, emitAgentFinish, emitAgentStart, emitGateFinish, emitGateStart, emitNodeFinish, emitNodeOutputRecorded, emitNodeStart, emitWorkflowFinish, emitWorkflowPlanned, emitWorkflowStarted, runtimeNodeActorDescriptor, runtimeSystemId } from "./events.js";
|
|
2
|
+
export { childReporter, createPublicRuntimeObservabilityEmitter, emit, emitAgentFinish, emitAgentStart, emitGateFinish, emitGateStart, emitNodeFinish, emitNodeOutputRecorded, emitNodeStart, emitWorkflowFinish, emitWorkflowPlanned, emitWorkflowStarted, runtimeNodeActorDescriptor, runtimeSystemId };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./contract.js";
|
|
2
|
-
import "./gates.js";
|
|
3
|
-
import "./registry.js";
|
|
4
|
-
import "./orchestrator.js";
|
|
5
|
-
export {};
|
|
1
|
+
import { forKind } from "./contract.js";
|
|
2
|
+
import { parseGateJson } from "./gates.js";
|
|
3
|
+
import { evaluateGate, gateRegistry } from "./registry.js";
|
|
4
|
+
import { evaluateNodeGates } from "./orchestrator.js";
|
|
5
|
+
export { evaluateGate, evaluateNodeGates, forKind, gateRegistry, parseGateJson };
|
|
@@ -106,4 +106,4 @@ function hasNonEmptyEvidence(value) {
|
|
|
106
106
|
return Array.isArray(value) && value.filter((item) => typeof item === "string" && item.trim()).length > 0;
|
|
107
107
|
}
|
|
108
108
|
//#endregion
|
|
109
|
-
export { evaluateAcceptanceGate };
|
|
109
|
+
export { acceptanceUnmetCriteria, evaluateAcceptanceGate };
|
|
@@ -20,7 +20,7 @@ function hookEnv(hook, context) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
function commandHookEnvEntries(hook, context) {
|
|
23
|
-
return [
|
|
23
|
+
return [.../* @__PURE__ */ new Set([...context.hookPolicy.envPassthrough, ...hook.env?.passthrough ?? []])].flatMap(commandHookEnvEntry);
|
|
24
24
|
}
|
|
25
25
|
function commandHookEnvEntry(name) {
|
|
26
26
|
const value = process.env[name];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./hooks.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { dispatchHooks } from "./hooks.js";
|
|
2
|
+
export { dispatchHooks };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./json-validation.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { normalizeJsonSource, parseJsonObject, parseRuntimeOutput, readJsonSchemaSource, readOptionalFile, validateJsonSchemaSource } from "./json-validation.js";
|
|
2
|
+
export { normalizeJsonSource, parseJsonObject, parseRuntimeOutput, readJsonSchemaSource, readOptionalFile, validateJsonSchemaSource };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./open-pull-request.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { executeOpenPullRequestBuiltin, openPullRequestProgram } from "./open-pull-request.js";
|
|
2
|
+
export { executeOpenPullRequestBuiltin, openPullRequestProgram };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./parallel-node.js";
|
|
2
|
-
export {};
|
|
1
|
+
import { executeParallelNode } from "./parallel-node.js";
|
|
2
|
+
export { executeParallelNode };
|
package/dist/runtime/retry.js
CHANGED
|
@@ -132,7 +132,7 @@ function computeReadyNodeIds(input) {
|
|
|
132
132
|
const completedIds = new Set((input.completed ?? []).map((r) => r.nodeId));
|
|
133
133
|
const runningIds = new Set(input.running ?? []);
|
|
134
134
|
const blockedIds = new Set(input.blocked ?? []);
|
|
135
|
-
const settled = new Set([...completedIds, ...runningIds]);
|
|
135
|
+
const settled = /* @__PURE__ */ new Set([...completedIds, ...runningIds]);
|
|
136
136
|
return orderedNodes(input.nodes).filter((node) => !(settled.has(node.id) || blockedIds.has(node.id))).filter((node) => node.needs.every((needId) => {
|
|
137
137
|
const result = (input.completed ?? []).find((r) => r.nodeId === needId);
|
|
138
138
|
if (result === void 0) return false;
|
|
@@ -21,4 +21,4 @@ const BacklogServiceLive = Layer.succeed(BacklogService, { run: (args, cwd) => E
|
|
|
21
21
|
try: () => execa("backlog", [...args], { cwd })
|
|
22
22
|
}).pipe(Effect.map((result) => result.stdout)) });
|
|
23
23
|
//#endregion
|
|
24
|
-
export { BacklogService, BacklogServiceLive };
|
|
24
|
+
export { BacklogCommandError, BacklogService, BacklogServiceLive };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from "effect";
|
|
2
|
-
import simpleGit
|
|
2
|
+
import simpleGit from "simple-git";
|
|
3
3
|
//#region src/runtime/services/drain-merge-git-service.ts
|
|
4
4
|
var DrainMergeGitService = class extends Context.Service()("DrainMergeGitService") {};
|
|
5
5
|
const DrainMergeGitServiceLive = Layer.succeed(DrainMergeGitService, { create: (baseDir) => Effect.sync(() => {
|
|
6
|
-
const git = simpleGit
|
|
6
|
+
const git = simpleGit({ baseDir });
|
|
7
7
|
return { raw: (args) => Effect.tryPromise(() => git.raw(args)) };
|
|
8
8
|
}) });
|
|
9
9
|
//#endregion
|
|
@@ -62,6 +62,10 @@ function resolveKubeConfig(options, dependencies) {
|
|
|
62
62
|
const kubeConfig = new KubeConfig();
|
|
63
63
|
if (options.kubeconfigPath) kubeConfig.loadFromFile(options.kubeconfigPath);
|
|
64
64
|
else kubeConfig.loadFromDefault();
|
|
65
|
+
if (options.kubeContext) {
|
|
66
|
+
if (!kubeConfig.getContextObject(options.kubeContext)) throw new Error(`Kube context '${options.kubeContext}' was not found in the resolved kubeconfig`);
|
|
67
|
+
kubeConfig.setCurrentContext(options.kubeContext);
|
|
68
|
+
}
|
|
65
69
|
return kubeConfig;
|
|
66
70
|
}
|
|
67
71
|
function apiClients(options, dependencies) {
|
|
@@ -96,4 +100,4 @@ function kubectlErrorStdout(error) {
|
|
|
96
100
|
return (error.stdout || "").trim();
|
|
97
101
|
}
|
|
98
102
|
//#endregion
|
|
99
|
-
export { KubernetesArgoService, KubernetesArgoServiceLive };
|
|
103
|
+
export { KubernetesArgoService, KubernetesArgoServiceLive, resolveKubeConfig };
|
|
@@ -93,4 +93,4 @@ function errorMessage(error) {
|
|
|
93
93
|
return error instanceof Error ? error.message : String(error);
|
|
94
94
|
}
|
|
95
95
|
//#endregion
|
|
96
|
-
export { backlogTicketCompletionStoreEffect, completeTicket, conservativeLayerAJudge };
|
|
96
|
+
export { TicketCompletionError, backlogTicketCompletionStoreEffect, completeTicket, conservativeLayerAJudge };
|
|
@@ -21,7 +21,7 @@ function sequenceTicketBatchesEffect(graph, ticketIds = dependencyGraphNodeIds(g
|
|
|
21
21
|
function scopedTicketIds(graph, rootId) {
|
|
22
22
|
if (!rootId) return dependencyGraphNodeIds(graph.dependencyGraph).sort(compareTaskIds);
|
|
23
23
|
if (!dependencyGraphHasNode(graph.dependencyGraph, rootId)) return [];
|
|
24
|
-
const ids = new Set([rootId]);
|
|
24
|
+
const ids = /* @__PURE__ */ new Set([rootId]);
|
|
25
25
|
const visit = (id) => {
|
|
26
26
|
for (const child of graph.childrenByParentId.get(id) ?? []) {
|
|
27
27
|
ids.add(child.id);
|
|
@@ -71,4 +71,4 @@ function compareTasks(a, b) {
|
|
|
71
71
|
return compareBacklogTasks(a, b);
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
|
-
export { buildTicketGraphEffect, compareTaskIds, predecessorIds, scopedTicketIds, sequenceTicketBatchesEffect };
|
|
74
|
+
export { TicketGraphError, buildTicketGraphEffect, compareTaskIds, predecessorIds, scopedTicketIds, sequenceTicketBatchesEffect };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# ADR: Two-Stage `moka submit` — Schedule-Then-Dispatch
|
|
2
|
+
|
|
3
|
+
Status: Accepted
|
|
4
|
+
|
|
5
|
+
Date: 2026-07-01
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
`moka submit` is one flow with two stages, not two separate commands and not two
|
|
10
|
+
separate code paths:
|
|
11
|
+
|
|
12
|
+
1. **Schedule** — research, planning, and graph generation, producing a
|
|
13
|
+
`ScheduleArtifact` and persisting it to the durable Postgres run-control
|
|
14
|
+
store before any Argo Workflow exists.
|
|
15
|
+
2. **Dispatch** — compile the persisted (or explicitly supplied) schedule into
|
|
16
|
+
an Argo Workflow manifest and submit it, targeting whatever Kubernetes
|
|
17
|
+
cluster/context the operator configured.
|
|
18
|
+
|
|
19
|
+
Both stages run inside the single call chain:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
moka submit [args]
|
|
23
|
+
-> registerSubmitCommand() src/cli/program.ts:71
|
|
24
|
+
-> runMokaSubmitFromCli() src/cli/submit-options.ts:55
|
|
25
|
+
-> submitMoka() src/moka-submit.ts:238
|
|
26
|
+
-> submitParsedMoka() src/remote/submit/service.ts:47
|
|
27
|
+
- compileMokaSubmitPlan() src/remote/submit/compilation.ts:32
|
|
28
|
+
- upsertRunRecord() [Schedule -> DB]
|
|
29
|
+
- submitCompiledMokaWorkflow() src/remote/submit/argo-submission.ts:46 [Dispatch]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
There is exactly one WorkflowSpec builder chain (`buildRunnerArgoWorkflowManifest`
|
|
33
|
+
/ `buildDynamicRunnerArgoWorkflowManifest` in `src/argo-workflow.ts`) and exactly
|
|
34
|
+
one Kubernetes/Argo client (`KubernetesArgoService` in
|
|
35
|
+
`src/runtime/services/kubernetes-argo-service.ts`). Static and dynamic
|
|
36
|
+
scheduling are a discriminated union (`dynamicScheduling: boolean` on
|
|
37
|
+
`CompiledMokaSubmitPlan`), not parallel implementations.
|
|
38
|
+
|
|
39
|
+
## Stage 1 — Schedule (research -> planning -> graph, persisted)
|
|
40
|
+
|
|
41
|
+
When no `scheduleYaml`/`schedulePath` is supplied at submit time
|
|
42
|
+
(`dynamicScheduling: true`), the schedule is produced inside the runner pod by
|
|
43
|
+
three sequential phases, run via `moka runner-pre-schedule --phase <phase>`
|
|
44
|
+
(`src/runner-command/pre-schedule.ts`):
|
|
45
|
+
|
|
46
|
+
1. `pre-research` — produces research context (findings, risks, target).
|
|
47
|
+
2. `pre-planning` — consumes research, produces a `TicketPlan` (tickets +
|
|
48
|
+
dependencies), via `ticketPlanPlanningContext()`
|
|
49
|
+
(`src/planning/generate.ts:343`).
|
|
50
|
+
3. `generate-schedule` — calls the configured planner profile to produce the
|
|
51
|
+
final `ScheduleArtifact`. If the planner fails or emits an invalid
|
|
52
|
+
artifact, `ticketPlanScheduleArtifact()` (`src/planning/generate.ts:497`)
|
|
53
|
+
deterministically derives a schedule directly from the `TicketPlan` graph
|
|
54
|
+
instead — this is the accepted fallback shape, not a patch to remove.
|
|
55
|
+
|
|
56
|
+
The result is written once via `publishSchedule()`
|
|
57
|
+
(`src/run-control/run-control-store.ts:60`) into the run's manifest
|
|
58
|
+
(`moka_run_control_run.manifest` JSONB). `publishSchedule` is idempotent for an
|
|
59
|
+
identical schedule and rejects a conflicting one for the same run
|
|
60
|
+
(`tests/run-control-store-contract.test.ts:423`).
|
|
61
|
+
|
|
62
|
+
## Stage 2 — Dispatch (compile -> submit)
|
|
63
|
+
|
|
64
|
+
`submitParsedMoka()` (`src/remote/submit/service.ts:47`) upserts the run record
|
|
65
|
+
to Postgres **before** calling Argo, but a DB write failure never blocks
|
|
66
|
+
dispatch — the guard at `service.ts:56-61` logs and proceeds, because the
|
|
67
|
+
in-pod runner lifecycle (`src/runner-command/lifecycle.ts`) re-creates the same
|
|
68
|
+
run record idempotently once the pod starts. Postgres is a durability/inspection
|
|
69
|
+
substrate for `moka status`/`moka logs`/`moka resume`, not a precondition for
|
|
70
|
+
submission.
|
|
71
|
+
|
|
72
|
+
`submitCompiledMokaWorkflow()` then calls `submitRunnerArgoWorkflow()` (static,
|
|
73
|
+
schedule already known) or `submitDynamicRunnerArgoWorkflow()` (dynamic,
|
|
74
|
+
schedule generated in-pod) — both in `src/argo-submit.ts`, both routed through
|
|
75
|
+
the same `KubernetesArgoService`.
|
|
76
|
+
|
|
77
|
+
## Cluster targeting is one seam, not per-caller
|
|
78
|
+
|
|
79
|
+
Kubernetes context/kubeconfig resolution is a single function,
|
|
80
|
+
`resolveKubeConfig()` (`src/runtime/services/kubernetes-argo-service.ts`), used
|
|
81
|
+
by every Argo/K8s call (`createConfigMap`, `createWorkflow`,
|
|
82
|
+
`getWorkflowPhase`). Precedence, highest wins:
|
|
83
|
+
|
|
84
|
+
1. `--kube-context <name>` / `--kubeconfig <path>` CLI flags
|
|
85
|
+
(`src/cli/submit-options.ts`)
|
|
86
|
+
2. `momokaya.kubernetes.context` / `momokaya.kubernetes.kubeconfig` in
|
|
87
|
+
`~/.config/moka/config.yaml` (`src/moka-global-config.ts`)
|
|
88
|
+
3. The kubeconfig's own `current-context` (`KubeConfig.loadFromDefault()`)
|
|
89
|
+
|
|
90
|
+
An unresolvable `kubeContext` fails loud at resolution time (`kubeConfig.
|
|
91
|
+
getContextObject()` check) rather than silently falling through to whatever
|
|
92
|
+
context happened to be current — this is what makes "point submit at momokaya
|
|
93
|
+
or at a local orbstack context" a config change, never a code change. Prior to
|
|
94
|
+
this ADR, `kubeContext` existed for the `kubectl`-shellout polling path
|
|
95
|
+
(`cluster-doctor.ts`) but not for the actual submission API calls; that gap is
|
|
96
|
+
closed as part of this decision.
|
|
97
|
+
|
|
98
|
+
## Consequences
|
|
99
|
+
|
|
100
|
+
- Do not add a second "generate the graph" path or a second Argo client.
|
|
101
|
+
Static vs. dynamic scheduling is a data flag on `CompiledMokaSubmitPlan`, not
|
|
102
|
+
a reason to fork the builder or the service.
|
|
103
|
+
- Do not gate submission on the DB write succeeding — the guard in
|
|
104
|
+
`service.ts` is intentional, not a missing try/catch to "fix".
|
|
105
|
+
- Any new cluster-targeting option (a third context source, a per-namespace
|
|
106
|
+
override) is added to `resolveKubeConfig`'s precedence list, not threaded
|
|
107
|
+
ad hoc through individual call sites.
|
|
108
|
+
|
|
109
|
+
## References
|
|
110
|
+
|
|
111
|
+
- Run-control persistence model: `./run-control.md`
|
|
112
|
+
- PIPE-94 durable substrate: `oisin-ee` backlog PIPE-94.3/94.4/94.5/94.8
|
package/package.json
CHANGED
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@biomejs/biome": "2.4.15",
|
|
34
34
|
"@effect/vitest": "^4.0.0-beta.90",
|
|
35
|
+
"@mpsuesser/oxlint-plugin-effect": "0.3.0",
|
|
36
|
+
"@oisin-ee/oxlint-config": "1.0.0",
|
|
35
37
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
36
38
|
"@semantic-release/exec": "^7.1.0",
|
|
37
39
|
"@semantic-release/github": "^12.0.8",
|
|
@@ -42,6 +44,9 @@
|
|
|
42
44
|
"@typescript/native-preview": "7.0.0-dev.20260629.1",
|
|
43
45
|
"drizzle-kit": "0.31.10",
|
|
44
46
|
"jscpd": "^4.0.5",
|
|
47
|
+
"oxfmt": "^0.56.0",
|
|
48
|
+
"oxlint": "^1.71.0",
|
|
49
|
+
"oxlint-tsgolint": "^0.23.0",
|
|
45
50
|
"semantic-release": "^25.0.3",
|
|
46
51
|
"tsdown": "^0.22.0",
|
|
47
52
|
"typescript": "rc",
|
|
@@ -132,7 +137,7 @@
|
|
|
132
137
|
"prepack": "nub run build:cli"
|
|
133
138
|
},
|
|
134
139
|
"type": "module",
|
|
135
|
-
"version": "3.19.
|
|
140
|
+
"version": "3.19.6",
|
|
136
141
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
137
142
|
"main": "./dist/index.js",
|
|
138
143
|
"types": "./dist/index.d.ts",
|