@wrenai/genbi 0.0.1
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/LICENSE +201 -0
- package/README.md +141 -0
- package/bin/genbi.mjs +31 -0
- package/dist/assets/echarts-LTFC-ysd.js +40 -0
- package/dist/assets/index-Bo--QMUN.js +441 -0
- package/dist/assets/index-Xs4q7pNo.css +1 -0
- package/dist/index.html +14 -0
- package/dist/wrenai_logo.png +0 -0
- package/dist/wrenai_logo_white.png +0 -0
- package/dist-server/harness/auth/detect.d.ts +18 -0
- package/dist-server/harness/auth/detect.js +37 -0
- package/dist-server/harness/auth/index.d.ts +4 -0
- package/dist-server/harness/auth/index.js +2 -0
- package/dist-server/harness/auth/probe.d.ts +18 -0
- package/dist-server/harness/auth/probe.js +52 -0
- package/dist-server/harness/auth/types.d.ts +42 -0
- package/dist-server/harness/auth/types.js +9 -0
- package/dist-server/harness/bundle/loader.d.ts +32 -0
- package/dist-server/harness/bundle/loader.js +43 -0
- package/dist-server/harness/bundle/schema.d.ts +199 -0
- package/dist-server/harness/bundle/schema.js +127 -0
- package/dist-server/harness/bundle/version.d.ts +10 -0
- package/dist-server/harness/bundle/version.js +43 -0
- package/dist-server/harness/capability/gate.d.ts +6 -0
- package/dist-server/harness/capability/gate.js +29 -0
- package/dist-server/harness/capability/registry.d.ts +6 -0
- package/dist-server/harness/capability/registry.js +17 -0
- package/dist-server/harness/cli-args.d.ts +123 -0
- package/dist-server/harness/cli-args.js +247 -0
- package/dist-server/harness/cli.d.ts +2 -0
- package/dist-server/harness/cli.js +151 -0
- package/dist-server/harness/compile/cache.d.ts +23 -0
- package/dist-server/harness/compile/cache.js +109 -0
- package/dist-server/harness/compile/compose-profile.d.ts +34 -0
- package/dist-server/harness/compile/compose-profile.js +95 -0
- package/dist-server/harness/compile/errors.d.ts +22 -0
- package/dist-server/harness/compile/errors.js +41 -0
- package/dist-server/harness/compile/fingerprint.d.ts +22 -0
- package/dist-server/harness/compile/fingerprint.js +84 -0
- package/dist-server/harness/compile/index.d.ts +8 -0
- package/dist-server/harness/compile/index.js +7 -0
- package/dist-server/harness/compile/pipeline.d.ts +66 -0
- package/dist-server/harness/compile/pipeline.js +176 -0
- package/dist-server/harness/compile/resolve-binary.d.ts +55 -0
- package/dist-server/harness/compile/resolve-binary.js +133 -0
- package/dist-server/harness/compile/types.d.ts +107 -0
- package/dist-server/harness/compile/types.js +1 -0
- package/dist-server/harness/compile/warble-identity.d.ts +12 -0
- package/dist-server/harness/compile/warble-identity.js +33 -0
- package/dist-server/harness/compliance/gate.d.ts +35 -0
- package/dist-server/harness/compliance/gate.js +48 -0
- package/dist-server/harness/compliance/index.d.ts +2 -0
- package/dist-server/harness/compliance/index.js +1 -0
- package/dist-server/harness/compliance/types.d.ts +16 -0
- package/dist-server/harness/compliance/types.js +1 -0
- package/dist-server/harness/events/emitter.d.ts +34 -0
- package/dist-server/harness/events/emitter.js +25 -0
- package/dist-server/harness/events/index.d.ts +4 -0
- package/dist-server/harness/events/index.js +2 -0
- package/dist-server/harness/events/sse.d.ts +20 -0
- package/dist-server/harness/events/sse.js +48 -0
- package/dist-server/harness/events/types.d.ts +131 -0
- package/dist-server/harness/events/types.js +1 -0
- package/dist-server/harness/exec/errors.d.ts +16 -0
- package/dist-server/harness/exec/errors.js +29 -0
- package/dist-server/harness/exec/index.d.ts +5 -0
- package/dist-server/harness/exec/index.js +2 -0
- package/dist-server/harness/exec/local.d.ts +32 -0
- package/dist-server/harness/exec/local.js +134 -0
- package/dist-server/harness/exec/policy.d.ts +12 -0
- package/dist-server/harness/exec/policy.js +1 -0
- package/dist-server/harness/exec/types.d.ts +63 -0
- package/dist-server/harness/exec/types.js +1 -0
- package/dist-server/harness/guardrails/index.d.ts +2 -0
- package/dist-server/harness/guardrails/index.js +1 -0
- package/dist-server/harness/guardrails/policy.d.ts +45 -0
- package/dist-server/harness/guardrails/policy.js +57 -0
- package/dist-server/harness/index.d.ts +37 -0
- package/dist-server/harness/index.js +19 -0
- package/dist-server/harness/loop/errors.d.ts +53 -0
- package/dist-server/harness/loop/errors.js +72 -0
- package/dist-server/harness/loop/executor.d.ts +123 -0
- package/dist-server/harness/loop/executor.js +380 -0
- package/dist-server/harness/loop/guard.d.ts +16 -0
- package/dist-server/harness/loop/guard.js +1 -0
- package/dist-server/harness/loop/index.d.ts +5 -0
- package/dist-server/harness/loop/index.js +3 -0
- package/dist-server/harness/native-producer/index.d.ts +109 -0
- package/dist-server/harness/native-producer/index.js +302 -0
- package/dist-server/harness/npm-package-resolve.d.ts +28 -0
- package/dist-server/harness/npm-package-resolve.js +47 -0
- package/dist-server/harness/providers/adapters/anthropic.d.ts +7 -0
- package/dist-server/harness/providers/adapters/anthropic.js +6 -0
- package/dist-server/harness/providers/adapters/mock.d.ts +4 -0
- package/dist-server/harness/providers/adapters/mock.js +5 -0
- package/dist-server/harness/providers/adapters/openai-compatible.d.ts +10 -0
- package/dist-server/harness/providers/adapters/openai-compatible.js +10 -0
- package/dist-server/harness/providers/binding.d.ts +23 -0
- package/dist-server/harness/providers/binding.js +13 -0
- package/dist-server/harness/providers/errors.d.ts +6 -0
- package/dist-server/harness/providers/errors.js +12 -0
- package/dist-server/harness/providers/index.d.ts +18 -0
- package/dist-server/harness/providers/index.js +22 -0
- package/dist-server/harness/providers/registry.d.ts +16 -0
- package/dist-server/harness/providers/registry.js +24 -0
- package/dist-server/harness/render/envelope.d.ts +145 -0
- package/dist-server/harness/render/envelope.js +428 -0
- package/dist-server/harness/render/errors.d.ts +33 -0
- package/dist-server/harness/render/errors.js +46 -0
- package/dist-server/harness/render/index.d.ts +5 -0
- package/dist-server/harness/render/index.js +3 -0
- package/dist-server/harness/render/validate.d.ts +13 -0
- package/dist-server/harness/render/validate.js +88 -0
- package/dist-server/harness/route/adapter-spec.d.ts +40 -0
- package/dist-server/harness/route/adapter-spec.js +61 -0
- package/dist-server/harness/route/agent-sdk-cli.d.ts +30 -0
- package/dist-server/harness/route/agent-sdk-cli.js +86 -0
- package/dist-server/harness/route/agent-sdk-manifest.d.ts +31 -0
- package/dist-server/harness/route/agent-sdk-manifest.js +56 -0
- package/dist-server/harness/route/artifact-content.d.ts +53 -0
- package/dist-server/harness/route/artifact-content.js +83 -0
- package/dist-server/harness/route/chat-event-mapper.d.ts +95 -0
- package/dist-server/harness/route/chat-event-mapper.js +164 -0
- package/dist-server/harness/route/codex-ask-events.d.ts +25 -0
- package/dist-server/harness/route/codex-ask-events.js +395 -0
- package/dist-server/harness/route/codex-ask.d.ts +15 -0
- package/dist-server/harness/route/codex-ask.js +242 -0
- package/dist-server/harness/route/codex-local-cli.d.ts +20 -0
- package/dist-server/harness/route/codex-local-cli.js +78 -0
- package/dist-server/harness/route/codex-local-manifest.d.ts +22 -0
- package/dist-server/harness/route/codex-local-manifest.js +180 -0
- package/dist-server/harness/route/describe.d.ts +54 -0
- package/dist-server/harness/route/describe.js +84 -0
- package/dist-server/harness/route/dispatched.d.ts +138 -0
- package/dist-server/harness/route/dispatched.js +339 -0
- package/dist-server/harness/route/in-process.d.ts +43 -0
- package/dist-server/harness/route/in-process.js +106 -0
- package/dist-server/harness/route/index.d.ts +19 -0
- package/dist-server/harness/route/index.js +12 -0
- package/dist-server/harness/route/profile-source.d.ts +37 -0
- package/dist-server/harness/route/profile-source.js +76 -0
- package/dist-server/harness/route/route.d.ts +33 -0
- package/dist-server/harness/route/route.js +114 -0
- package/dist-server/harness/route/tier-binding.d.ts +36 -0
- package/dist-server/harness/route/tier-binding.js +63 -0
- package/dist-server/harness/route/types.d.ts +286 -0
- package/dist-server/harness/route/types.js +1 -0
- package/dist-server/harness/session/errors.d.ts +4 -0
- package/dist-server/harness/session/errors.js +7 -0
- package/dist-server/harness/session/gate.d.ts +11 -0
- package/dist-server/harness/session/gate.js +13 -0
- package/dist-server/harness/session/index.d.ts +5 -0
- package/dist-server/harness/session/index.js +3 -0
- package/dist-server/harness/session/run.d.ts +60 -0
- package/dist-server/harness/session/run.js +333 -0
- package/dist-server/harness/session/types.d.ts +29 -0
- package/dist-server/harness/session/types.js +1 -0
- package/dist-server/harness/setup/codex-events.d.ts +12 -0
- package/dist-server/harness/setup/codex-events.js +108 -0
- package/dist-server/harness/setup/runner.d.ts +497 -0
- package/dist-server/harness/setup/runner.js +1314 -0
- package/dist-server/harness/tools/errors.d.ts +107 -0
- package/dist-server/harness/tools/errors.js +141 -0
- package/dist-server/harness/tools/index.d.ts +13 -0
- package/dist-server/harness/tools/index.js +8 -0
- package/dist-server/harness/tools/mcp.d.ts +26 -0
- package/dist-server/harness/tools/mcp.js +15 -0
- package/dist-server/harness/tools/native.d.ts +179 -0
- package/dist-server/harness/tools/native.js +322 -0
- package/dist-server/harness/tools/parse.d.ts +14 -0
- package/dist-server/harness/tools/parse.js +18 -0
- package/dist-server/harness/tools/resolve-wren-binary.d.ts +12 -0
- package/dist-server/harness/tools/resolve-wren-binary.js +21 -0
- package/dist-server/harness/tools/resolve.d.ts +51 -0
- package/dist-server/harness/tools/resolve.js +79 -0
- package/dist-server/harness/tools/setup-native.d.ts +84 -0
- package/dist-server/harness/tools/setup-native.js +353 -0
- package/dist-server/harness/tools/wiring.d.ts +10 -0
- package/dist-server/harness/tools/wiring.js +16 -0
- package/dist-server/providers/setup.provider.yaml +31 -0
- package/dist-server/providers/wren.provider.yaml +33 -0
- package/dist-server/server/adopt.d.ts +87 -0
- package/dist-server/server/adopt.js +263 -0
- package/dist-server/server/app.d.ts +6 -0
- package/dist-server/server/app.js +2521 -0
- package/dist-server/server/auth-choice.d.ts +16 -0
- package/dist-server/server/auth-choice.js +36 -0
- package/dist-server/server/bin.d.ts +2 -0
- package/dist-server/server/bin.js +601 -0
- package/dist-server/server/bootstrap-project-binding.d.ts +31 -0
- package/dist-server/server/bootstrap-project-binding.js +71 -0
- package/dist-server/server/clarify.d.ts +10 -0
- package/dist-server/server/clarify.js +17 -0
- package/dist-server/server/codex-setup-mcp.d.ts +2 -0
- package/dist-server/server/codex-setup-mcp.js +147 -0
- package/dist-server/server/compose.d.ts +89 -0
- package/dist-server/server/compose.js +271 -0
- package/dist-server/server/conn-config.d.ts +30 -0
- package/dist-server/server/conn-config.js +253 -0
- package/dist-server/server/context-files.d.ts +12 -0
- package/dist-server/server/context-files.js +117 -0
- package/dist-server/server/context-map.d.ts +30 -0
- package/dist-server/server/context-map.js +95 -0
- package/dist-server/server/context-source.d.ts +68 -0
- package/dist-server/server/context-source.js +85 -0
- package/dist-server/server/db.d.ts +862 -0
- package/dist-server/server/db.js +1839 -0
- package/dist-server/server/enrichment-runner.d.ts +184 -0
- package/dist-server/server/enrichment-runner.js +213 -0
- package/dist-server/server/enrichment-verify.d.ts +73 -0
- package/dist-server/server/enrichment-verify.js +290 -0
- package/dist-server/server/enrichment.d.ts +232 -0
- package/dist-server/server/enrichment.js +199 -0
- package/dist-server/server/env-detect.d.ts +8 -0
- package/dist-server/server/env-detect.js +17 -0
- package/dist-server/server/env-field-hints.d.ts +46 -0
- package/dist-server/server/env-field-hints.js +48 -0
- package/dist-server/server/fold.d.ts +133 -0
- package/dist-server/server/fold.js +407 -0
- package/dist-server/server/harness-profile-sources.d.ts +3 -0
- package/dist-server/server/harness-profile-sources.js +24 -0
- package/dist-server/server/harness.d.ts +19 -0
- package/dist-server/server/harness.js +439 -0
- package/dist-server/server/impact.d.ts +18 -0
- package/dist-server/server/impact.js +85 -0
- package/dist-server/server/interactive-terminal.d.ts +175 -0
- package/dist-server/server/interactive-terminal.js +336 -0
- package/dist-server/server/native-artifacts.d.ts +1004 -0
- package/dist-server/server/native-artifacts.js +564 -0
- package/dist-server/server/native-dispatch-registry.d.ts +42 -0
- package/dist-server/server/native-dispatch-registry.js +45 -0
- package/dist-server/server/native-producer-fence.d.ts +14 -0
- package/dist-server/server/native-producer-fence.js +48 -0
- package/dist-server/server/native-session-resume.d.ts +6 -0
- package/dist-server/server/native-session-resume.js +103 -0
- package/dist-server/server/native-session-workspace.d.ts +40 -0
- package/dist-server/server/native-session-workspace.js +175 -0
- package/dist-server/server/native-sessions.d.ts +374 -0
- package/dist-server/server/native-sessions.js +1517 -0
- package/dist-server/server/native-wren-runtime.d.ts +20 -0
- package/dist-server/server/native-wren-runtime.js +259 -0
- package/dist-server/server/node-pty-host.d.ts +31 -0
- package/dist-server/server/node-pty-host.js +100 -0
- package/dist-server/server/route-intent.d.ts +40 -0
- package/dist-server/server/route-intent.js +23 -0
- package/dist-server/server/runtime-binding.d.ts +52 -0
- package/dist-server/server/runtime-binding.js +258 -0
- package/dist-server/server/source-catalog.d.ts +84 -0
- package/dist-server/server/source-catalog.js +221 -0
- package/dist-server/server/source-driver.d.ts +35 -0
- package/dist-server/server/source-driver.js +124 -0
- package/dist-server/server/spa.d.ts +2 -0
- package/dist-server/server/spa.js +51 -0
- package/dist-server/server/subscription-model-catalog.d.ts +27 -0
- package/dist-server/server/subscription-model-catalog.js +203 -0
- package/dist-server/server/turn.d.ts +249 -0
- package/dist-server/server/turn.js +1074 -0
- package/dist-server/server/wire-types.d.ts +799 -0
- package/dist-server/server/wire-types.js +1 -0
- package/dist-server/server/wren-home.d.ts +19 -0
- package/dist-server/server/wren-home.js +33 -0
- package/dist-server/server/wren-profiles.d.ts +43 -0
- package/dist-server/server/wren-profiles.js +123 -0
- package/package.json +93 -0
- package/profiles/genbi-default/context/binding.yml +9 -0
- package/profiles/genbi-default/ir.golden.json +506 -0
- package/profiles/genbi-default/profile.yml +16 -0
- package/profiles/genbi-enrich-context/components/apply_enrichment/component.yml +42 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/component.yml +30 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/steps/draft.md +34 -0
- package/profiles/genbi-enrich-context/components/inspect_context/component.yml +32 -0
- package/profiles/genbi-enrich-context/components/inspect_context/steps/inspect.md +13 -0
- package/profiles/genbi-enrich-context/context/binding.yml +4 -0
- package/profiles/genbi-enrich-context/ir.golden.json +302 -0
- package/profiles/genbi-enrich-context/profile.yml +15 -0
- package/profiles/genbi-monitor/context/binding.yml +7 -0
- package/profiles/genbi-monitor/ir.golden.json +188 -0
- package/profiles/genbi-monitor/profile.yml +27 -0
- package/profiles/genbi-setup/components/build_context/component.yml +44 -0
- package/profiles/genbi-setup/components/build_context/steps/build.md +14 -0
- package/profiles/genbi-setup/components/connect_source/component.yml +51 -0
- package/profiles/genbi-setup/components/connect_source/steps/connect.md +23 -0
- package/profiles/genbi-setup/context/binding.yml +8 -0
- package/profiles/genbi-setup/ir.golden.json +140 -0
- package/profiles/genbi-setup/profile.yml +18 -0
- package/profiles/genbi-setup/raw/schema.json +5 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface NativeWrenRuntime {
|
|
2
|
+
readonly version: "1";
|
|
3
|
+
readonly shim: string;
|
|
4
|
+
readonly launcher: string;
|
|
5
|
+
readonly venv_python: string;
|
|
6
|
+
readonly tool_root: string;
|
|
7
|
+
readonly site_packages: string;
|
|
8
|
+
readonly source_root: string;
|
|
9
|
+
readonly interpreter: string;
|
|
10
|
+
readonly interpreter_root: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class NativeWrenRuntimeError extends Error {
|
|
13
|
+
}
|
|
14
|
+
/** The documented server default; deployments can set an explicit absolute shim path. */
|
|
15
|
+
export declare function defaultNativeWrenShim(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Validates every launcher hop before serializing the exact read/execute
|
|
18
|
+
* closure. The source root comes only from the one editable .pth entry.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveNativeWrenRuntime(configuredShim?: string): NativeWrenRuntime;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the fixed Wren installation that a native Codex session may use.
|
|
3
|
+
* This is BFF configuration, never a browser, request, PATH, or permission
|
|
4
|
+
* input. The returned object is the closed scope shape consumed by Warble.
|
|
5
|
+
*/
|
|
6
|
+
import { accessSync, constants, lstatSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
export class NativeWrenRuntimeError extends Error {
|
|
11
|
+
}
|
|
12
|
+
function unavailable(reason) { throw new NativeWrenRuntimeError(`native Wren runtime is unavailable: ${reason}`); }
|
|
13
|
+
function regularExecutable(file) {
|
|
14
|
+
try {
|
|
15
|
+
const canonical = realpathSync(file);
|
|
16
|
+
const stat = statSync(canonical);
|
|
17
|
+
if (!stat.isFile() || (stat.mode & 0o111) === 0)
|
|
18
|
+
unavailable("shim target is not an executable regular file");
|
|
19
|
+
return canonical;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
23
|
+
throw error;
|
|
24
|
+
return unavailable("shim target could not be stat-ed");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function directory(directory) {
|
|
28
|
+
try {
|
|
29
|
+
const canonical = realpathSync(directory);
|
|
30
|
+
if (!statSync(canonical).isDirectory())
|
|
31
|
+
unavailable("expected a directory");
|
|
32
|
+
accessSync(canonical, constants.R_OK | constants.X_OK);
|
|
33
|
+
return canonical;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
37
|
+
throw error;
|
|
38
|
+
return unavailable("directory could not be resolved");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function contained(root, candidate) {
|
|
42
|
+
const relative = path.relative(root, candidate);
|
|
43
|
+
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
44
|
+
}
|
|
45
|
+
/** Reject symlinks (including symlinked parents) and detect a replacement while reading. */
|
|
46
|
+
function stableRegularFile(file) {
|
|
47
|
+
try {
|
|
48
|
+
const stat = lstatSync(file);
|
|
49
|
+
const canonical = realpathSync(file);
|
|
50
|
+
if (!stat.isFile() || stat.isSymbolicLink() || canonical !== file)
|
|
51
|
+
unavailable("expected a stable regular file, not a symlink or an alias");
|
|
52
|
+
return { canonical, dev: stat.dev, ino: stat.ino, size: stat.size, mtimeMs: stat.mtimeMs, ctimeMs: stat.ctimeMs };
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
56
|
+
throw error;
|
|
57
|
+
return unavailable("file could not be stat-ed");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function stableFileText(file) {
|
|
61
|
+
const before = stableRegularFile(file);
|
|
62
|
+
let text;
|
|
63
|
+
try {
|
|
64
|
+
text = readFileSync(file, "utf8");
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return unavailable("file could not be read");
|
|
68
|
+
}
|
|
69
|
+
const after = stableRegularFile(file);
|
|
70
|
+
if (before.canonical !== after.canonical || before.dev !== after.dev || before.ino !== after.ino ||
|
|
71
|
+
before.size !== after.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs)
|
|
72
|
+
unavailable("file changed while it was being read");
|
|
73
|
+
return text;
|
|
74
|
+
}
|
|
75
|
+
function gitCommonDirectory(repository) {
|
|
76
|
+
const gitEntry = path.join(repository, ".git");
|
|
77
|
+
try {
|
|
78
|
+
const entry = lstatSync(gitEntry);
|
|
79
|
+
if (entry.isSymbolicLink())
|
|
80
|
+
unavailable("git entry is a symlink");
|
|
81
|
+
if (entry.isDirectory())
|
|
82
|
+
return directory(gitEntry);
|
|
83
|
+
if (!entry.isFile())
|
|
84
|
+
unavailable("git entry is not a file");
|
|
85
|
+
const match = /^gitdir: ([^\r\n]+)\r?\n?$/.exec(stableFileText(gitEntry));
|
|
86
|
+
if (!match)
|
|
87
|
+
unavailable("gitdir line did not parse");
|
|
88
|
+
const worktreeGitDir = directory(path.resolve(repository, match[1]));
|
|
89
|
+
const commonDirFile = path.join(worktreeGitDir, "commondir");
|
|
90
|
+
try {
|
|
91
|
+
const commonDir = stableFileText(commonDirFile).trim();
|
|
92
|
+
if (!commonDir)
|
|
93
|
+
unavailable("no common git directory");
|
|
94
|
+
const commonDirectory = directory(path.resolve(worktreeGitDir, commonDir));
|
|
95
|
+
if (!contained(path.join(commonDirectory, "worktrees"), worktreeGitDir))
|
|
96
|
+
unavailable("worktree gitdir escapes the common directory");
|
|
97
|
+
const declaredGitFile = path.resolve(worktreeGitDir, stableFileText(path.join(worktreeGitDir, "gitdir")).trim());
|
|
98
|
+
if (declaredGitFile !== gitEntry)
|
|
99
|
+
unavailable("declared gitdir does not match the entry");
|
|
100
|
+
return commonDirectory;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
104
|
+
throw error;
|
|
105
|
+
return worktreeGitDir;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
110
|
+
throw error;
|
|
111
|
+
return unavailable("git layout could not be inspected");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Finds the repository that shipped this BFF; it is never supplied by a request or environment variable. */
|
|
115
|
+
function serverRepositoryRoot() {
|
|
116
|
+
let candidate = path.dirname(fileURLToPath(import.meta.url));
|
|
117
|
+
while (true) {
|
|
118
|
+
try {
|
|
119
|
+
const repository = directory(candidate);
|
|
120
|
+
stableRegularFile(path.join(repository, "apps", "genbi", "package.json"));
|
|
121
|
+
stableRegularFile(path.join(repository, "core", "wren", "pyproject.toml"));
|
|
122
|
+
return repository;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (error instanceof NativeWrenRuntimeError) {
|
|
126
|
+
const parent = path.dirname(candidate);
|
|
127
|
+
if (parent === candidate)
|
|
128
|
+
return unavailable("walked past the filesystem root looking for a repository");
|
|
129
|
+
candidate = parent;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
return unavailable("repository root could not be found");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* A runtime may use a sibling Git worktree, but never an arbitrary editable
|
|
138
|
+
* directory. Only that worktree's exact core/wren/src root is granted.
|
|
139
|
+
*/
|
|
140
|
+
function approvedWrenSourceRoot(sourceRoot) {
|
|
141
|
+
try {
|
|
142
|
+
const sourceEntry = lstatSync(sourceRoot);
|
|
143
|
+
const canonical = realpathSync(sourceRoot);
|
|
144
|
+
if (!sourceEntry.isDirectory() || sourceEntry.isSymbolicLink() || canonical !== sourceRoot)
|
|
145
|
+
unavailable("source root is not a plain directory");
|
|
146
|
+
const runtimeRepository = directory(path.resolve(sourceRoot, "..", "..", ".."));
|
|
147
|
+
if (sourceRoot !== path.join(runtimeRepository, "core", "wren", "src"))
|
|
148
|
+
unavailable("source root is not core/wren/src");
|
|
149
|
+
stableRegularFile(path.join(runtimeRepository, "core", "wren", "pyproject.toml"));
|
|
150
|
+
stableRegularFile(path.join(sourceRoot, "wren", "__init__.py"));
|
|
151
|
+
if (gitCommonDirectory(runtimeRepository) !== gitCommonDirectory(serverRepositoryRoot()))
|
|
152
|
+
unavailable("source repository differs from the server repository");
|
|
153
|
+
const after = lstatSync(sourceRoot);
|
|
154
|
+
if (!after.isDirectory() || after.isSymbolicLink() || realpathSync(sourceRoot) !== canonical)
|
|
155
|
+
unavailable("source root changed while being checked");
|
|
156
|
+
return canonical;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
160
|
+
throw error;
|
|
161
|
+
return unavailable("source root could not be inspected");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** The documented server default; deployments can set an explicit absolute shim path. */
|
|
165
|
+
export function defaultNativeWrenShim() {
|
|
166
|
+
return path.join(os.homedir(), ".local", "bin", "wren");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Validates every launcher hop before serializing the exact read/execute
|
|
170
|
+
* closure. The source root comes only from the one editable .pth entry.
|
|
171
|
+
*/
|
|
172
|
+
export function resolveNativeWrenRuntime(configuredShim = defaultNativeWrenShim()) {
|
|
173
|
+
if (!path.isAbsolute(configuredShim))
|
|
174
|
+
unavailable("configured shim path is not absolute");
|
|
175
|
+
try {
|
|
176
|
+
const shimEntry = lstatSync(configuredShim);
|
|
177
|
+
if (!shimEntry.isSymbolicLink())
|
|
178
|
+
unavailable("shim is not a symlink");
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
unavailable("shim could not be stat-ed");
|
|
182
|
+
}
|
|
183
|
+
const shim = path.resolve(configuredShim);
|
|
184
|
+
const launcher = regularExecutable(shim);
|
|
185
|
+
const toolRoot = directory(path.dirname(path.dirname(launcher)));
|
|
186
|
+
const toolBin = path.join(toolRoot, "bin");
|
|
187
|
+
const venvPython = path.join(toolBin, "python");
|
|
188
|
+
if (launcher !== path.join(toolBin, "wren"))
|
|
189
|
+
unavailable("shim does not resolve to <tool root>/bin/wren");
|
|
190
|
+
try {
|
|
191
|
+
if (!lstatSync(venvPython).isSymbolicLink())
|
|
192
|
+
unavailable("tool venv python is not a symlink");
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
unavailable("tool venv python could not be stat-ed");
|
|
196
|
+
}
|
|
197
|
+
const interpreter = regularExecutable(venvPython);
|
|
198
|
+
const interpreterRoot = directory(path.dirname(path.dirname(interpreter)));
|
|
199
|
+
const interpreterBin = path.join(interpreterRoot, "bin");
|
|
200
|
+
if (!contained(interpreterBin, interpreter) || interpreter === interpreterBin)
|
|
201
|
+
unavailable("interpreter is not inside its own bin directory");
|
|
202
|
+
directory(path.join(interpreterRoot, "lib"));
|
|
203
|
+
let hasVenvMetadata = false;
|
|
204
|
+
try {
|
|
205
|
+
hasVenvMetadata = statSync(path.join(toolRoot, "pyvenv.cfg")).isFile();
|
|
206
|
+
}
|
|
207
|
+
catch { /* fail below */ }
|
|
208
|
+
if (!hasVenvMetadata)
|
|
209
|
+
unavailable("tool root has no pyvenv.cfg, so it is not a venv");
|
|
210
|
+
let launcherText;
|
|
211
|
+
try {
|
|
212
|
+
launcherText = readFileSync(launcher, "utf8");
|
|
213
|
+
}
|
|
214
|
+
catch { /* fail below */ }
|
|
215
|
+
if (launcherText === undefined || (!launcherText.startsWith(`#!${venvPython}\n`) && !launcherText.startsWith(`#!${venvPython}\r\n`)))
|
|
216
|
+
unavailable("launcher shebang does not point at the tool venv python");
|
|
217
|
+
const toolLib = directory(path.join(toolRoot, "lib"));
|
|
218
|
+
let sitePackages;
|
|
219
|
+
try {
|
|
220
|
+
const candidates = readdirSync(toolLib, { withFileTypes: true })
|
|
221
|
+
.filter((entry) => entry.isDirectory() && /^python\d+(?:\.\d+)?$/.test(entry.name))
|
|
222
|
+
.map((entry) => path.join(toolLib, entry.name, "site-packages"))
|
|
223
|
+
.filter((candidate) => {
|
|
224
|
+
try {
|
|
225
|
+
return statSync(candidate).isDirectory() && stableRegularFile(path.join(candidate, "_editable_impl_wrenai.pth")) !== undefined;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
if (candidates.length !== 1)
|
|
232
|
+
unavailable("expected exactly one lib/python*/site-packages");
|
|
233
|
+
sitePackages = directory(candidates[0]);
|
|
234
|
+
if (!contained(toolLib, sitePackages))
|
|
235
|
+
unavailable("site-packages escapes the tool lib directory");
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
239
|
+
throw error;
|
|
240
|
+
return unavailable("tool lib could not be inspected");
|
|
241
|
+
}
|
|
242
|
+
let sourceRoot;
|
|
243
|
+
try {
|
|
244
|
+
const lines = stableFileText(path.join(sitePackages, "_editable_impl_wrenai.pth"))
|
|
245
|
+
.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
246
|
+
if (lines.length !== 1 || !path.isAbsolute(lines[0]))
|
|
247
|
+
unavailable("pth file did not contain a single absolute path");
|
|
248
|
+
sourceRoot = approvedWrenSourceRoot(lines[0]);
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
if (error instanceof NativeWrenRuntimeError)
|
|
252
|
+
throw error;
|
|
253
|
+
return unavailable("pth file could not be read");
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
version: "1", shim, launcher, venv_python: venvPython, tool_root: toolRoot,
|
|
257
|
+
site_packages: sitePackages, source_root: sourceRoot, interpreter, interpreter_root: interpreterRoot,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type PtyFactory, type PtyProcess } from "./interactive-terminal.js";
|
|
2
|
+
interface NodePtyModule {
|
|
3
|
+
spawn(file: string, args: string[], options: {
|
|
4
|
+
cwd: string;
|
|
5
|
+
cols: number;
|
|
6
|
+
rows: number;
|
|
7
|
+
name: string;
|
|
8
|
+
env: NodeJS.ProcessEnv;
|
|
9
|
+
}): PtyProcess;
|
|
10
|
+
}
|
|
11
|
+
export interface PtyHostOptions {
|
|
12
|
+
readonly cwd?: string;
|
|
13
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
14
|
+
readonly probeExecutable?: string;
|
|
15
|
+
readonly probeTimeoutMs?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* node-pty 1.1 ships a small spawn-helper for prebuilt macOS binaries. Some
|
|
19
|
+
* package managers restore that regular file without its executable mode,
|
|
20
|
+
* making every PTY fork fail with the otherwise opaque `posix_spawnp failed`.
|
|
21
|
+
* Repair only that fixed package-owned helper; a read-only installation will
|
|
22
|
+
* fail closed in the spawn probe below and leave the copy-command fallback.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ensureDarwinNodePtySpawnHelper(nodePtyEntry: string, platform?: NodeJS.Platform, arch?: NodeJS.Architecture): void;
|
|
25
|
+
/**
|
|
26
|
+
* Build the production PTY adapter only after a fixed, no-model Node process
|
|
27
|
+
* successfully starts. Importability alone is not a readiness signal: native
|
|
28
|
+
* helpers can load while process creation is still broken.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createProbedPtyFactory(nodePty: NodePtyModule, options?: PtyHostOptions): Promise<PtyFactory>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { closeSync, constants, fchmodSync, fstatSync, lstatSync, openSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { nativeTerminalEnvironment } from "./interactive-terminal.js";
|
|
4
|
+
/**
|
|
5
|
+
* node-pty 1.1 ships a small spawn-helper for prebuilt macOS binaries. Some
|
|
6
|
+
* package managers restore that regular file without its executable mode,
|
|
7
|
+
* making every PTY fork fail with the otherwise opaque `posix_spawnp failed`.
|
|
8
|
+
* Repair only that fixed package-owned helper; a read-only installation will
|
|
9
|
+
* fail closed in the spawn probe below and leave the copy-command fallback.
|
|
10
|
+
*/
|
|
11
|
+
export function ensureDarwinNodePtySpawnHelper(nodePtyEntry, platform = process.platform, arch = process.arch) {
|
|
12
|
+
if (platform !== "darwin")
|
|
13
|
+
return;
|
|
14
|
+
if (arch !== "arm64" && arch !== "x64")
|
|
15
|
+
throw new Error("node-pty spawn helper is unavailable");
|
|
16
|
+
const entry = path.resolve(nodePtyEntry);
|
|
17
|
+
const packageRoot = path.resolve(path.dirname(entry), "..");
|
|
18
|
+
// node-pty 1.1 has exactly this package entry and helper layout. Do not
|
|
19
|
+
// generalize a permission repair to an arbitrary dependency path.
|
|
20
|
+
if (entry !== path.join(packageRoot, "lib", "index.js")) {
|
|
21
|
+
throw new Error("node-pty spawn helper is unavailable");
|
|
22
|
+
}
|
|
23
|
+
const prebuilds = path.join(packageRoot, "prebuilds");
|
|
24
|
+
const platformPrebuild = path.join(prebuilds, `${platform}-${arch}`);
|
|
25
|
+
const helper = path.join(platformPrebuild, "spawn-helper");
|
|
26
|
+
// lstat never follows a link. Reject every package-owned component before
|
|
27
|
+
// opening the helper so the fixed package path cannot be redirected.
|
|
28
|
+
for (const directory of [packageRoot, prebuilds, platformPrebuild]) {
|
|
29
|
+
if (!lstatSync(directory).isDirectory())
|
|
30
|
+
throw new Error("node-pty spawn helper is unavailable");
|
|
31
|
+
}
|
|
32
|
+
if (!lstatSync(helper).isFile())
|
|
33
|
+
throw new Error("node-pty spawn helper is unavailable");
|
|
34
|
+
// Keep the chmod bound to the opened object, not the path. O_NOFOLLOW and
|
|
35
|
+
// fchmod remove the final-component symlink and replacement race.
|
|
36
|
+
const fd = openSync(helper, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
37
|
+
try {
|
|
38
|
+
const stat = fstatSync(fd);
|
|
39
|
+
if (!stat.isFile())
|
|
40
|
+
throw new Error("node-pty spawn helper is unavailable");
|
|
41
|
+
if ((stat.mode & 0o111) === 0)
|
|
42
|
+
fchmodSync(fd, stat.mode | 0o111);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
closeSync(fd);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build the production PTY adapter only after a fixed, no-model Node process
|
|
50
|
+
* successfully starts. Importability alone is not a readiness signal: native
|
|
51
|
+
* helpers can load while process creation is still broken.
|
|
52
|
+
*/
|
|
53
|
+
export async function createProbedPtyFactory(nodePty, options = {}) {
|
|
54
|
+
const cwd = options.cwd ?? process.cwd();
|
|
55
|
+
const env = nativeTerminalEnvironment(options.env);
|
|
56
|
+
const probeExecutable = options.probeExecutable ?? process.execPath;
|
|
57
|
+
const probeTimeoutMs = options.probeTimeoutMs ?? 2_000;
|
|
58
|
+
let probe;
|
|
59
|
+
try {
|
|
60
|
+
probe = nodePty.spawn(probeExecutable, ["--version"], {
|
|
61
|
+
cwd,
|
|
62
|
+
cols: 80,
|
|
63
|
+
rows: 24,
|
|
64
|
+
name: "xterm-256color",
|
|
65
|
+
env,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
throw new Error("interactive terminal host cannot spawn local processes");
|
|
70
|
+
}
|
|
71
|
+
await new Promise((resolve, reject) => {
|
|
72
|
+
let settled = false;
|
|
73
|
+
const finish = (error) => {
|
|
74
|
+
if (settled)
|
|
75
|
+
return;
|
|
76
|
+
settled = true;
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
if (error)
|
|
79
|
+
reject(error);
|
|
80
|
+
else
|
|
81
|
+
resolve();
|
|
82
|
+
};
|
|
83
|
+
const timer = setTimeout(() => {
|
|
84
|
+
probe.kill();
|
|
85
|
+
finish(new Error("interactive terminal host spawn probe timed out"));
|
|
86
|
+
}, probeTimeoutMs);
|
|
87
|
+
probe.onExit(({ exitCode }) => finish(exitCode === 0 ? undefined : new Error("interactive terminal host spawn probe failed")));
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
spawn: (file, args, spawnOptions) => nodePty.spawn(file, [...args], {
|
|
91
|
+
cwd: spawnOptions.cwd,
|
|
92
|
+
cols: spawnOptions.cols,
|
|
93
|
+
rows: spawnOptions.rows,
|
|
94
|
+
name: "xterm-256color",
|
|
95
|
+
// Defend this lower adapter too: future PTY callers cannot bypass the
|
|
96
|
+
// server-owned native-terminal color contract by supplying an env.
|
|
97
|
+
env: nativeTerminalEnvironment(spawnOptions.env ?? env),
|
|
98
|
+
}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic (no LLM) intent router: picks which compiled
|
|
3
|
+
* agent should serve a question. Mirrors `classifyClarify`'s shape (a plain
|
|
4
|
+
* regex classifier, no dependencies) so intent routing stays exactly as
|
|
5
|
+
* auditable and replay-safe as the clarify pre-flight — same reason: a
|
|
6
|
+
* question's classification must be reproducible on SSE replay without
|
|
7
|
+
* re-invoking any LLM.
|
|
8
|
+
*
|
|
9
|
+
* This function IS the intent taxonomy — extend the regexes
|
|
10
|
+
* here, don't grow a second classification path elsewhere. Rules, in
|
|
11
|
+
* priority order:
|
|
12
|
+
*
|
|
13
|
+
* 1. Explanation intent ("why", "explain", "what caused/drove/led to",
|
|
14
|
+
* "reason", "driver", "because") -> "explain_change" (the narrative
|
|
15
|
+
* bundle agent).
|
|
16
|
+
* 2. Dashboard intent ("dashboard", "chart", "graph", "plot",
|
|
17
|
+
* "visuali[sz]e", "trend", "over time", "breakdown", "by <dimension>")
|
|
18
|
+
* -> "generate_dashboard".
|
|
19
|
+
* 3. Everything else -> "answer_query" (the existing default).
|
|
20
|
+
*
|
|
21
|
+
* Explanation is checked first because a question can plausibly match both
|
|
22
|
+
* ("why did revenue trend down over time?") — explaining the driver is the
|
|
23
|
+
* more specific ask.
|
|
24
|
+
*
|
|
25
|
+
* `availableAgentIds` guards against routing to an agent the compiled bundle
|
|
26
|
+
* doesn't actually have (e.g. a profile that never declared
|
|
27
|
+
* `generate_dashboard`): when the rule-matched id isn't present, this falls
|
|
28
|
+
* back to `"answer_query"` — never throws, never returns an unknown id.
|
|
29
|
+
*
|
|
30
|
+
* Returns the chosen `agentId` alongside a short human `reason` for
|
|
31
|
+
* WHY that route was picked — surfaced as the turn's "Route" decision entry in
|
|
32
|
+
* the work log (see `server/turn.ts`). The routing LOGIC is unchanged; the
|
|
33
|
+
* reason is purely a display label.
|
|
34
|
+
*/
|
|
35
|
+
export interface IntentDecision {
|
|
36
|
+
readonly agentId: string;
|
|
37
|
+
/** Short human label for why this agent was chosen, e.g. `dashboard intent (chart)` or `default → answer_query`. */
|
|
38
|
+
readonly reason: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function classifyIntent(question: string, availableAgentIds: readonly string[]): IntentDecision;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function classifyIntent(question, availableAgentIds) {
|
|
2
|
+
const q = question.trim();
|
|
3
|
+
const explainMatch = q.match(/\b(why|explain|what\s+(?:caused|drove|led to)|reason|driver|because)\b/i);
|
|
4
|
+
const dashboardMatch = q.match(/\b(dashboard|chart|graph|plot|visuali[sz]e|trend|over time|breakdown|by\s+(?:region|month|quarter|year|week|day|category|product|customer|segment))\b/i);
|
|
5
|
+
// Exact candidate-selection logic: explanation has priority over dashboard, and
|
|
6
|
+
// a rule-matched id that the bundle lacks falls straight back to answer_query
|
|
7
|
+
// (it does NOT then reconsider a lower-priority rule).
|
|
8
|
+
const candidate = explainMatch ? "explain_change" : dashboardMatch ? "generate_dashboard" : "answer_query";
|
|
9
|
+
if (availableAgentIds.includes(candidate)) {
|
|
10
|
+
if (candidate === "explain_change" && explainMatch) {
|
|
11
|
+
return { agentId: candidate, reason: `explanation intent (${keyword(explainMatch)})` };
|
|
12
|
+
}
|
|
13
|
+
if (candidate === "generate_dashboard" && dashboardMatch) {
|
|
14
|
+
return { agentId: candidate, reason: `dashboard intent (${keyword(dashboardMatch)})` };
|
|
15
|
+
}
|
|
16
|
+
return { agentId: candidate, reason: "default → answer_query" };
|
|
17
|
+
}
|
|
18
|
+
return { agentId: "answer_query", reason: "default → answer_query" };
|
|
19
|
+
}
|
|
20
|
+
/** The matched intent keyword, lowercased — group 1 when present, else the whole match. */
|
|
21
|
+
function keyword(match) {
|
|
22
|
+
return (match[1] ?? match[0]).toLowerCase();
|
|
23
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AuthChoice, RouteOptions } from "../harness/index.js";
|
|
2
|
+
import type { CodexManifestModels } from "../harness/route/codex-local-manifest.js";
|
|
3
|
+
import type { RuntimeSettings, TierModelBinding } from "./wire-types.js";
|
|
4
|
+
export declare class RuntimeBindingError extends Error {
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The Claude Agent SDK accepts concrete model ids for its top-level driver,
|
|
8
|
+
* but its per-step `agents[].model` surface is deliberately narrower. Keep
|
|
9
|
+
* this product-side contract explicit so an invalid saved Runtime is rejected
|
|
10
|
+
* before a user turn reaches the dispatcher.
|
|
11
|
+
*/
|
|
12
|
+
export declare const CLAUDE_AGENT_SDK_PER_STEP_MODELS: readonly ["sonnet", "opus", "haiku", "inherit"];
|
|
13
|
+
/** The old single Model field is the default for every tier without a model override. */
|
|
14
|
+
export declare function effectiveTierModel(binding: TierModelBinding, settings: RuntimeSettings): string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Returns a browser-safe correction for an already persisted Runtime. This is
|
|
17
|
+
* intentionally narrower than catalog validation: provider catalog entries
|
|
18
|
+
* remain free-form wherever their dispatcher accepts concrete model ids. Only
|
|
19
|
+
* Claude's SDK subagent tier field has the closed alias union below.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runtimeSettingsCorrection(settings: RuntimeSettings): string | undefined;
|
|
22
|
+
/** Throws the same actionable error at every persisted-runtime dispatch boundary. */
|
|
23
|
+
export declare function assertRuntimeSettingsDispatchable(settings: RuntimeSettings): void;
|
|
24
|
+
/** Credential env vars used by the materialized in-process rows (local rows need none). */
|
|
25
|
+
export declare function requiredInProcessCredentialEnvVars(settings: RuntimeSettings): string[];
|
|
26
|
+
/** Validates the complete bundle map before Store/auth/live-route mutation. */
|
|
27
|
+
export declare function validateRuntimeTierBindings(settings: RuntimeSettings, bundleTiers: readonly string[]): void;
|
|
28
|
+
/** Generates the dispatcher-owned models config without ever serializing an API key. */
|
|
29
|
+
export declare function writeClaudeModelsConfig(settings: RuntimeSettings, bundleTiers: readonly string[]): string;
|
|
30
|
+
export declare function codexModelsForRuntime(settings: RuntimeSettings): CodexManifestModels;
|
|
31
|
+
/** Materializes the already-validated live binding for the selected runtime. */
|
|
32
|
+
export declare function materializeRuntimeRouteOptions(settings: RuntimeSettings, authChoice: AuthChoice): Pick<RouteOptions, "tierBinding" | "modelsConfig" | "codexModels">;
|
|
33
|
+
/** Bundle-owned tier names, in first-seen order. */
|
|
34
|
+
export declare function collectBundleTierNames(bundle: {
|
|
35
|
+
readonly agents: readonly {
|
|
36
|
+
readonly steps: readonly {
|
|
37
|
+
readonly tier: string;
|
|
38
|
+
}[];
|
|
39
|
+
}[];
|
|
40
|
+
}): string[];
|
|
41
|
+
/** Reads the tier contract directly from a compiled Warble IR document. */
|
|
42
|
+
export declare function collectIrTierNames(ir: unknown): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Compiles the canonical profile source without rebinding its context and
|
|
45
|
+
* extracts its tier contract from IR. This is intentionally independent of
|
|
46
|
+
* auth choice and of any user project: the Setup form must discover the rows
|
|
47
|
+
* before either exists.
|
|
48
|
+
*/
|
|
49
|
+
export declare function compileUnboundProfileTierNames(options: {
|
|
50
|
+
readonly profileSource: string;
|
|
51
|
+
readonly warbleBin?: string;
|
|
52
|
+
}): Promise<string[]>;
|