agentweaver 0.1.10 → 0.1.12
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/README.md +218 -224
- package/dist/artifacts.js +109 -55
- package/dist/executors/{codex-local-executor.js → codex-executor.js} +6 -5
- package/dist/executors/configs/{codex-local-config.js → codex-config.js} +1 -1
- package/dist/executors/configs/jira-fetch-config.js +2 -0
- package/dist/executors/configs/telegram-notifier-config.js +3 -0
- package/dist/executors/fetch-gitlab-diff-executor.js +1 -1
- package/dist/executors/fetch-gitlab-review-executor.js +1 -1
- package/dist/executors/git-commit-executor.js +25 -0
- package/dist/executors/jira-fetch-executor.js +1 -0
- package/dist/executors/opencode-executor.js +22 -11
- package/dist/executors/process-executor.js +3 -0
- package/dist/executors/telegram-notifier-executor.js +54 -0
- package/dist/flow-state.js +46 -1
- package/dist/gitlab.js +13 -8
- package/dist/index.js +477 -514
- package/dist/interactive-ui.js +609 -88
- package/dist/jira.js +109 -5
- package/dist/pipeline/auto-flow.js +6 -6
- package/dist/pipeline/context.js +1 -0
- package/dist/pipeline/flow-catalog.js +34 -4
- package/dist/pipeline/flow-model-settings.js +77 -0
- package/dist/pipeline/flow-specs/auto-common.json +446 -0
- package/dist/pipeline/flow-specs/auto-golang.json +563 -0
- package/dist/pipeline/flow-specs/{bug-analyze.json → bugz/bug-analyze.json} +43 -25
- package/dist/pipeline/flow-specs/{bug-fix.json → bugz/bug-fix.json} +5 -4
- package/dist/pipeline/flow-specs/git-commit.json +196 -0
- package/dist/pipeline/flow-specs/{gitlab-diff-review.json → gitlab/gitlab-diff-review.json} +20 -50
- package/dist/pipeline/flow-specs/{gitlab-review.json → gitlab/gitlab-review.json} +65 -133
- package/dist/pipeline/flow-specs/{mr-description.json → gitlab/mr-description.json} +17 -10
- package/dist/pipeline/flow-specs/{run-go-linter-loop.json → go/run-go-linter-loop.json} +40 -14
- package/dist/pipeline/flow-specs/{run-go-tests-loop.json → go/run-go-tests-loop.json} +40 -14
- package/dist/pipeline/flow-specs/implement.json +5 -4
- package/dist/pipeline/flow-specs/plan.json +40 -148
- package/dist/pipeline/flow-specs/{review-fix.json → review/review-fix.json} +74 -13
- package/dist/pipeline/flow-specs/review/review-loop.json +282 -0
- package/dist/pipeline/flow-specs/review/review-project.json +87 -0
- package/dist/pipeline/flow-specs/review/review.json +126 -0
- package/dist/pipeline/flow-specs/task-describe.json +252 -11
- package/dist/pipeline/launch-profile-config.js +38 -0
- package/dist/pipeline/node-registry.js +75 -45
- package/dist/pipeline/nodes/build-failure-summary-node.js +16 -29
- package/dist/pipeline/nodes/build-review-fix-prompt-node.js +36 -0
- package/dist/pipeline/nodes/codex-prompt-node.js +41 -0
- package/dist/pipeline/nodes/commit-message-form-node.js +79 -0
- package/dist/pipeline/nodes/git-commit-form-node.js +138 -0
- package/dist/pipeline/nodes/git-commit-node.js +28 -0
- package/dist/pipeline/nodes/git-status-node.js +221 -0
- package/dist/pipeline/nodes/gitlab-review-artifacts-node.js +10 -6
- package/dist/pipeline/nodes/jira-context-node.js +10 -0
- package/dist/pipeline/nodes/jira-fetch-node.js +3 -0
- package/dist/pipeline/nodes/llm-prompt-node.js +62 -0
- package/dist/pipeline/nodes/plan-codex-node.js +1 -1
- package/dist/pipeline/nodes/read-file-node.js +11 -0
- package/dist/pipeline/nodes/review-findings-form-node.js +48 -14
- package/dist/pipeline/nodes/select-files-form-node.js +72 -0
- package/dist/pipeline/nodes/telegram-notifier-node.js +28 -0
- package/dist/pipeline/nodes/user-input-node.js +43 -8
- package/dist/pipeline/nodes/write-selection-file-node.js +46 -0
- package/dist/pipeline/prompt-registry.js +3 -4
- package/dist/pipeline/prompt-runtime.js +13 -3
- package/dist/pipeline/registry.js +6 -8
- package/dist/pipeline/spec-compiler.js +5 -0
- package/dist/pipeline/spec-types.js +9 -3
- package/dist/pipeline/spec-validator.js +4 -0
- package/dist/pipeline/types.js +1 -0
- package/dist/pipeline/value-resolver.js +50 -38
- package/dist/prompts.js +119 -110
- package/dist/runtime/agentweaver-home.js +8 -0
- package/dist/runtime/command-resolution.js +0 -38
- package/dist/runtime/env-loader.js +43 -0
- package/dist/runtime/process-runner.js +9 -3
- package/dist/structured-artifact-schema-registry.js +54 -0
- package/dist/structured-artifact-schemas.json +22 -20
- package/dist/structured-artifacts.js +3 -43
- package/dist/user-input.js +38 -3
- package/package.json +2 -6
- package/Dockerfile.codex +0 -56
- package/dist/executors/claude-executor.js +0 -46
- package/dist/executors/codex-docker-executor.js +0 -27
- package/dist/executors/configs/claude-config.js +0 -12
- package/dist/executors/configs/codex-docker-config.js +0 -10
- package/dist/executors/configs/verify-build-config.js +0 -7
- package/dist/executors/verify-build-executor.js +0 -123
- package/dist/pipeline/flow-specs/auto.json +0 -979
- package/dist/pipeline/flow-specs/opencode/auto-opencode.json +0 -1365
- package/dist/pipeline/flow-specs/opencode/bugz/bug-analyze-opencode.json +0 -382
- package/dist/pipeline/flow-specs/opencode/bugz/bug-fix-opencode.json +0 -56
- package/dist/pipeline/flow-specs/opencode/gitlab/gitlab-diff-review-opencode.json +0 -308
- package/dist/pipeline/flow-specs/opencode/gitlab/gitlab-review-opencode.json +0 -437
- package/dist/pipeline/flow-specs/opencode/gitlab/mr-description-opencode.json +0 -117
- package/dist/pipeline/flow-specs/opencode/go/run-go-linter-loop-opencode.json +0 -321
- package/dist/pipeline/flow-specs/opencode/go/run-go-tests-loop-opencode.json +0 -321
- package/dist/pipeline/flow-specs/opencode/implement-opencode.json +0 -64
- package/dist/pipeline/flow-specs/opencode/plan-opencode.json +0 -603
- package/dist/pipeline/flow-specs/opencode/review/review-fix-opencode.json +0 -209
- package/dist/pipeline/flow-specs/opencode/review/review-opencode.json +0 -452
- package/dist/pipeline/flow-specs/opencode/task-describe-opencode.json +0 -148
- package/dist/pipeline/flow-specs/review-project.json +0 -243
- package/dist/pipeline/flow-specs/review.json +0 -312
- package/dist/pipeline/flows/preflight-flow.js +0 -19
- package/dist/pipeline/nodes/claude-prompt-node.js +0 -54
- package/dist/pipeline/nodes/codex-docker-prompt-node.js +0 -32
- package/dist/pipeline/nodes/codex-local-prompt-node.js +0 -32
- package/dist/pipeline/nodes/review-claude-node.js +0 -38
- package/dist/pipeline/nodes/review-reply-codex-node.js +0 -40
- package/dist/pipeline/nodes/verify-build-node.js +0 -15
- package/dist/runtime/docker-runtime.js +0 -51
- package/docker-compose.yml +0 -445
- package/verify_build.sh +0 -105
|
@@ -1,27 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
2
|
import { TaskRunnerError } from "./errors.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"bug-fix-design/v1",
|
|
8
|
-
"bug-fix-plan/v1",
|
|
9
|
-
"gitlab-mr-diff/v1",
|
|
10
|
-
"gitlab-review/v1",
|
|
11
|
-
"implementation-design/v1",
|
|
12
|
-
"implementation-plan/v1",
|
|
13
|
-
"jira-description/v1",
|
|
14
|
-
"mr-description/v1",
|
|
15
|
-
"planning-questions/v1",
|
|
16
|
-
"qa-plan/v1",
|
|
17
|
-
"review-findings/v1",
|
|
18
|
-
"review-fix-report/v1",
|
|
19
|
-
"review-reply/v1",
|
|
20
|
-
"task-summary/v1",
|
|
21
|
-
"user-input/v1",
|
|
22
|
-
];
|
|
23
|
-
const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
-
const SCHEMA_REGISTRY_PATH = path.join(MODULE_DIR, "structured-artifact-schemas.json");
|
|
3
|
+
import { STRUCTURED_ARTIFACT_SCHEMA_IDS, getStructuredArtifactSchema, } from "./structured-artifact-schema-registry.js";
|
|
4
|
+
export { STRUCTURED_ARTIFACT_SCHEMA_IDS };
|
|
25
5
|
function isRecord(value) {
|
|
26
6
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27
7
|
}
|
|
@@ -99,23 +79,6 @@ function validateNode(value, schema, currentPath) {
|
|
|
99
79
|
}
|
|
100
80
|
}
|
|
101
81
|
}
|
|
102
|
-
function loadSchemaRegistry() {
|
|
103
|
-
if (!existsSync(SCHEMA_REGISTRY_PATH)) {
|
|
104
|
-
throw new TaskRunnerError(`Structured artifact schema registry not found: ${SCHEMA_REGISTRY_PATH}`);
|
|
105
|
-
}
|
|
106
|
-
let parsed;
|
|
107
|
-
try {
|
|
108
|
-
parsed = JSON.parse(readFileSync(SCHEMA_REGISTRY_PATH, "utf8"));
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
throw new TaskRunnerError(`Failed to parse structured artifact schema registry: ${error.message}`);
|
|
112
|
-
}
|
|
113
|
-
if (!isRecord(parsed)) {
|
|
114
|
-
throw new TaskRunnerError(`Structured artifact schema registry ${SCHEMA_REGISTRY_PATH} must be a JSON object.`);
|
|
115
|
-
}
|
|
116
|
-
return parsed;
|
|
117
|
-
}
|
|
118
|
-
const schemas = loadSchemaRegistry();
|
|
119
82
|
export function validateStructuredArtifact(path, schemaId) {
|
|
120
83
|
if (!existsSync(path)) {
|
|
121
84
|
throw new TaskRunnerError(`Structured artifact file not found: ${path}`);
|
|
@@ -127,10 +90,7 @@ export function validateStructuredArtifact(path, schemaId) {
|
|
|
127
90
|
catch (error) {
|
|
128
91
|
throw new TaskRunnerError(`Structured artifact ${path} is not valid JSON: ${error.message}`);
|
|
129
92
|
}
|
|
130
|
-
const schema =
|
|
131
|
-
if (!schema) {
|
|
132
|
-
throw new TaskRunnerError(`Structured artifact schema is not registered: ${schemaId}`);
|
|
133
|
-
}
|
|
93
|
+
const schema = getStructuredArtifactSchema(schemaId);
|
|
134
94
|
const issues = validateNode(parsed, schema, path);
|
|
135
95
|
if (issues.length > 0) {
|
|
136
96
|
throw new TaskRunnerError(`Structured artifact ${path} failed schema ${schemaId} validation:\n${issues.join("\n")}`);
|
package/dist/user-input.js
CHANGED
|
@@ -71,6 +71,16 @@ export function validateUserInputValues(form, values) {
|
|
|
71
71
|
throw new TaskRunnerError("Select at least one finding or enable 'apply all'.");
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
+
if (form.formId === "task-describe-source-input") {
|
|
75
|
+
const jiraRef = typeof values.jira_ref === "string" ? normalizeText(values.jira_ref) : "";
|
|
76
|
+
const taskDescription = typeof values.task_description === "string" ? normalizeText(values.task_description) : "";
|
|
77
|
+
if (!jiraRef && !taskDescription) {
|
|
78
|
+
throw new TaskRunnerError("Provide either Jira URL/key or a short task description.");
|
|
79
|
+
}
|
|
80
|
+
if (jiraRef && taskDescription) {
|
|
81
|
+
throw new TaskRunnerError("Provide either Jira URL/key or a short task description, not both.");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
74
84
|
}
|
|
75
85
|
function parseBoolean(value) {
|
|
76
86
|
const normalized = normalizeText(value).toLowerCase();
|
|
@@ -120,11 +130,36 @@ export async function requestUserInputInTerminal(form) {
|
|
|
120
130
|
}
|
|
121
131
|
if (field.type === "text") {
|
|
122
132
|
const current = String(values[field.id] ?? "");
|
|
123
|
-
|
|
124
|
-
|
|
133
|
+
if (field.multiline) {
|
|
134
|
+
process.stdout.write(`${field.label}${current ? " (leave empty to keep current value)" : ""}:\n`);
|
|
135
|
+
if (field.help?.trim()) {
|
|
136
|
+
process.stdout.write(`${field.help.trim()}\n`);
|
|
137
|
+
}
|
|
138
|
+
process.stdout.write("Finish input with an empty line.\n");
|
|
139
|
+
const lines = [];
|
|
140
|
+
while (true) {
|
|
141
|
+
const line = await rl.question(lines.length === 0 ? "> " : "... ");
|
|
142
|
+
if (!line.trim()) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
lines.push(line);
|
|
146
|
+
}
|
|
147
|
+
values[field.id] = lines.length > 0 ? lines.join("\n") : current;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const answer = await rl.question(`${field.label}${current ? ` (${current})` : ""}: `);
|
|
151
|
+
values[field.id] = answer.trim() ? answer : current;
|
|
152
|
+
}
|
|
125
153
|
continue;
|
|
126
154
|
}
|
|
127
|
-
const options = field.options
|
|
155
|
+
const options = field.options
|
|
156
|
+
.map((option, index) => {
|
|
157
|
+
const description = option.description
|
|
158
|
+
? `\n ${option.description.split("\n").join("\n ")}`
|
|
159
|
+
: "";
|
|
160
|
+
return `${index + 1}. ${option.label}${description}`;
|
|
161
|
+
})
|
|
162
|
+
.join("\n");
|
|
128
163
|
process.stdout.write(`${field.label}\n${options}\n`);
|
|
129
164
|
if (field.type === "single-select") {
|
|
130
165
|
while (true) {
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentweaver",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "CLI orchestrator for Jira/Codex
|
|
3
|
+
"version": "0.1.12",
|
|
4
|
+
"description": "CLI orchestrator for Jira/Codex engineering workflows",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
7
7
|
"cli",
|
|
8
8
|
"jira",
|
|
9
9
|
"codex",
|
|
10
|
-
"claude",
|
|
11
10
|
"tui",
|
|
12
11
|
"developer-tools"
|
|
13
12
|
],
|
|
@@ -29,9 +28,6 @@
|
|
|
29
28
|
"files": [
|
|
30
29
|
"dist",
|
|
31
30
|
"README.md",
|
|
32
|
-
"docker-compose.yml",
|
|
33
|
-
"Dockerfile.codex",
|
|
34
|
-
"verify_build.sh",
|
|
35
31
|
"run_go_tests.py",
|
|
36
32
|
"run_go_linter.py",
|
|
37
33
|
"run_go_coverage.sh"
|
package/Dockerfile.codex
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
FROM golang:1.25.5-bookworm
|
|
2
|
-
|
|
3
|
-
ARG GOLANGCI_LINT_VERSION=v2.7.2
|
|
4
|
-
ARG MOCKGEN_VERSION=v1.6.0
|
|
5
|
-
ARG SWAG_VERSION=latest
|
|
6
|
-
ARG PROTOC_GEN_GO_VERSION=latest
|
|
7
|
-
ARG PROTOC_GEN_GO_GRPC_VERSION=latest
|
|
8
|
-
|
|
9
|
-
RUN apt-get update \
|
|
10
|
-
&& apt-get install -y --no-install-recommends \
|
|
11
|
-
ca-certificates \
|
|
12
|
-
nodejs \
|
|
13
|
-
npm \
|
|
14
|
-
curl \
|
|
15
|
-
jq \
|
|
16
|
-
less \
|
|
17
|
-
file \
|
|
18
|
-
make \
|
|
19
|
-
procps \
|
|
20
|
-
ripgrep \
|
|
21
|
-
git \
|
|
22
|
-
openssh-client \
|
|
23
|
-
docker.io \
|
|
24
|
-
protobuf-compiler \
|
|
25
|
-
unzip \
|
|
26
|
-
zip \
|
|
27
|
-
findutils \
|
|
28
|
-
&& update-ca-certificates \
|
|
29
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
30
|
-
|
|
31
|
-
RUN if ! getent group 1000 >/dev/null; then groupadd -g 1000 codex; fi \
|
|
32
|
-
&& if ! getent passwd 1000 >/dev/null; then useradd -u 1000 -g 1000 -d /codex-home/home -M -s /bin/bash codex; fi
|
|
33
|
-
|
|
34
|
-
RUN npm install -g @openai/codex@latest \
|
|
35
|
-
&& npm cache clean --force
|
|
36
|
-
|
|
37
|
-
RUN GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${GOLANGCI_LINT_VERSION} \
|
|
38
|
-
&& GOBIN=/usr/local/bin go install github.com/golang/mock/mockgen@${MOCKGEN_VERSION} \
|
|
39
|
-
&& GOBIN=/usr/local/bin go install github.com/swaggo/swag/cmd/swag@${SWAG_VERSION} \
|
|
40
|
-
&& GOBIN=/usr/local/bin go install google.golang.org/protobuf/cmd/protoc-gen-go@${PROTOC_GEN_GO_VERSION} \
|
|
41
|
-
&& GOBIN=/usr/local/bin go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@${PROTOC_GEN_GO_GRPC_VERSION} \
|
|
42
|
-
&& ln -sf /usr/local/go/bin/go /usr/bin/go \
|
|
43
|
-
&& ln -sf /usr/local/go/bin/gofmt /usr/bin/gofmt
|
|
44
|
-
|
|
45
|
-
ENV PATH="/usr/local/go/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
46
|
-
|
|
47
|
-
COPY verify_build.sh /usr/local/bin/verify_build.sh
|
|
48
|
-
COPY run_go_tests.py /usr/local/bin/run_go_tests.py
|
|
49
|
-
COPY run_go_linter.py /usr/local/bin/run_go_linter.py
|
|
50
|
-
COPY run_go_coverage.sh /usr/local/bin/run_go_coverage.sh
|
|
51
|
-
RUN chmod +x /usr/local/bin/verify_build.sh /usr/local/bin/run_go_tests.py /usr/local/bin/run_go_linter.py /usr/local/bin/run_go_coverage.sh
|
|
52
|
-
|
|
53
|
-
WORKDIR /workspace
|
|
54
|
-
|
|
55
|
-
ENTRYPOINT ["codex"]
|
|
56
|
-
CMD ["--dangerously-bypass-approvals-and-sandbox"]
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { claudeExecutorDefaultConfig } from "./configs/claude-config.js";
|
|
2
|
-
import { processExecutor } from "./process-executor.js";
|
|
3
|
-
function resolveModel(config, env) {
|
|
4
|
-
const primaryModel = env[config.modelEnvVar]?.trim();
|
|
5
|
-
if (primaryModel) {
|
|
6
|
-
return primaryModel;
|
|
7
|
-
}
|
|
8
|
-
for (const envVarName of config.legacyModelEnvVars ?? []) {
|
|
9
|
-
const legacyModel = env[envVarName]?.trim();
|
|
10
|
-
if (legacyModel) {
|
|
11
|
-
return legacyModel;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return config.defaultModel;
|
|
15
|
-
}
|
|
16
|
-
export const claudeExecutor = {
|
|
17
|
-
kind: "claude",
|
|
18
|
-
version: 1,
|
|
19
|
-
defaultConfig: claudeExecutorDefaultConfig,
|
|
20
|
-
async execute(context, input, config) {
|
|
21
|
-
const env = input.env ?? context.env;
|
|
22
|
-
const command = input.command ?? context.runtime.resolveCmd(config.defaultCommand, config.commandEnvVar);
|
|
23
|
-
const model = input.model?.trim() || resolveModel(config, env);
|
|
24
|
-
const argv = [command, "--model", model, config.promptFlag, `--allowedTools=${config.allowedTools}`];
|
|
25
|
-
if (config.outputFormat) {
|
|
26
|
-
argv.push("--output-format", config.outputFormat);
|
|
27
|
-
}
|
|
28
|
-
if (config.verboseMode) {
|
|
29
|
-
argv.push("--verbose");
|
|
30
|
-
}
|
|
31
|
-
if (config.includePartialMessages) {
|
|
32
|
-
argv.push("--include-partial-messages");
|
|
33
|
-
}
|
|
34
|
-
argv.push(input.prompt);
|
|
35
|
-
const result = await processExecutor.execute(context, {
|
|
36
|
-
argv,
|
|
37
|
-
env,
|
|
38
|
-
label: `claude:${model}`,
|
|
39
|
-
}, processExecutor.defaultConfig);
|
|
40
|
-
return {
|
|
41
|
-
output: result.output,
|
|
42
|
-
command,
|
|
43
|
-
model,
|
|
44
|
-
};
|
|
45
|
-
},
|
|
46
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { codexDockerExecutorDefaultConfig } from "./configs/codex-docker-config.js";
|
|
2
|
-
import { processExecutor } from "./process-executor.js";
|
|
3
|
-
function resolveModel(config, env) {
|
|
4
|
-
return env[config.modelEnvVar]?.trim() || config.defaultModel;
|
|
5
|
-
}
|
|
6
|
-
export const codexDockerExecutor = {
|
|
7
|
-
kind: "codex-docker",
|
|
8
|
-
version: 1,
|
|
9
|
-
defaultConfig: codexDockerExecutorDefaultConfig,
|
|
10
|
-
async execute(context, input, config) {
|
|
11
|
-
const composeCommand = context.runtime.resolveDockerComposeCmd();
|
|
12
|
-
const env = context.runtime.dockerRuntimeEnv();
|
|
13
|
-
const model = input.model?.trim() || resolveModel(config, env);
|
|
14
|
-
env[config.promptEnvVar] = input.prompt;
|
|
15
|
-
env[config.flagsEnvVar] = config.execFlagsTemplate.replace("{model}", model);
|
|
16
|
-
const result = await processExecutor.execute(context, {
|
|
17
|
-
argv: [...composeCommand, config.composeFileFlag, input.dockerComposeFile, ...config.runArgs, config.service],
|
|
18
|
-
env,
|
|
19
|
-
label: `codex:${model}`,
|
|
20
|
-
}, processExecutor.defaultConfig);
|
|
21
|
-
return {
|
|
22
|
-
output: result.output,
|
|
23
|
-
composeCommand,
|
|
24
|
-
model,
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export const claudeExecutorDefaultConfig = {
|
|
2
|
-
commandEnvVar: "CLAUDE_BIN",
|
|
3
|
-
defaultCommand: "claude",
|
|
4
|
-
modelEnvVar: "CLAUDE_MODEL",
|
|
5
|
-
legacyModelEnvVars: ["CLAUDE_REVIEW_MODEL"],
|
|
6
|
-
defaultModel: "opus",
|
|
7
|
-
promptFlag: "-p",
|
|
8
|
-
allowedTools: "Read,Write,Edit",
|
|
9
|
-
outputFormat: "stream-json",
|
|
10
|
-
includePartialMessages: true,
|
|
11
|
-
verboseMode: true,
|
|
12
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export const codexDockerExecutorDefaultConfig = {
|
|
2
|
-
service: "codex-exec",
|
|
3
|
-
composeFileFlag: "-f",
|
|
4
|
-
runArgs: ["run", "--rm"],
|
|
5
|
-
modelEnvVar: "CODEX_MODEL",
|
|
6
|
-
defaultModel: "gpt-5.4",
|
|
7
|
-
promptEnvVar: "CODEX_PROMPT",
|
|
8
|
-
flagsEnvVar: "CODEX_EXEC_FLAGS",
|
|
9
|
-
execFlagsTemplate: "--model {model} --dangerously-bypass-approvals-and-sandbox",
|
|
10
|
-
};
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { verifyBuildExecutorDefaultConfig } from "./configs/verify-build-config.js";
|
|
2
|
-
import { TaskRunnerError } from "../errors.js";
|
|
3
|
-
import { processExecutor } from "./process-executor.js";
|
|
4
|
-
function parseStructuredResult(output, service) {
|
|
5
|
-
const lines = output
|
|
6
|
-
.split(/\r?\n/)
|
|
7
|
-
.map((line) => line.replace(/\u001b\[[0-9;]*m/g, "").trim())
|
|
8
|
-
.filter(Boolean);
|
|
9
|
-
if (lines.length === 0) {
|
|
10
|
-
throw new TaskRunnerError(`Structured result is missing from service '${service}' output.`);
|
|
11
|
-
}
|
|
12
|
-
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
13
|
-
const line = lines[index];
|
|
14
|
-
if (!line) {
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
const candidates = [];
|
|
18
|
-
if (line.startsWith("{") && line.endsWith("}")) {
|
|
19
|
-
candidates.push(line);
|
|
20
|
-
}
|
|
21
|
-
const firstBrace = line.indexOf("{");
|
|
22
|
-
const lastBrace = line.lastIndexOf("}");
|
|
23
|
-
if (firstBrace >= 0 && lastBrace > firstBrace) {
|
|
24
|
-
const slice = line.slice(firstBrace, lastBrace + 1).trim();
|
|
25
|
-
if (slice && !candidates.includes(slice)) {
|
|
26
|
-
candidates.push(slice);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
for (const rawJson of candidates) {
|
|
30
|
-
let parsed;
|
|
31
|
-
try {
|
|
32
|
-
parsed = JSON.parse(rawJson);
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
const candidate = parsed;
|
|
41
|
-
if (typeof candidate.ok !== "boolean" ||
|
|
42
|
-
typeof candidate.kind !== "string" ||
|
|
43
|
-
typeof candidate.stage !== "string" ||
|
|
44
|
-
typeof candidate.exitCode !== "number" ||
|
|
45
|
-
typeof candidate.summary !== "string" ||
|
|
46
|
-
typeof candidate.command !== "string") {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
const details = candidate.details;
|
|
50
|
-
if (details !== undefined && (!details || typeof details !== "object" || Array.isArray(details))) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
return {
|
|
54
|
-
ok: candidate.ok,
|
|
55
|
-
kind: candidate.kind,
|
|
56
|
-
stage: candidate.stage,
|
|
57
|
-
exitCode: candidate.exitCode,
|
|
58
|
-
summary: candidate.summary,
|
|
59
|
-
command: candidate.command,
|
|
60
|
-
details: details ?? {},
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
throw new TaskRunnerError(`Structured result is missing or invalid in service '${service}' output.`);
|
|
65
|
-
}
|
|
66
|
-
export const verifyBuildExecutor = {
|
|
67
|
-
kind: "verify-build",
|
|
68
|
-
version: 1,
|
|
69
|
-
defaultConfig: verifyBuildExecutorDefaultConfig,
|
|
70
|
-
async execute(context, input, config) {
|
|
71
|
-
const composeCommand = context.runtime.resolveDockerComposeCmd();
|
|
72
|
-
const service = input.service ?? config.service;
|
|
73
|
-
if (context.dryRun) {
|
|
74
|
-
await processExecutor.execute(context, {
|
|
75
|
-
argv: [...composeCommand, config.composeFileFlag, input.dockerComposeFile, ...config.runArgs, service],
|
|
76
|
-
env: context.runtime.dockerRuntimeEnv(),
|
|
77
|
-
verbose: config.verbose,
|
|
78
|
-
label: service,
|
|
79
|
-
}, {
|
|
80
|
-
printFailureOutput: config.printFailureOutput,
|
|
81
|
-
});
|
|
82
|
-
return {
|
|
83
|
-
output: "",
|
|
84
|
-
composeCommand,
|
|
85
|
-
parsed: {
|
|
86
|
-
ok: true,
|
|
87
|
-
kind: service,
|
|
88
|
-
stage: "dry_run",
|
|
89
|
-
exitCode: 0,
|
|
90
|
-
summary: `Dry run for service '${service}'`,
|
|
91
|
-
command: [...composeCommand, config.composeFileFlag, input.dockerComposeFile, ...config.runArgs, service].join(" "),
|
|
92
|
-
details: {},
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
let output = "";
|
|
97
|
-
let exitCode = 0;
|
|
98
|
-
try {
|
|
99
|
-
const result = await processExecutor.execute(context, {
|
|
100
|
-
argv: [...composeCommand, config.composeFileFlag, input.dockerComposeFile, ...config.runArgs, service],
|
|
101
|
-
env: context.runtime.dockerRuntimeEnv(),
|
|
102
|
-
verbose: config.verbose,
|
|
103
|
-
label: service,
|
|
104
|
-
}, {
|
|
105
|
-
printFailureOutput: config.printFailureOutput,
|
|
106
|
-
});
|
|
107
|
-
output = result.output;
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
output = String(error.output ?? "");
|
|
111
|
-
exitCode = Number(error.returnCode ?? 1);
|
|
112
|
-
}
|
|
113
|
-
const parsed = parseStructuredResult(output, service);
|
|
114
|
-
if (parsed.exitCode !== exitCode && exitCode !== 0) {
|
|
115
|
-
throw new TaskRunnerError(`Structured result exit code mismatch for service '${service}': script=${parsed.exitCode}, runtime=${exitCode}.`);
|
|
116
|
-
}
|
|
117
|
-
return {
|
|
118
|
-
output,
|
|
119
|
-
composeCommand,
|
|
120
|
-
parsed,
|
|
121
|
-
};
|
|
122
|
-
},
|
|
123
|
-
};
|