@oisincoveney/pipeline 3.12.4 → 3.13.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/argo-submit.d.ts +5 -0
- package/dist/argo-submit.js +3 -0
- package/dist/argo-workflow.d.ts +15 -2
- package/dist/argo-workflow.js +41 -7
- package/dist/broker-auth.d.ts +16 -0
- package/dist/broker-auth.js +172 -0
- package/dist/cli/program.js +1 -0
- package/dist/cli/submit-options.js +1 -0
- package/dist/cluster-doctor.js +4 -2
- package/dist/codex-auth-sync.js +14 -1
- package/dist/install-commands/claude-code.js +1 -1
- package/dist/install-commands/opencode.js +1 -1
- package/dist/install-commands.js +2 -2
- package/dist/install-hooks.js +1 -1
- package/dist/loop/loop-command.js +1 -0
- package/dist/moka-global-config.d.ts +6 -1
- package/dist/moka-global-config.js +3 -1
- package/dist/moka-submit.d.ts +12 -0
- package/dist/moka-submit.js +3 -0
- package/dist/run-state/opencode-accounts.js +45 -4
- package/dist/runner-command/run.js +1 -0
- package/package.json +1 -1
package/dist/argo-submit.d.ts
CHANGED
|
@@ -20,6 +20,11 @@ declare const submitRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
20
20
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
21
21
|
name: z.ZodOptional<z.ZodString>;
|
|
22
22
|
namespace: z.ZodString;
|
|
23
|
+
brokerAuth: z.ZodOptional<z.ZodObject<{
|
|
24
|
+
secretKey: z.ZodDefault<z.ZodString>;
|
|
25
|
+
secretName: z.ZodString;
|
|
26
|
+
url: z.ZodDefault<z.ZodString>;
|
|
27
|
+
}, z.core.$strict>>;
|
|
23
28
|
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
24
29
|
opencodeOpenaiAccountsSecretName: z.ZodOptional<z.ZodString>;
|
|
25
30
|
payloadJson: z.ZodString;
|
package/dist/argo-submit.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ArgoGraphCompilerError, compileArgoExecutionGraph } from "./argo-graph.js";
|
|
2
|
+
import { brokerAuthOptionSchema } from "./broker-auth.js";
|
|
2
3
|
import { parseRunnerCommandPayload, runnerCommandPayloadSchema } from "./runner-command-contract.js";
|
|
3
4
|
import { buildRunnerTaskDescriptor } from "./runner-command/task-descriptor.js";
|
|
4
5
|
import { buildRunnerArgoWorkflowManifest, runnerArgoWorkflowManifestSchema } from "./argo-workflow.js";
|
|
@@ -38,6 +39,7 @@ const submitRunnerArgoWorkflowOptionsSchema = z.object({
|
|
|
38
39
|
kubeconfigPath: z.string().min(1).optional(),
|
|
39
40
|
name: z.string().min(1).optional(),
|
|
40
41
|
namespace: z.string().min(1),
|
|
42
|
+
brokerAuth: brokerAuthOptionSchema.optional(),
|
|
41
43
|
opencodeAuthSecretName: z.string().min(1).optional(),
|
|
42
44
|
opencodeOpenaiAccountsSecretName: z.string().min(1).optional(),
|
|
43
45
|
payloadJson: z.string().min(1),
|
|
@@ -89,6 +91,7 @@ function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
|
|
|
89
91
|
labels,
|
|
90
92
|
name: options.name,
|
|
91
93
|
namespace: options.namespace,
|
|
94
|
+
brokerAuth: options.brokerAuth,
|
|
92
95
|
opencodeAuthSecretName: options.opencodeAuthSecretName,
|
|
93
96
|
opencodeOpenaiAccountsSecret: options.opencodeOpenaiAccountsSecretName ? { name: options.opencodeOpenaiAccountsSecretName } : void 0,
|
|
94
97
|
payloadConfigMapName,
|
package/dist/argo-workflow.d.ts
CHANGED
|
@@ -27,10 +27,18 @@ declare const runnerArgoWorkflowManifestSchema: z.ZodObject<{
|
|
|
27
27
|
container: z.ZodOptional<z.ZodObject<{
|
|
28
28
|
args: z.ZodArray<z.ZodString>;
|
|
29
29
|
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
30
|
-
env: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
30
|
+
env: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
31
31
|
name: z.ZodString;
|
|
32
32
|
value: z.ZodString;
|
|
33
|
-
}, z.core.$strict
|
|
33
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
34
|
+
name: z.ZodString;
|
|
35
|
+
valueFrom: z.ZodObject<{
|
|
36
|
+
secretKeyRef: z.ZodObject<{
|
|
37
|
+
key: z.ZodString;
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
}, z.core.$strict>]>>>;
|
|
34
42
|
image: z.ZodString;
|
|
35
43
|
imagePullPolicy: z.ZodEnum<{
|
|
36
44
|
Always: "Always";
|
|
@@ -137,6 +145,11 @@ declare const buildRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
137
145
|
labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodOptional<z.ZodString>>>;
|
|
138
146
|
name: z.ZodOptional<z.ZodString>;
|
|
139
147
|
namespace: z.ZodString;
|
|
148
|
+
brokerAuth: z.ZodOptional<z.ZodObject<{
|
|
149
|
+
secretKey: z.ZodDefault<z.ZodString>;
|
|
150
|
+
secretName: z.ZodString;
|
|
151
|
+
url: z.ZodDefault<z.ZodString>;
|
|
152
|
+
}, z.core.$strict>>;
|
|
140
153
|
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
141
154
|
opencodeOpenaiAccountsSecret: z.ZodOptional<z.ZodObject<{
|
|
142
155
|
key: z.ZodOptional<z.ZodString>;
|
package/dist/argo-workflow.js
CHANGED
|
@@ -92,14 +92,21 @@ const argoWorkflowRetryStrategySchema = z.object({
|
|
|
92
92
|
"OnTransientError"
|
|
93
93
|
])
|
|
94
94
|
}).strict();
|
|
95
|
+
const argoWorkflowEnvVarSchema = z.union([z.object({
|
|
96
|
+
name: z.string().min(1),
|
|
97
|
+
value: z.string()
|
|
98
|
+
}).strict(), z.object({
|
|
99
|
+
name: z.string().min(1),
|
|
100
|
+
valueFrom: z.object({ secretKeyRef: z.object({
|
|
101
|
+
key: z.string().min(1),
|
|
102
|
+
name: kubernetesNameSchema
|
|
103
|
+
}).strict() }).strict()
|
|
104
|
+
}).strict()]);
|
|
95
105
|
const argoWorkflowTemplateSchema = z.object({
|
|
96
106
|
container: z.object({
|
|
97
107
|
args: z.array(z.string().min(1)).min(1),
|
|
98
108
|
command: z.array(z.string().min(1)).min(1).optional(),
|
|
99
|
-
env: z.array(
|
|
100
|
-
name: z.string().min(1),
|
|
101
|
-
value: z.string()
|
|
102
|
-
}).strict()).optional(),
|
|
109
|
+
env: z.array(argoWorkflowEnvVarSchema).optional(),
|
|
103
110
|
image: z.string().min(1),
|
|
104
111
|
imagePullPolicy: z.enum([
|
|
105
112
|
"Always",
|
|
@@ -169,6 +176,11 @@ const buildRunnerArgoWorkflowOptionsSchema = z.object({
|
|
|
169
176
|
labels: z.record(z.string().min(1), z.string().min(1).optional()).default({}),
|
|
170
177
|
name: z.string().min(1).optional(),
|
|
171
178
|
namespace: kubernetesNameSchema,
|
|
179
|
+
brokerAuth: z.object({
|
|
180
|
+
secretKey: z.string().min(1).default("api-key"),
|
|
181
|
+
secretName: kubernetesNameSchema,
|
|
182
|
+
url: z.string().min(1).default("https://cliproxy.momokaya.ee")
|
|
183
|
+
}).strict().optional(),
|
|
172
184
|
opencodeAuthSecretName: kubernetesNameSchema.optional(),
|
|
173
185
|
opencodeOpenaiAccountsSecret: z.object({
|
|
174
186
|
key: z.string().min(1).optional(),
|
|
@@ -374,6 +386,28 @@ function runnerWorkflowStorage(options, tasks) {
|
|
|
374
386
|
volumes: z.array(argoWorkflowVolumeSchema).parse(volumes)
|
|
375
387
|
};
|
|
376
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* The runner container env: the static opencode/agent tuning plus, when broker
|
|
391
|
+
* auth is configured, BROKER_URL (literal) and BROKER_API_KEY (sourced from the
|
|
392
|
+
* broker secret key, never inlined into the manifest).
|
|
393
|
+
*/
|
|
394
|
+
function runnerContainerEnv(options) {
|
|
395
|
+
if (!options.brokerAuth) return [...RUNNER_OPENCODE_ENV];
|
|
396
|
+
return [
|
|
397
|
+
...RUNNER_OPENCODE_ENV,
|
|
398
|
+
{
|
|
399
|
+
name: "BROKER_URL",
|
|
400
|
+
value: options.brokerAuth.url
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: "BROKER_API_KEY",
|
|
404
|
+
valueFrom: { secretKeyRef: {
|
|
405
|
+
key: options.brokerAuth.secretKey,
|
|
406
|
+
name: options.brokerAuth.secretName
|
|
407
|
+
} }
|
|
408
|
+
}
|
|
409
|
+
];
|
|
410
|
+
}
|
|
377
411
|
function runnerLifecycleTemplate(options, volumeMounts) {
|
|
378
412
|
return {
|
|
379
413
|
container: {
|
|
@@ -387,7 +421,7 @@ function runnerLifecycleTemplate(options, volumeMounts) {
|
|
|
387
421
|
RUNNER_WORKFLOW_SCHEDULE_PATH
|
|
388
422
|
],
|
|
389
423
|
command: ["moka"],
|
|
390
|
-
env:
|
|
424
|
+
env: runnerContainerEnv(options),
|
|
391
425
|
image: options.image,
|
|
392
426
|
imagePullPolicy: options.imagePullPolicy,
|
|
393
427
|
name: "runner",
|
|
@@ -416,7 +450,7 @@ function runnerCommandTemplate(task, options, volumeMounts) {
|
|
|
416
450
|
RUNNER_WORKFLOW_SCHEDULE_PATH
|
|
417
451
|
],
|
|
418
452
|
command: ["moka"],
|
|
419
|
-
env:
|
|
453
|
+
env: runnerContainerEnv(options),
|
|
420
454
|
image: options.image,
|
|
421
455
|
imagePullPolicy: options.imagePullPolicy,
|
|
422
456
|
name: "runner",
|
|
@@ -441,7 +475,7 @@ function runnerFinalizerTemplate(options, volumeMounts) {
|
|
|
441
475
|
"{{workflow.status}}"
|
|
442
476
|
],
|
|
443
477
|
command: ["moka"],
|
|
444
|
-
env:
|
|
478
|
+
env: runnerContainerEnv(options),
|
|
445
479
|
image: options.image,
|
|
446
480
|
imagePullPolicy: options.imagePullPolicy,
|
|
447
481
|
name: "runner",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/broker-auth.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Submit-time broker auth options: the runner sources BROKER_API_KEY from
|
|
6
|
+
* `secretName[secretKey]` and BROKER_URL from `url`. Shared by every submit
|
|
7
|
+
* entrypoint so the broker wiring is declared in exactly one place.
|
|
8
|
+
*/
|
|
9
|
+
declare const brokerAuthOptionSchema: z.ZodObject<{
|
|
10
|
+
secretKey: z.ZodDefault<z.ZodString>;
|
|
11
|
+
secretName: z.ZodString;
|
|
12
|
+
url: z.ZodDefault<z.ZodString>;
|
|
13
|
+
}, z.core.$strict>;
|
|
14
|
+
type BrokerAuthOption = z.input<typeof brokerAuthOptionSchema>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { BrokerAuthOption };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { applyJsonEdit, ensureTrailingNewline, formatJson, parseJsonRecord } from "./json-config-merge.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/broker-auth.ts
|
|
4
|
+
/**
|
|
5
|
+
* Central CLIProxyAPI broker auth for codex + opencode.
|
|
6
|
+
*
|
|
7
|
+
* When `BROKER_API_KEY` is present, codex and opencode authenticate through the
|
|
8
|
+
* central broker (an OpenAI-compatible `/v1` endpoint) instead of materializing
|
|
9
|
+
* the bespoke multi-auth account pool. The broker owns OAuth refresh / rotation
|
|
10
|
+
* / failover, so the runner no longer stages `oc-codex-multi-auth` accounts, the
|
|
11
|
+
* mounted `~/.codex/auth.json`, or the multi-auth opencode plugin.
|
|
12
|
+
*
|
|
13
|
+
* This mirrors the proven coder dev-workspace template
|
|
14
|
+
* (infra: coder-templates/dev-workspace/main.tf):
|
|
15
|
+
* - codex ~/.codex/config.toml: `model_provider = "broker"` +
|
|
16
|
+
* `[model_providers.broker]` base_url=<broker>/v1 env_key=BROKER_API_KEY
|
|
17
|
+
* wire_api="responses".
|
|
18
|
+
* - opencode global config: `provider.openai.options.baseURL=<broker>/v1`
|
|
19
|
+
* plus `store=false` and `include=["reasoning.encrypted_content"]` (required
|
|
20
|
+
* by the Codex/Responses backend the broker fronts).
|
|
21
|
+
* - opencode auth store: `{"openai":{"type":"api","key":<BROKER_API_KEY>}}`.
|
|
22
|
+
*/
|
|
23
|
+
const BROKER_API_KEY_ENV = "BROKER_API_KEY";
|
|
24
|
+
const BROKER_URL_ENV = "BROKER_URL";
|
|
25
|
+
const DEFAULT_BROKER_URL = "https://cliproxy.momokaya.ee";
|
|
26
|
+
const TRAILING_SLASH_RE = /\/+$/;
|
|
27
|
+
const CODEX_BROKER_PROVIDER_ID = "broker";
|
|
28
|
+
const OPENCODE_OPENAI_PROVIDER_ID = "openai";
|
|
29
|
+
/** Plugin removed from opencode config in broker mode (broker fronts auth). */
|
|
30
|
+
const OC_CODEX_MULTI_AUTH_PLUGIN_NAME = "oc-codex-multi-auth";
|
|
31
|
+
/**
|
|
32
|
+
* Submit-time broker auth options: the runner sources BROKER_API_KEY from
|
|
33
|
+
* `secretName[secretKey]` and BROKER_URL from `url`. Shared by every submit
|
|
34
|
+
* entrypoint so the broker wiring is declared in exactly one place.
|
|
35
|
+
*/
|
|
36
|
+
const brokerAuthOptionSchema = z.object({
|
|
37
|
+
secretKey: z.string().min(1).default("api-key"),
|
|
38
|
+
secretName: z.string().min(1),
|
|
39
|
+
url: z.string().min(1).default(DEFAULT_BROKER_URL)
|
|
40
|
+
}).strict();
|
|
41
|
+
/**
|
|
42
|
+
* Resolve broker credentials from the environment, or `undefined` when the
|
|
43
|
+
* runner is not broker-authenticated (local dev, non-broker fallback). The
|
|
44
|
+
* `BROKER_URL` env is optional and defaults to the production broker origin.
|
|
45
|
+
*/
|
|
46
|
+
function resolveBrokerCredentials(env = process.env) {
|
|
47
|
+
const apiKey = env[BROKER_API_KEY_ENV];
|
|
48
|
+
if (apiKey === void 0 || apiKey.length === 0) return;
|
|
49
|
+
const rawUrl = env[BROKER_URL_ENV];
|
|
50
|
+
return {
|
|
51
|
+
apiKey,
|
|
52
|
+
baseUrl: rawUrl !== void 0 && rawUrl.length > 0 ? rawUrl.replace(TRAILING_SLASH_RE, "") : DEFAULT_BROKER_URL
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** The broker's OpenAI-compatible endpoint (`<baseUrl>/v1`). */
|
|
56
|
+
function brokerV1Url(credentials) {
|
|
57
|
+
return `${credentials.baseUrl}/v1`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* opencode host auth store contents for broker mode — the `openai` provider
|
|
61
|
+
* authenticates with the broker api-key. Other providers in an existing store
|
|
62
|
+
* are intentionally NOT preserved here: in broker mode the runner owns this
|
|
63
|
+
* file outright (the multi-auth pool that previously populated it is gone).
|
|
64
|
+
*/
|
|
65
|
+
function renderOpencodeBrokerAuthJson(credentials) {
|
|
66
|
+
return formatJson({ [OPENCODE_OPENAI_PROVIDER_ID]: {
|
|
67
|
+
key: credentials.apiKey,
|
|
68
|
+
type: "api"
|
|
69
|
+
} });
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Inject the codex broker model provider into an existing `config.toml`,
|
|
73
|
+
* preserving every other section. Idempotent: re-running replaces the
|
|
74
|
+
* `[model_providers.broker]` block and the top-level `model_provider` key.
|
|
75
|
+
*/
|
|
76
|
+
function applyCodexBrokerProvider(currentText, credentials) {
|
|
77
|
+
const withoutProvider = removeCodexBrokerSections(currentText ?? "");
|
|
78
|
+
const projection = renderCodexBrokerProvider(credentials);
|
|
79
|
+
return ensureTrailingNewline([withoutProvider.trimEnd(), projection.trimEnd()].filter(Boolean).join("\n\n"));
|
|
80
|
+
}
|
|
81
|
+
function renderCodexBrokerProvider(credentials) {
|
|
82
|
+
return [
|
|
83
|
+
`model_provider = "${CODEX_BROKER_PROVIDER_ID}"`,
|
|
84
|
+
"",
|
|
85
|
+
`[model_providers.${CODEX_BROKER_PROVIDER_ID}]`,
|
|
86
|
+
`name = "${CODEX_BROKER_PROVIDER_ID}"`,
|
|
87
|
+
`base_url = "${brokerV1Url(credentials)}"`,
|
|
88
|
+
`env_key = "${BROKER_API_KEY_ENV}"`,
|
|
89
|
+
"wire_api = \"responses\""
|
|
90
|
+
].join("\n");
|
|
91
|
+
}
|
|
92
|
+
const CODEX_BROKER_SECTION_HEADER = `[model_providers.${CODEX_BROKER_PROVIDER_ID}]`;
|
|
93
|
+
const CODEX_MODEL_PROVIDER_KEY_RE = /^\s*model_provider\s*=/;
|
|
94
|
+
function removeCodexBrokerSections(content) {
|
|
95
|
+
const lines = content.split("\n");
|
|
96
|
+
const kept = [];
|
|
97
|
+
let removing = false;
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
if (line.trim() === CODEX_BROKER_SECTION_HEADER) {
|
|
100
|
+
removing = true;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (removing && isTomlSectionHeader(line)) removing = false;
|
|
104
|
+
if (removing) continue;
|
|
105
|
+
if (CODEX_MODEL_PROVIDER_KEY_RE.test(line)) continue;
|
|
106
|
+
kept.push(line);
|
|
107
|
+
}
|
|
108
|
+
return kept.join("\n");
|
|
109
|
+
}
|
|
110
|
+
function isTomlSectionHeader(line) {
|
|
111
|
+
const trimmed = line.trim();
|
|
112
|
+
return trimmed.startsWith("[") && trimmed.endsWith("]");
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Point an opencode config (global or project `opencode.json`) at the broker:
|
|
116
|
+
* set `provider.openai.options.{baseURL,store,include}` and drop the
|
|
117
|
+
* `oc-codex-multi-auth` plugin entry. Preserves all other config (models, mcp,
|
|
118
|
+
* other plugins). Creates a minimal config when `currentText` is undefined.
|
|
119
|
+
*/
|
|
120
|
+
function applyOpencodeBrokerProvider(currentText, credentials) {
|
|
121
|
+
const options = {
|
|
122
|
+
baseURL: brokerV1Url(credentials),
|
|
123
|
+
include: ["reasoning.encrypted_content"],
|
|
124
|
+
store: false
|
|
125
|
+
};
|
|
126
|
+
if (currentText === void 0) return { content: formatJson({
|
|
127
|
+
$schema: "https://opencode.ai/config.json",
|
|
128
|
+
provider: { [OPENCODE_OPENAI_PROVIDER_ID]: { options } }
|
|
129
|
+
}) };
|
|
130
|
+
const parsed = parseJsonRecord(currentText);
|
|
131
|
+
if (!parsed.ok) return { error: "invalid opencode config JSON" };
|
|
132
|
+
const withProvider = applyJsonEdit(currentText, [
|
|
133
|
+
"provider",
|
|
134
|
+
OPENCODE_OPENAI_PROVIDER_ID,
|
|
135
|
+
"options"
|
|
136
|
+
], mergeOpenaiOptions(parsed.value, options));
|
|
137
|
+
const nextPlugins = pluginsWithoutMultiAuth(parsed.value.plugin);
|
|
138
|
+
return { content: ensureTrailingNewline(nextPlugins === void 0 ? withProvider : applyJsonEdit(withProvider, ["plugin"], nextPlugins)) };
|
|
139
|
+
}
|
|
140
|
+
function mergeOpenaiOptions(parsed, options) {
|
|
141
|
+
return {
|
|
142
|
+
...currentOpenaiOptions(parsed),
|
|
143
|
+
...options
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function currentOpenaiOptions(parsed) {
|
|
147
|
+
const provider = parsed.provider;
|
|
148
|
+
if (!isRecord(provider)) return {};
|
|
149
|
+
const openai = provider[OPENCODE_OPENAI_PROVIDER_ID];
|
|
150
|
+
if (!isRecord(openai)) return {};
|
|
151
|
+
return isRecord(openai.options) ? openai.options : {};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Return the plugin array with every `oc-codex-multi-auth` entry removed, or
|
|
155
|
+
* `undefined` when there was nothing to remove (so the caller can skip the
|
|
156
|
+
* edit). Handles bare-string and `[name, opts]` tuple plugin specifiers.
|
|
157
|
+
*/
|
|
158
|
+
function pluginsWithoutMultiAuth(plugin) {
|
|
159
|
+
if (!Array.isArray(plugin)) return;
|
|
160
|
+
const filtered = plugin.filter((entry) => !isMultiAuthPlugin(entry));
|
|
161
|
+
return filtered.length === plugin.length ? void 0 : filtered;
|
|
162
|
+
}
|
|
163
|
+
function isMultiAuthPlugin(entry) {
|
|
164
|
+
const specifier = Array.isArray(entry) ? entry[0] : entry;
|
|
165
|
+
if (typeof specifier !== "string") return false;
|
|
166
|
+
return (specifier.indexOf("@", 1) === -1 ? specifier : specifier.slice(0, specifier.indexOf("@", 1))) === OC_CODEX_MULTI_AUTH_PLUGIN_NAME;
|
|
167
|
+
}
|
|
168
|
+
function isRecord(value) {
|
|
169
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
export { applyCodexBrokerProvider, applyOpencodeBrokerProvider, brokerAuthOptionSchema, renderOpencodeBrokerAuthJson, resolveBrokerCredentials };
|
package/dist/cli/program.js
CHANGED
|
@@ -415,6 +415,7 @@ function buildLoopSubmitInput(options) {
|
|
|
415
415
|
githubAuthSecretName: momokaya?.submit.githubAuthSecretName,
|
|
416
416
|
kubeconfigPath: momokaya?.kubernetes.kubeconfig,
|
|
417
417
|
namespace: momokaya?.kubernetes.namespace,
|
|
418
|
+
brokerAuth: momokaya?.submit.brokerAuth,
|
|
418
419
|
opencodeAuthSecretName: momokaya?.submit.opencodeAuthSecretName,
|
|
419
420
|
opencodeOpenaiAccountsSecretName: momokaya?.submit.opencodeOpenaiAccountsSecretName,
|
|
420
421
|
serviceAccountName: momokaya?.submit.serviceAccountName,
|
|
@@ -48,6 +48,7 @@ function mokaCommonSubmitOptions(input) {
|
|
|
48
48
|
kubeconfigPath: input.flags.kubeconfig ?? momokaya?.kubernetes.kubeconfig,
|
|
49
49
|
name: input.flags.name,
|
|
50
50
|
namespace: input.flags.namespace ?? momokaya?.kubernetes.namespace,
|
|
51
|
+
brokerAuth: momokaya?.submit.brokerAuth,
|
|
51
52
|
opencodeAuthSecretName: momokaya?.submit.opencodeAuthSecretName,
|
|
52
53
|
opencodeOpenaiAccountsSecretName: momokaya?.submit.opencodeOpenaiAccountsSecretName,
|
|
53
54
|
serviceAccountName: input.flags.serviceAccount ?? momokaya?.submit.serviceAccountName,
|
package/dist/cluster-doctor.js
CHANGED
|
@@ -62,19 +62,21 @@ function clusterResources() {
|
|
|
62
62
|
const configured = loadMokaGlobalConfig()?.momokaya.submit;
|
|
63
63
|
return configured ? {
|
|
64
64
|
...DEFAULT_RESOURCES,
|
|
65
|
+
brokerAuthSecretName: configured.brokerAuth?.secretName,
|
|
65
66
|
eventAuthSecretName: configured.eventAuthSecretName,
|
|
66
67
|
gitCredentialsSecretName: configured.gitCredentialsSecretName,
|
|
67
68
|
githubAuthSecretName: configured.githubAuthSecretName,
|
|
68
69
|
imagePullSecretName: configured.imagePullSecretName,
|
|
69
|
-
opencodeAuthSecretName: configured.opencodeAuthSecretName,
|
|
70
|
+
opencodeAuthSecretName: configured.opencodeAuthSecretName ?? DEFAULT_RESOURCES.opencodeAuthSecretName,
|
|
70
71
|
serviceAccountName: configured.serviceAccountName
|
|
71
72
|
} : DEFAULT_RESOURCES;
|
|
72
73
|
}
|
|
73
74
|
function secretChecks(namespace, kubectlOptions, resources) {
|
|
75
|
+
const authSecretCheck = resources.brokerAuthSecretName ? [resources.brokerAuthSecretName, `Secret ${resources.brokerAuthSecretName} missing in ${namespace}; expected broker api-key mount by name.`] : [resources.opencodeAuthSecretName, `Secret ${resources.opencodeAuthSecretName} missing in ${namespace}; expected OpenCode auth mount by name.`];
|
|
74
76
|
return [
|
|
75
77
|
[resources.eventAuthSecretName, eventAuthMissingDetail(namespace)],
|
|
76
78
|
[resources.imagePullSecretName, `Secret ${resources.imagePullSecretName} missing in ${namespace}; expected imagePullSecret for ghcr.io/oisin-ee/pipeline-runner.`],
|
|
77
|
-
|
|
79
|
+
authSecretCheck,
|
|
78
80
|
[resources.gitCredentialsSecretName, `Secret ${resources.gitCredentialsSecretName} missing in ${namespace}; expected runner git credentials mount by name.`],
|
|
79
81
|
[resources.githubAuthSecretName, `Secret ${resources.githubAuthSecretName} missing in ${namespace}; expected GitHub auth mount by name.`]
|
|
80
82
|
].map(([name, missingDetail]) => checkNamespacedResource(`secret/${name}`, [
|
package/dist/codex-auth-sync.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyOpencodeBrokerProvider, resolveBrokerCredentials } from "./broker-auth.js";
|
|
1
2
|
import { mergeOpenCodeProjectConfig } from "./opencode-project-config.js";
|
|
2
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { homedir } from "node:os";
|
|
@@ -7,7 +8,8 @@ import { parse } from "jsonc-parser";
|
|
|
7
8
|
const CODEX_MULTI_AUTH_PLUGIN = "oc-codex-multi-auth@6.3.2";
|
|
8
9
|
const GLOBAL_CODEX_AUTH_CONFIG_PATH = join(homedir(), ".opencode/openai-codex-auth-config.json");
|
|
9
10
|
function syncLocalCodexAuth(options) {
|
|
10
|
-
const
|
|
11
|
+
const broker = options.broker === void 0 ? resolveBrokerCredentials() : options.broker;
|
|
12
|
+
const items = broker ? discoverGitRepositories(options.root).map((repo) => syncProjectBrokerConfig(repo, broker, options)) : [syncGlobalPluginConfig(options.globalConfigPath ?? GLOBAL_CODEX_AUTH_CONFIG_PATH, options), ...discoverGitRepositories(options.root).map((repo) => syncProjectOpenCodeConfig(repo, options))];
|
|
11
13
|
const hasRequiredChanges = items.some((item) => item.action === "create" || item.action === "update");
|
|
12
14
|
const hasErrors = items.some((item) => item.action === "error");
|
|
13
15
|
const checkFailed = options.check === true && hasRequiredChanges;
|
|
@@ -48,6 +50,17 @@ function syncProjectOpenCodeConfig(repo, options) {
|
|
|
48
50
|
};
|
|
49
51
|
return writeIfChanged(path, currentText, merged.content, options);
|
|
50
52
|
}
|
|
53
|
+
function syncProjectBrokerConfig(repo, broker, options) {
|
|
54
|
+
const path = join(repo, ".opencode/opencode.json");
|
|
55
|
+
const currentText = existsSync(path) ? readFileSync(path, "utf8") : void 0;
|
|
56
|
+
const result = applyOpencodeBrokerProvider(currentText, broker);
|
|
57
|
+
if ("error" in result) return {
|
|
58
|
+
action: "error",
|
|
59
|
+
message: result.error,
|
|
60
|
+
path
|
|
61
|
+
};
|
|
62
|
+
return writeIfChanged(path, currentText, result.content, options);
|
|
63
|
+
}
|
|
51
64
|
function writeIfChanged(path, currentText, nextText, options) {
|
|
52
65
|
if (currentText === nextText) return {
|
|
53
66
|
action: "unchanged",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { CLAUDE_PROJECT_CONFIG_PATH, commandIdForHost, compactLines, entrypointDescription, entrypointEntries, instructionsPointer, invocationForHost } from "./shared.js";
|
|
1
2
|
import { opencodeAgentName } from "../runtime/opencode-agent-name.js";
|
|
2
3
|
import { mergeClaudeSettings } from "../claude-settings-config.js";
|
|
3
|
-
import { CLAUDE_PROJECT_CONFIG_PATH, commandIdForHost, compactLines, entrypointDescription, entrypointEntries, instructionsPointer, invocationForHost } from "./shared.js";
|
|
4
4
|
import { agentDispatchRoutes, entrypointDispatchBlock, grants, header, markdown, projectAgentsMdDefinition, resolvedHostModel } from "./opencode.js";
|
|
5
5
|
//#region src/install-commands/claude-code.ts
|
|
6
6
|
const CLAUDE_CODE_HOST = "claude-code";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AGENTS_MD_END, AGENTS_MD_START, COMMAND_HOSTS, GENERATED_MARKER, GENERATED_TS_MARKER, OPENCODE_PROJECT_CONFIG_PATH, OWNER_MARKER_PREFIX, OWNER_TS_MARKER_PREFIX, SINGLE_OPENCODE_PLUGIN_ARRAY_RE, commandIdForHost, compactLines, entrypointDescription, entrypointEntries, instructionsPointer, invocationForHost, profileEntries } from "./shared.js";
|
|
1
2
|
import { DEFAULT_OPENCODE_ECOSYSTEM_MANIFEST } from "../config/defaults.js";
|
|
2
3
|
import { resolvePackageAssetPath } from "../package-assets.js";
|
|
3
4
|
import "../config.js";
|
|
@@ -6,7 +7,6 @@ import { renderOpenCodeGatewayConfig } from "../mcp/gateway.js";
|
|
|
6
7
|
import { compileWorkflowPlan } from "../planning/compile.js";
|
|
7
8
|
import { opencodeAgentName } from "../runtime/opencode-agent-name.js";
|
|
8
9
|
import { mergeOpenCodeProjectConfig } from "../opencode-project-config.js";
|
|
9
|
-
import { AGENTS_MD_END, AGENTS_MD_START, COMMAND_HOSTS, GENERATED_MARKER, GENERATED_TS_MARKER, OPENCODE_PROJECT_CONFIG_PATH, OWNER_MARKER_PREFIX, OWNER_TS_MARKER_PREFIX, SINGLE_OPENCODE_PLUGIN_ARRAY_RE, commandIdForHost, compactLines, entrypointDescription, entrypointEntries, instructionsPointer, invocationForHost, profileEntries } from "./shared.js";
|
|
10
10
|
import { Effect } from "effect";
|
|
11
11
|
import { basename } from "node:path";
|
|
12
12
|
import matter from "gray-matter";
|
package/dist/install-commands.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { isRecord } from "./json-config-merge.js";
|
|
2
|
+
import { CLAUDE_USER_CONFIG_PATH, CODEX_CONFIG_PATH, COMMAND_HOSTS, ENTRYPOINT_PATH_PATTERNS, INSTALL_HOSTS, invocationForHost, resolveHarnessTarget } from "./install-commands/shared.js";
|
|
1
3
|
import { loadPipelineConfig } from "./config/load.js";
|
|
2
4
|
import "./config.js";
|
|
3
|
-
import { isRecord } from "./json-config-merge.js";
|
|
4
5
|
import { mergeClaudeUserConfig } from "./claude-user-config.js";
|
|
5
6
|
import { mergeCodexConfig } from "./codex-config.js";
|
|
6
7
|
import { renderClaudeGatewayUserConfig, renderCodexGatewayConfig } from "./mcp/gateway.js";
|
|
7
|
-
import { CLAUDE_USER_CONFIG_PATH, CODEX_CONFIG_PATH, COMMAND_HOSTS, ENTRYPOINT_PATH_PATTERNS, INSTALL_HOSTS, invocationForHost, resolveHarnessTarget } from "./install-commands/shared.js";
|
|
8
8
|
import { opencodeAdapter } from "./install-commands/opencode.js";
|
|
9
9
|
import { claudeCodeAdapter } from "./install-commands/claude-code.js";
|
|
10
10
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
package/dist/install-hooks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { applyJsonEdit, ensureTrailingNewline, parseJsonRecord } from "./json-config-merge.js";
|
|
2
|
-
import { AGENT_ASSET_SOURCE, AGENT_HOOKS_DIR } from "./agent-assets.js";
|
|
3
2
|
import { resolveHarnessTarget } from "./install-commands/shared.js";
|
|
3
|
+
import { AGENT_ASSET_SOURCE, AGENT_HOOKS_DIR } from "./agent-assets.js";
|
|
4
4
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { dirname, join, relative } from "node:path";
|
|
@@ -80,6 +80,7 @@ function loopControllerSubmitInput(input) {
|
|
|
80
80
|
image: input.image,
|
|
81
81
|
kubeconfigPath: input.kubeconfigPath,
|
|
82
82
|
namespace: input.namespace,
|
|
83
|
+
brokerAuth: input.brokerAuth,
|
|
83
84
|
opencodeAuthSecretName: input.opencodeAuthSecretName,
|
|
84
85
|
opencodeOpenaiAccountsSecretName: input.opencodeOpenaiAccountsSecretName,
|
|
85
86
|
serviceAccountName: input.serviceAccountName,
|
|
@@ -9,13 +9,18 @@ declare const mokaGlobalConfigSchema: z.ZodObject<{
|
|
|
9
9
|
namespace: z.ZodString;
|
|
10
10
|
}, z.core.$strict>;
|
|
11
11
|
submit: z.ZodObject<{
|
|
12
|
+
brokerAuth: z.ZodOptional<z.ZodObject<{
|
|
13
|
+
secretKey: z.ZodDefault<z.ZodString>;
|
|
14
|
+
secretName: z.ZodString;
|
|
15
|
+
url: z.ZodDefault<z.ZodString>;
|
|
16
|
+
}, z.core.$strict>>;
|
|
12
17
|
eventAuthSecretKey: z.ZodString;
|
|
13
18
|
eventAuthSecretName: z.ZodString;
|
|
14
19
|
eventUrl: z.ZodString;
|
|
15
20
|
gitCredentialsSecretName: z.ZodString;
|
|
16
21
|
githubAuthSecretName: z.ZodString;
|
|
17
22
|
imagePullSecretName: z.ZodString;
|
|
18
|
-
opencodeAuthSecretName: z.ZodString
|
|
23
|
+
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
19
24
|
opencodeOpenaiAccountsSecretName: z.ZodOptional<z.ZodString>;
|
|
20
25
|
serviceAccountName: z.ZodString;
|
|
21
26
|
}, z.core.$strict>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { brokerAuthOptionSchema } from "./broker-auth.js";
|
|
1
2
|
import { PipelineConfigError } from "./config/schemas.js";
|
|
2
3
|
import { ConfigIoService, runConfigIoSync } from "./runtime/services/config-io-service.js";
|
|
3
4
|
import "./config.js";
|
|
@@ -8,13 +9,14 @@ import { join } from "node:path";
|
|
|
8
9
|
//#region src/moka-global-config.ts
|
|
9
10
|
const MOKA_GLOBAL_CONFIG_PATH = ".config/moka/config.yaml";
|
|
10
11
|
const mokaSubmitGlobalConfigSchema = z.object({
|
|
12
|
+
brokerAuth: brokerAuthOptionSchema.optional(),
|
|
11
13
|
eventAuthSecretKey: z.string().min(1),
|
|
12
14
|
eventAuthSecretName: z.string().min(1),
|
|
13
15
|
eventUrl: z.string().url(),
|
|
14
16
|
gitCredentialsSecretName: z.string().min(1),
|
|
15
17
|
githubAuthSecretName: z.string().min(1),
|
|
16
18
|
imagePullSecretName: z.string().min(1),
|
|
17
|
-
opencodeAuthSecretName: z.string().min(1),
|
|
19
|
+
opencodeAuthSecretName: z.string().min(1).optional(),
|
|
18
20
|
opencodeOpenaiAccountsSecretName: z.string().min(1).optional(),
|
|
19
21
|
serviceAccountName: z.string().min(1)
|
|
20
22
|
}).strict();
|
package/dist/moka-submit.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PipelineConfig } from "./config/schemas.js";
|
|
2
|
+
import { BrokerAuthOption } from "./broker-auth.js";
|
|
2
3
|
import { generateScheduleArtifact } from "./planning/generate.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
|
|
@@ -151,6 +152,11 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
151
152
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
152
153
|
name: z.ZodOptional<z.ZodString>;
|
|
153
154
|
namespace: z.ZodOptional<z.ZodString>;
|
|
155
|
+
brokerAuth: z.ZodOptional<z.ZodObject<{
|
|
156
|
+
secretKey: z.ZodDefault<z.ZodString>;
|
|
157
|
+
secretName: z.ZodString;
|
|
158
|
+
url: z.ZodDefault<z.ZodString>;
|
|
159
|
+
}, z.core.$strict>>;
|
|
154
160
|
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
155
161
|
opencodeOpenaiAccountsSecretName: z.ZodOptional<z.ZodString>;
|
|
156
162
|
repository: z.ZodOptional<z.ZodObject<{
|
|
@@ -269,6 +275,11 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
269
275
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
270
276
|
name: z.ZodOptional<z.ZodString>;
|
|
271
277
|
namespace: z.ZodOptional<z.ZodString>;
|
|
278
|
+
brokerAuth: z.ZodOptional<z.ZodObject<{
|
|
279
|
+
secretKey: z.ZodDefault<z.ZodString>;
|
|
280
|
+
secretName: z.ZodString;
|
|
281
|
+
url: z.ZodDefault<z.ZodString>;
|
|
282
|
+
}, z.core.$strict>>;
|
|
272
283
|
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
273
284
|
opencodeOpenaiAccountsSecretName: z.ZodOptional<z.ZodString>;
|
|
274
285
|
repository: z.ZodOptional<z.ZodObject<{
|
|
@@ -323,6 +334,7 @@ interface SubmitMokaDependencies {
|
|
|
323
334
|
submitWorkflow?: (options: MokaWorkflowSubmitOptions) => Promise<MokaSubmitOutput>;
|
|
324
335
|
}
|
|
325
336
|
interface MokaWorkflowSubmitOptions {
|
|
337
|
+
brokerAuth?: BrokerAuthOption;
|
|
326
338
|
config: PipelineConfig;
|
|
327
339
|
eventAuthSecretKey?: string;
|
|
328
340
|
eventAuthSecretName?: string;
|
package/dist/moka-submit.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { brokerAuthOptionSchema } from "./broker-auth.js";
|
|
1
2
|
import { buildRunnerCommandPayload, runnerDeliverySchema, runnerHookPolicySchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskSchema } from "./runner-command-contract.js";
|
|
2
3
|
import { normalizeRunnerRepositoryForSubmit } from "./git-remote-url.js";
|
|
3
4
|
import { compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact } from "./planning/generate.js";
|
|
@@ -80,6 +81,7 @@ const mokaSubmitBaseOptionsSchema = z.object({
|
|
|
80
81
|
kubeconfigPath: z.string().min(1).optional(),
|
|
81
82
|
name: z.string().min(1).optional(),
|
|
82
83
|
namespace: z.string().min(1).optional(),
|
|
84
|
+
brokerAuth: brokerAuthOptionSchema.optional(),
|
|
83
85
|
opencodeAuthSecretName: z.string().min(1).optional(),
|
|
84
86
|
opencodeOpenaiAccountsSecretName: z.string().min(1).optional(),
|
|
85
87
|
repository: runnerRepositoryContextSchema.optional(),
|
|
@@ -305,6 +307,7 @@ function workflowSubmitOptions(options) {
|
|
|
305
307
|
kubeconfigPath: options.kubeconfigPath,
|
|
306
308
|
name: options.name,
|
|
307
309
|
namespace: requireSubmitOption(options.namespace, "namespace"),
|
|
310
|
+
brokerAuth: options.brokerAuth,
|
|
308
311
|
opencodeAuthSecretName: options.opencodeAuthSecretName,
|
|
309
312
|
opencodeOpenaiAccountsSecretName: options.opencodeOpenaiAccountsSecretName,
|
|
310
313
|
serviceAccountName: options.serviceAccountName
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { applyCodexBrokerProvider, applyOpencodeBrokerProvider, renderOpencodeBrokerAuthJson, resolveBrokerCredentials } from "../broker-auth.js";
|
|
2
|
+
import { resolveHarnessTarget } from "../install-commands/shared.js";
|
|
1
3
|
import { isRecord } from "../safe-json.js";
|
|
2
4
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
5
|
import { homedir } from "node:os";
|
|
@@ -21,12 +23,51 @@ const WRITABLE_OPENCODE_CREDENTIAL_FILES = [{
|
|
|
21
23
|
stagedPath: join(OPENCODE_AUTH_STAGING_DIR, AUTH_FILE_NAME)
|
|
22
24
|
}];
|
|
23
25
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* Prepare codex + opencode runner credentials. In broker mode, writes the
|
|
27
|
+
* broker provider config and api-key and skips the legacy pool staging. In
|
|
28
|
+
* legacy mode, copies each staged secret to its writable live path and syncs
|
|
29
|
+
* the pool's active openai token into auth.json.
|
|
28
30
|
*/
|
|
29
31
|
function prepareOpencodeCredentials(options = {}) {
|
|
32
|
+
const broker = options.broker === void 0 ? resolveBrokerCredentials() : options.broker;
|
|
33
|
+
if (broker) return {
|
|
34
|
+
brokerConfigured: configureBrokerCredentials(broker, options.brokerPaths),
|
|
35
|
+
copied: [],
|
|
36
|
+
hostOpenaiTokenSynced: false
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
brokerConfigured: [],
|
|
40
|
+
...prepareLegacyPoolCredentials(options)
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function defaultBrokerConfigPaths() {
|
|
44
|
+
return {
|
|
45
|
+
codexConfigPath: resolveHarnessTarget(".codex/config.toml"),
|
|
46
|
+
opencodeAuthPath: join(homedir(), ".local", "share", "opencode", AUTH_FILE_NAME),
|
|
47
|
+
opencodeConfigPath: resolveHarnessTarget(".opencode/opencode.json")
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function configureBrokerCredentials(broker, pathsOverride) {
|
|
51
|
+
const paths = pathsOverride ?? defaultBrokerConfigPaths();
|
|
52
|
+
const configured = [];
|
|
53
|
+
writeFileEnsured(paths.opencodeAuthPath, renderOpencodeBrokerAuthJson(broker), 384);
|
|
54
|
+
configured.push(basename(paths.opencodeAuthPath));
|
|
55
|
+
writeFileEnsured(paths.codexConfigPath, applyCodexBrokerProvider(readIfExists(paths.codexConfigPath), broker));
|
|
56
|
+
configured.push(basename(paths.codexConfigPath));
|
|
57
|
+
const opencodeConfig = applyOpencodeBrokerProvider(readIfExists(paths.opencodeConfigPath), broker);
|
|
58
|
+
if ("error" in opencodeConfig) throw new Error(`Cannot configure opencode broker provider: ${opencodeConfig.error}`);
|
|
59
|
+
writeFileEnsured(paths.opencodeConfigPath, opencodeConfig.content);
|
|
60
|
+
configured.push(basename(paths.opencodeConfigPath));
|
|
61
|
+
return configured;
|
|
62
|
+
}
|
|
63
|
+
function readIfExists(path) {
|
|
64
|
+
return existsSync(path) ? readFileSync(path, "utf8") : void 0;
|
|
65
|
+
}
|
|
66
|
+
function writeFileEnsured(path, content, mode) {
|
|
67
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
68
|
+
writeFileSync(path, content, mode === void 0 ? void 0 : { mode });
|
|
69
|
+
}
|
|
70
|
+
function prepareLegacyPoolCredentials(options) {
|
|
30
71
|
const home = homedir();
|
|
31
72
|
const files = options.files ?? WRITABLE_OPENCODE_CREDENTIAL_FILES.map((file) => ({
|
|
32
73
|
destPath: join(home, ...file.destFromHome),
|
|
@@ -106,6 +106,7 @@ function runRunnerCommandEffect(options, runtime) {
|
|
|
106
106
|
}, "opencode.credentials.prepare start");
|
|
107
107
|
const credentialsPrep = yield* io.prepareOpencodeCredentials();
|
|
108
108
|
logger.info({
|
|
109
|
+
brokerConfigured: credentialsPrep.brokerConfigured,
|
|
109
110
|
copied: credentialsPrep.copied,
|
|
110
111
|
hostOpenaiTokenSynced: credentialsPrep.hostOpenaiTokenSynced,
|
|
111
112
|
phase: "opencode.credentials.prepare",
|
package/package.json
CHANGED
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"prepack": "bun run build:cli"
|
|
129
129
|
},
|
|
130
130
|
"type": "module",
|
|
131
|
-
"version": "3.
|
|
131
|
+
"version": "3.13.0",
|
|
132
132
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
133
133
|
"main": "./dist/index.js",
|
|
134
134
|
"types": "./dist/index.d.ts",
|