@iowarp/clio-coder 0.3.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/CHANGELOG.md +407 -0
- package/CODE_OF_CONDUCT.md +21 -0
- package/CONTRIBUTING.md +224 -0
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +798 -0
- package/SECURITY.md +72 -0
- package/assets/clio-coder-logo-128.webp +0 -0
- package/damage-control-rules.yaml +419 -0
- package/dist/acp-UMLFVA3F.js +92 -0
- package/dist/agents-Q4MYPMUW.js +91 -0
- package/dist/auth-O6HYIJ6J.js +521 -0
- package/dist/chunk-262G75JS.js +35 -0
- package/dist/chunk-26BZQOAD.js +1281 -0
- package/dist/chunk-2J63S4SF.js +508 -0
- package/dist/chunk-3DANZDGR.js +717 -0
- package/dist/chunk-4UQA7NCT.js +29 -0
- package/dist/chunk-527KG6XR.js +497 -0
- package/dist/chunk-5LDRNKX2.js +1063 -0
- package/dist/chunk-5N2FG33Q.js +25 -0
- package/dist/chunk-67MTHP2E.js +135 -0
- package/dist/chunk-6CWDTGUC.js +20 -0
- package/dist/chunk-7BHLZB3A.js +2115 -0
- package/dist/chunk-7RBKDI66.js +348 -0
- package/dist/chunk-AMFR5YA3.js +541 -0
- package/dist/chunk-BBUH4VAA.js +1224 -0
- package/dist/chunk-BYEU76JP.js +899 -0
- package/dist/chunk-CLJ5HLUD.js +458 -0
- package/dist/chunk-D5YD55AR.js +116 -0
- package/dist/chunk-DXQNI4PC.js +61 -0
- package/dist/chunk-E3NYWENM.js +1004 -0
- package/dist/chunk-GNGDQYDU.js +34688 -0
- package/dist/chunk-GOTUR54M.js +9 -0
- package/dist/chunk-HBU5MTAM.js +41 -0
- package/dist/chunk-HMYNFFY4.js +28 -0
- package/dist/chunk-JPOWPFCU.js +1010 -0
- package/dist/chunk-JWHCJDCI.js +1215 -0
- package/dist/chunk-KBR4MZZR.js +41 -0
- package/dist/chunk-KKKPTZLM.js +93 -0
- package/dist/chunk-ME6DNWIU.js +66 -0
- package/dist/chunk-NI4DEJMC.js +88 -0
- package/dist/chunk-O4EJEDHO.js +659 -0
- package/dist/chunk-PIDUD6M2.js +31 -0
- package/dist/chunk-PS4PFJQP.js +29459 -0
- package/dist/chunk-QV47YRF4.js +48 -0
- package/dist/chunk-RQDWMVRB.js +279 -0
- package/dist/chunk-TFSSEXL6.js +136 -0
- package/dist/chunk-TKHQ4DGZ.js +8290 -0
- package/dist/chunk-TPOCL34A.js +2876 -0
- package/dist/chunk-UGYAX5YI.js +565 -0
- package/dist/chunk-UHTSULZS.js +461 -0
- package/dist/chunk-UU3R62TT.js +128 -0
- package/dist/chunk-UWIJNAOB.js +3906 -0
- package/dist/chunk-VOO7NYPP.js +914 -0
- package/dist/chunk-VPAWTYLY.js +117 -0
- package/dist/chunk-WD6AJM35.js +1216 -0
- package/dist/chunk-X3BR7HWV.js +115 -0
- package/dist/chunk-X3NE4WVW.js +120 -0
- package/dist/chunk-XNISANGE.js +1395 -0
- package/dist/chunk-XV4ZJ6ZM.js +3177 -0
- package/dist/cli/index.js +236 -0
- package/dist/clio-KIQ5SNDS.js +53 -0
- package/dist/components-JVHMUBEB.js +653 -0
- package/dist/config-ZFCDBMDC.js +372 -0
- package/dist/configure-G4E3A2PG.js +27 -0
- package/dist/context-CDXTP2MP.js +293 -0
- package/dist/context-E3KIFVXI.js +185 -0
- package/dist/context-clear-3F4PLXOS.js +102 -0
- package/dist/context-index-Q7YSYTR3.js +106 -0
- package/dist/docs-YIETIWZI.js +280 -0
- package/dist/doctor-M5HJJZOL.js +61 -0
- package/dist/domains/agents/builtins/architect.md +33 -0
- package/dist/domains/agents/builtins/coder.md +31 -0
- package/dist/domains/agents/builtins/context-bootstrap.md +38 -0
- package/dist/domains/agents/builtins/debugger.md +30 -0
- package/dist/domains/agents/builtins/documenter.md +31 -0
- package/dist/domains/agents/builtins/git-master.md +30 -0
- package/dist/domains/agents/builtins/provenance.md +30 -0
- package/dist/domains/agents/builtins/researcher.md +71 -0
- package/dist/domains/agents/builtins/scout.md +42 -0
- package/dist/domains/agents/builtins/tester.md +31 -0
- package/dist/domains/agents/builtins/verifier.md +30 -0
- package/dist/domains/agents/builtins/wiki-writer.md +41 -0
- package/dist/eval-B3KZZESM.js +2674 -0
- package/dist/evidence-V67CHM35.js +233 -0
- package/dist/evolve-YDZSUQYA.js +518 -0
- package/dist/extensions-SRG7XCAH.js +207 -0
- package/dist/fleet-CA2CRTVG.js +760 -0
- package/dist/fleet-preflight-CLIAX7YR.js +21 -0
- package/dist/init-2OZDJE2D.js +227 -0
- package/dist/memory-3PIQQAKX.js +207 -0
- package/dist/models-DY35XI7Y.js +237 -0
- package/dist/paths-5OMXW7Z4.js +57 -0
- package/dist/preload-KZVHET2B.js +11 -0
- package/dist/reset-PIFYNOS3.js +216 -0
- package/dist/run-3VSPP24F.js +735 -0
- package/dist/share-D36RQCXM.js +241 -0
- package/dist/skills-F2MRLELY.js +445 -0
- package/dist/skills-eval-E2ZTW4PL.js +932 -0
- package/dist/targets-DZMEZAH4.js +977 -0
- package/dist/trace-7NYCUI2J.js +250 -0
- package/dist/uninstall-AD3JWHBB.js +322 -0
- package/dist/upgrade-WYYBKGDY.js +301 -0
- package/dist/usage-ULIDAGFF.js +755 -0
- package/dist/version-ROZ6CZKH.js +16 -0
- package/dist/wiki-generate-PKFIX6OB.js +377 -0
- package/dist/worker/entry.js +1739 -0
- package/docs/README.md +93 -0
- package/docs/acp.md +120 -0
- package/docs/alcf-provider.md +72 -0
- package/docs/architecture.md +172 -0
- package/docs/artifact-versions.md +54 -0
- package/docs/built-in-agents.md +265 -0
- package/docs/capacity-and-scheduling.md +97 -0
- package/docs/commands-and-modes.md +554 -0
- package/docs/config-knobs-audit.md +115 -0
- package/docs/configuration-and-targets.md +812 -0
- package/docs/context-engine.md +236 -0
- package/docs/dispatch-architecture-rationale.md +126 -0
- package/docs/documentation-coverage.md +46 -0
- package/docs/documentation-guide.md +166 -0
- package/docs/environment-variables.md +105 -0
- package/docs/eval-runner.md +205 -0
- package/docs/evals-internal.md +298 -0
- package/docs/evidence-and-memory.md +243 -0
- package/docs/evolution.md +143 -0
- package/docs/exit-codes-and-output.md +74 -0
- package/docs/extensions-and-sharing.md +306 -0
- package/docs/fleet-demo-runbook.md +179 -0
- package/docs/fleet-dispatch.md +591 -0
- package/docs/glossary.md +75 -0
- package/docs/html/agents_blueprint.html +936 -0
- package/docs/html/alcf_blueprint.html +324 -0
- package/docs/html/architecture_blueprint.html +850 -0
- package/docs/html/commands_blueprint.html +794 -0
- package/docs/html/config_knobs_audit_blueprint.html +178 -0
- package/docs/html/configuration_blueprint.html +1080 -0
- package/docs/html/context_blueprint.html +603 -0
- package/docs/html/documentation_blueprint.html +832 -0
- package/docs/html/environment_blueprint.html +404 -0
- package/docs/html/eval_blueprint.html +743 -0
- package/docs/html/evals_internal_blueprint.html +190 -0
- package/docs/html/evolution_blueprint.html +674 -0
- package/docs/html/extensions_blueprint.html +2065 -0
- package/docs/html/fleet_dispatch_blueprint.html +286 -0
- package/docs/html/index.html +919 -0
- package/docs/html/lifecycle_blueprint.html +723 -0
- package/docs/html/memory_blueprint.html +699 -0
- package/docs/html/middleware_blueprint.html +664 -0
- package/docs/html/models_blueprint.html +2366 -0
- package/docs/html/observability_blueprint.html +683 -0
- package/docs/html/provider_adapter_blueprint.html +245 -0
- package/docs/html/safety_blueprint.html +1386 -0
- package/docs/html/shared.css +571 -0
- package/docs/html/shared.js +143 -0
- package/docs/html/skills_blueprint.html +671 -0
- package/docs/html/soak_blueprint.html +182 -0
- package/docs/html/tool_usage_blueprint.html +350 -0
- package/docs/html/tools_blueprint.html +2249 -0
- package/docs/html/trace_blueprint.html +235 -0
- package/docs/html/tui_design_blueprint.html +314 -0
- package/docs/html/validation_blueprint.html +961 -0
- package/docs/html/worker_dispatch_blueprint.html +231 -0
- package/docs/installation-and-lifecycle.md +308 -0
- package/docs/middleware-and-components.md +148 -0
- package/docs/model-catalog.md +189 -0
- package/docs/observability.md +233 -0
- package/docs/proactive-memory.md +452 -0
- package/docs/prompt-envelope-and-tools.md +142 -0
- package/docs/provider-adapter-cookbook.md +148 -0
- package/docs/release-cut-checklist.md +138 -0
- package/docs/safety-model.md +357 -0
- package/docs/scientific-validation.md +105 -0
- package/docs/session-lifecycle.md +156 -0
- package/docs/skills-marketplace.md +46 -0
- package/docs/tool-usage.md +527 -0
- package/docs/trace-store.md +132 -0
- package/docs/troubleshooting.md +33 -0
- package/docs/tui-design.md +239 -0
- package/docs/worker-dispatch-mechanics.md +242 -0
- package/package.json +132 -0
- package/skills/README.md +408 -0
- package/skills/git/commit-crafting/SKILL.md +79 -0
- package/skills/git/commit-crafting/evals.md +92 -0
- package/skills/git/create-pr/SKILL.md +116 -0
- package/skills/git/create-pr/evals.md +114 -0
- package/skills/git/investigate-issue/SKILL.md +139 -0
- package/skills/git/investigate-issue/evals.md +94 -0
- package/skills/git/resolve-merge-conflicts/SKILL.md +96 -0
- package/skills/git/resolve-merge-conflicts/evals.md +58 -0
- package/skills/git/review-changes/SKILL.md +103 -0
- package/skills/git/review-changes/evals.md +85 -0
- package/skills/git/worktree-create/SKILL.md +92 -0
- package/skills/git/worktree-create/evals.md +97 -0
- package/skills/git/worktree-create/references/worktree-setup.md +66 -0
- package/skills/git/worktree-merge/SKILL.md +95 -0
- package/skills/git/worktree-merge/evals.md +114 -0
- package/skills/skill-marketplace.json +261 -0
- package/skills/workflow/cut-it/SKILL.md +86 -0
- package/skills/workflow/cut-it/evals.md +42 -0
- package/src/domains/agents/builtins/architect.md +33 -0
- package/src/domains/agents/builtins/coder.md +31 -0
- package/src/domains/agents/builtins/context-bootstrap.md +38 -0
- package/src/domains/agents/builtins/debugger.md +30 -0
- package/src/domains/agents/builtins/documenter.md +31 -0
- package/src/domains/agents/builtins/git-master.md +30 -0
- package/src/domains/agents/builtins/provenance.md +30 -0
- package/src/domains/agents/builtins/researcher.md +71 -0
- package/src/domains/agents/builtins/scout.md +42 -0
- package/src/domains/agents/builtins/tester.md +31 -0
- package/src/domains/agents/builtins/verifier.md +30 -0
- package/src/domains/agents/builtins/wiki-writer.md +41 -0
- package/src/domains/agents/fleets/build-review.md +34 -0
- package/src/domains/agents/fleets/build-test.md +35 -0
- package/src/domains/agents/fleets/sdlc.md +86 -0
- package/src/domains/prompts/fragments/identity/clio-worker.md +11 -0
- package/src/domains/prompts/fragments/identity/clio.md +26 -0
- package/src/domains/prompts/fragments/operating/contract.md +64 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +14 -0
- package/src/domains/prompts/fragments/safety/full-auto.md +14 -0
- package/src/domains/prompts/fragments/safety/read-only.md +13 -0
- package/src/domains/prompts/fragments/safety/suggest.md +13 -0
- package/src/domains/prompts/fragments/wiki/page.md +75 -0
- package/src/domains/prompts/fragments/wiki/plan.md +48 -0
- package/src/domains/providers/models/cloud-models/alcf.yaml +40 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +993 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import {
|
|
2
|
+
armInternalDispatchDeadline
|
|
3
|
+
} from "./chunk-4UQA7NCT.js";
|
|
4
|
+
import {
|
|
5
|
+
SchedulingDomainModule,
|
|
6
|
+
createPromptsDomainModule
|
|
7
|
+
} from "./chunk-3DANZDGR.js";
|
|
8
|
+
import {
|
|
9
|
+
AgentsDomainModule,
|
|
10
|
+
SafetyDomainModule
|
|
11
|
+
} from "./chunk-JPOWPFCU.js";
|
|
12
|
+
import {
|
|
13
|
+
ConfigDomainModule,
|
|
14
|
+
loadDomains
|
|
15
|
+
} from "./chunk-527KG6XR.js";
|
|
16
|
+
import {
|
|
17
|
+
fallbackBootstrapOutput
|
|
18
|
+
} from "./chunk-UWIJNAOB.js";
|
|
19
|
+
import {
|
|
20
|
+
renderCodewikiDigest
|
|
21
|
+
} from "./chunk-X3BR7HWV.js";
|
|
22
|
+
import {
|
|
23
|
+
DispatchDomainModule,
|
|
24
|
+
MiddlewareDomainModule,
|
|
25
|
+
SessionDomainModule,
|
|
26
|
+
UnsupportedResponseSchemaError,
|
|
27
|
+
createObservabilityDomainModule,
|
|
28
|
+
isResponseSchemaRejection
|
|
29
|
+
} from "./chunk-GNGDQYDU.js";
|
|
30
|
+
import {
|
|
31
|
+
ResourcesDomainModule
|
|
32
|
+
} from "./chunk-2J63S4SF.js";
|
|
33
|
+
import {
|
|
34
|
+
ProvidersDomainModule
|
|
35
|
+
} from "./chunk-TKHQ4DGZ.js";
|
|
36
|
+
|
|
37
|
+
// src/domains/context/bootstrap-prompt.ts
|
|
38
|
+
var BOOTSTRAP_PROMPT = `You are the clio-coder bootstrap agent. Your job is to write the custom sections of CLIO-CODER.md for the project at <cwd>. CLIO-CODER.md is a lean, project-specific handbook that the clio-coder coding agent loads on every session, so write for an experienced engineer who has never seen this repository and is about to change it.
|
|
39
|
+
|
|
40
|
+
Read the repository before you answer: start with code_nav (modes symbol, path, entries, outline, deps, dependents, wiki) against the index Clio just built, then read the specific files that decide behavior. Do not write files, run tests, or use external sources.
|
|
41
|
+
|
|
42
|
+
You will be given:
|
|
43
|
+
- The repository-derived project name. Return it exactly as projectName; do not substitute a path or invent a brand.
|
|
44
|
+
- The detected project type.
|
|
45
|
+
- The existing CLIO-CODER.md when one is present. Treat it as evidence; Clio preserves its human-owned fields outside your response.
|
|
46
|
+
- A structural digest from the codewiki index: module count, entry points, and top directories.
|
|
47
|
+
- A sanitized adoption scan of project-local agent configs, including Claude Code context files and skills (CLAUDE.md, .claude/CLAUDE.md, project settings/commands/agents/skills), Codex (AGENTS.md, CODEX.md, .codex/AGENTS.md, .codex/skills), Gemini (GEMINI.md, .gemini/GEMINI.md, .gemini config/rules), Cursor (.cursor/rules/*.mdc and *.md), OpenCode (.opencode/skills), and GitHub Copilot (.github/copilot-instructions.md, .github/skills).
|
|
48
|
+
- Global user preferences only when the user explicitly opted in.
|
|
49
|
+
|
|
50
|
+
THE CITATION RULE, which Clio enforces after you answer: a line survives only when it contains at least one backticked token, and every backticked token names something real in this repository, meaning an indexed file path, a symbol, a runnable package script, or a string that occurs in the supplied evidence. A line that cites nothing is deleted. A line that cites something that does not exist is deleted. Write every line so that it names the file, symbol, or command it is about.
|
|
51
|
+
|
|
52
|
+
Clio's deterministic layer owns the project name, identity, conventions, hard invariants, the navigation and repository-shape sections, agent-context provenance, and the verification-command section. Set projectName to the supplied expectedProjectName, keep identity to one short sentence, and return empty conventions and invariants arrays.
|
|
53
|
+
|
|
54
|
+
Your contribution is two to four custom H2 sections, chosen from these, in this order of value:
|
|
55
|
+
- "Architecture": the control flow a change has to travel through, named file by file. Say which module owns which decision, and which files are coupled and must change together. This is the section that requires reading, so it is the one worth the most.
|
|
56
|
+
- "Gotchas": invariants that are easy to break. Each item names the file that enforces it and the consequence of breaking it, especially where a violation degrades silently instead of failing loudly.
|
|
57
|
+
- "Extending": for the two or three most likely kinds of change, the exact set of files that must be touched together.
|
|
58
|
+
- "Commands": only development commands that Clio's verification section will not already state, such as running a single test, a dry-run mode, or a debug environment variable.
|
|
59
|
+
|
|
60
|
+
Prefer specific over complete. Six lines that name real files beat twenty lines of summary. State a size warning when a file is large enough that reading it top to bottom is the wrong move. A fenced block is acceptable for commands; Clio inlines it.
|
|
61
|
+
|
|
62
|
+
Copy commands, file paths, symbols, and version constraints exactly. Never repair, combine, or paraphrase a shell command. Never invent an API endpoint, an example, an ownership team, a review requirement, a release process, or a file count. If you did not read it or it was not supplied, do not write it.
|
|
63
|
+
|
|
64
|
+
Do not include a project map, a file tree, a dependency inventory, a language-idiom list, preferences, communication-style content, secrets, credentials, auth tokens, caches, histories, generated state, fingerprint metadata, or imported-context provenance. Clio adds its deterministic surfaces after parsing. Keep the complete custom-section payload under 2500 bytes.
|
|
65
|
+
|
|
66
|
+
Return one assistant message containing only compact JSON with this exact shape. Do not include markdown fences, prose, explanation, or commentary:
|
|
67
|
+
{
|
|
68
|
+
"projectName": "string",
|
|
69
|
+
"identity": "string",
|
|
70
|
+
"conventions": ["string"],
|
|
71
|
+
"invariants": ["string"],
|
|
72
|
+
"sections": [{ "title": "string", "body": "markdown string" }]
|
|
73
|
+
}`;
|
|
74
|
+
var BOOTSTRAP_OUTPUT_JSON_SCHEMA = {
|
|
75
|
+
type: "object",
|
|
76
|
+
additionalProperties: false,
|
|
77
|
+
required: ["projectName", "identity", "conventions", "invariants", "sections"],
|
|
78
|
+
properties: {
|
|
79
|
+
// Keep the provider schema to llama.cpp's portable grammar subset.
|
|
80
|
+
// parseBootstrapModelOutput enforces all string and array bounds below.
|
|
81
|
+
projectName: { type: "string" },
|
|
82
|
+
identity: { type: "string" },
|
|
83
|
+
conventions: {
|
|
84
|
+
type: "array",
|
|
85
|
+
items: { type: "string" }
|
|
86
|
+
},
|
|
87
|
+
invariants: {
|
|
88
|
+
type: "array",
|
|
89
|
+
items: { type: "string" }
|
|
90
|
+
},
|
|
91
|
+
sections: {
|
|
92
|
+
type: "array",
|
|
93
|
+
items: {
|
|
94
|
+
type: "object",
|
|
95
|
+
additionalProperties: false,
|
|
96
|
+
required: ["title", "body"],
|
|
97
|
+
properties: {
|
|
98
|
+
title: { type: "string" },
|
|
99
|
+
body: { type: "string" }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
function truncate(value, max) {
|
|
106
|
+
if (value.length <= max) return value;
|
|
107
|
+
const marker = "\n[truncated]";
|
|
108
|
+
if (max <= marker.length) return value.slice(0, max);
|
|
109
|
+
return `${value.slice(0, max - marker.length)}${marker}`;
|
|
110
|
+
}
|
|
111
|
+
var BOOTSTRAP_INPUT_MAX_CHARS = 48e3;
|
|
112
|
+
var BOOTSTRAP_SIBLING_MAX_FILES = 12;
|
|
113
|
+
var BOOTSTRAP_SIBLING_CONTENT_MAX_CHARS = 12e3;
|
|
114
|
+
function sourceSummaries(files, adoption) {
|
|
115
|
+
const selected = files.slice(0, BOOTSTRAP_SIBLING_MAX_FILES);
|
|
116
|
+
const perFileLimit = Math.min(
|
|
117
|
+
3e3,
|
|
118
|
+
Math.max(1, Math.floor(BOOTSTRAP_SIBLING_CONTENT_MAX_CHARS / Math.max(1, selected.length)))
|
|
119
|
+
);
|
|
120
|
+
const displayPath = new Map(adoption.sources.map((source) => [source.path, source.displayPath]));
|
|
121
|
+
return selected.map((file) => ({
|
|
122
|
+
scope: file.source,
|
|
123
|
+
path: truncate(displayPath.get(file.path) ?? file.path, 240),
|
|
124
|
+
content: truncate(file.content, perFileLimit)
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
function compactImportedRules(adoption) {
|
|
128
|
+
return adoption.importedRules.slice(0, 12).map((rule) => ({
|
|
129
|
+
text: truncate(rule.text, 240),
|
|
130
|
+
sources: rule.sources.slice(0, 2).map((source) => truncate(source, 160)),
|
|
131
|
+
providers: rule.providers.slice(0, 2).map((provider) => truncate(provider, 80)),
|
|
132
|
+
...rule.directoryScopes ? { directoryScopes: rule.directoryScopes.slice(0, 2).map((scope) => truncate(scope, 160)) } : {},
|
|
133
|
+
...rule.conflictKey ? { conflictKey: truncate(rule.conflictKey, 80) } : {}
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
function compactConflicts(adoption) {
|
|
137
|
+
return adoption.conflicts.slice(0, 6).map((conflict) => ({
|
|
138
|
+
key: truncate(conflict.key, 80),
|
|
139
|
+
kept: truncate(conflict.kept, 240),
|
|
140
|
+
keptSources: conflict.keptSources.slice(0, 2).map((source) => truncate(source, 160)),
|
|
141
|
+
skipped: conflict.skipped.slice(0, 1).map((skipped) => ({
|
|
142
|
+
text: truncate(skipped.text, 240),
|
|
143
|
+
source: truncate(skipped.source, 160),
|
|
144
|
+
provider: truncate(skipped.provider, 80)
|
|
145
|
+
}))
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
function compactRejected(adoption) {
|
|
149
|
+
return adoption.rejected.slice(0, 8).map((rejected) => ({
|
|
150
|
+
path: truncate(rejected.displayPath, 240),
|
|
151
|
+
scope: rejected.scope,
|
|
152
|
+
...rejected.provider ? { provider: rejected.provider } : {},
|
|
153
|
+
reason: truncate(rejected.reason, 160)
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
function buildBootstrapPrompt(input) {
|
|
157
|
+
const siblingFiles = sourceSummaries(input.siblingFiles, input.adoption);
|
|
158
|
+
const importedRules = compactImportedRules(input.adoption);
|
|
159
|
+
const conflicts = compactConflicts(input.adoption);
|
|
160
|
+
const rejected = compactRejected(input.adoption);
|
|
161
|
+
const adoption = {
|
|
162
|
+
includeGlobal: input.adoption.includeGlobal,
|
|
163
|
+
sourceCount: input.adoption.sources.length,
|
|
164
|
+
presentedSourceCount: siblingFiles.length,
|
|
165
|
+
importedRuleCount: input.adoption.importedRules.length,
|
|
166
|
+
conflictCount: input.adoption.conflicts.length,
|
|
167
|
+
rejectedCount: input.adoption.rejected.length,
|
|
168
|
+
importedRules,
|
|
169
|
+
conflicts,
|
|
170
|
+
rejected
|
|
171
|
+
};
|
|
172
|
+
const payload = {
|
|
173
|
+
projectRoot: ".",
|
|
174
|
+
expectedProjectName: truncate(input.expectedProjectName ?? "Project", 80),
|
|
175
|
+
projectType: input.projectType,
|
|
176
|
+
...input.existingClioMdText ? { existingClioMd: truncate(input.existingClioMdText, 8e3) } : {},
|
|
177
|
+
...input.codewiki ? { codewikiDigest: renderCodewikiDigest(input.codewiki, 1200) } : {},
|
|
178
|
+
siblingFiles,
|
|
179
|
+
adoption
|
|
180
|
+
};
|
|
181
|
+
let serialized = JSON.stringify(payload);
|
|
182
|
+
while (serialized.length > BOOTSTRAP_INPUT_MAX_CHARS) {
|
|
183
|
+
if (rejected.length > 0) rejected.pop();
|
|
184
|
+
else if (conflicts.length > 0) conflicts.pop();
|
|
185
|
+
else if (siblingFiles.length > 1) siblingFiles.pop();
|
|
186
|
+
else if (importedRules.length > 1) importedRules.pop();
|
|
187
|
+
else break;
|
|
188
|
+
adoption.presentedSourceCount = siblingFiles.length;
|
|
189
|
+
serialized = JSON.stringify(payload);
|
|
190
|
+
}
|
|
191
|
+
if (serialized.length > BOOTSTRAP_INPUT_MAX_CHARS) {
|
|
192
|
+
serialized = JSON.stringify({
|
|
193
|
+
projectRoot: ".",
|
|
194
|
+
expectedProjectName: truncate(input.expectedProjectName ?? "Project", 80),
|
|
195
|
+
projectType: input.projectType,
|
|
196
|
+
...input.existingClioMdText ? { existingClioMd: truncate(input.existingClioMdText, 2e3) } : {},
|
|
197
|
+
...input.codewiki ? { codewikiDigest: renderCodewikiDigest(input.codewiki, 1200) } : {},
|
|
198
|
+
siblingFiles: [],
|
|
199
|
+
adoption: {
|
|
200
|
+
includeGlobal: input.adoption.includeGlobal,
|
|
201
|
+
sourceCount: input.adoption.sources.length,
|
|
202
|
+
presentedSourceCount: 0,
|
|
203
|
+
importedRuleCount: input.adoption.importedRules.length,
|
|
204
|
+
conflictCount: input.adoption.conflicts.length,
|
|
205
|
+
rejectedCount: input.adoption.rejected.length
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return `${BOOTSTRAP_PROMPT}
|
|
210
|
+
|
|
211
|
+
<bootstrap-input>
|
|
212
|
+
${serialized}
|
|
213
|
+
</bootstrap-input>`;
|
|
214
|
+
}
|
|
215
|
+
function extractJsonObject(text) {
|
|
216
|
+
const trimmed = text.trim();
|
|
217
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) return JSON.parse(trimmed);
|
|
218
|
+
const fenced = /```(?:json)?\s*([\s\S]*?)```/i.exec(trimmed)?.[1]?.trim();
|
|
219
|
+
if (fenced?.startsWith("{")) return JSON.parse(fenced);
|
|
220
|
+
const start = trimmed.indexOf("{");
|
|
221
|
+
const end = trimmed.lastIndexOf("}");
|
|
222
|
+
if (start >= 0 && end > start) return JSON.parse(trimmed.slice(start, end + 1));
|
|
223
|
+
throw new Error("bootstrap model output did not contain a JSON object");
|
|
224
|
+
}
|
|
225
|
+
function stringArray(value, key, maxItems, maxChars) {
|
|
226
|
+
if (value === void 0) return [];
|
|
227
|
+
if (!Array.isArray(value)) throw new Error(`bootstrap model output '${key}' must be an array`);
|
|
228
|
+
return value.map((item, index) => {
|
|
229
|
+
if (typeof item !== "string") throw new Error(`bootstrap model output '${key}[${index}]' must be a string`);
|
|
230
|
+
return item.replace(/\s+/g, " ").trim();
|
|
231
|
+
}).filter((item) => item.length > 0).slice(0, maxItems).map((item) => item.slice(0, maxChars));
|
|
232
|
+
}
|
|
233
|
+
function stringField(record, key, maxChars) {
|
|
234
|
+
const value = record[key];
|
|
235
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
236
|
+
throw new Error(`bootstrap model output '${key}' must be a non-empty string`);
|
|
237
|
+
}
|
|
238
|
+
return value.replace(/\s+/g, " ").trim().slice(0, maxChars);
|
|
239
|
+
}
|
|
240
|
+
function structuredSections(value) {
|
|
241
|
+
if (value === void 0) return [];
|
|
242
|
+
if (!Array.isArray(value)) throw new Error("bootstrap model output 'sections' must be an array");
|
|
243
|
+
return value.map((item, index) => {
|
|
244
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
245
|
+
throw new Error(`bootstrap model output 'sections[${index}]' must be an object`);
|
|
246
|
+
}
|
|
247
|
+
const record = item;
|
|
248
|
+
if (typeof record.title !== "string" || record.title.trim().length === 0) {
|
|
249
|
+
throw new Error(`bootstrap model output 'sections[${index}].title' must be a non-empty string`);
|
|
250
|
+
}
|
|
251
|
+
if (typeof record.body !== "string" || record.body.trim().length === 0) {
|
|
252
|
+
throw new Error(`bootstrap model output 'sections[${index}].body' must be a non-empty string`);
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
title: record.title.replace(/\s+/g, " ").trim().slice(0, 80),
|
|
256
|
+
body: record.body.trim().slice(0, 2500)
|
|
257
|
+
};
|
|
258
|
+
}).filter((section) => section.title.length > 0 && section.body.length > 0).slice(0, 8);
|
|
259
|
+
}
|
|
260
|
+
function parseBootstrapModelOutput(text) {
|
|
261
|
+
const parsed = extractJsonObject(text);
|
|
262
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
263
|
+
throw new Error("bootstrap model output must be a JSON object");
|
|
264
|
+
}
|
|
265
|
+
const record = parsed;
|
|
266
|
+
return {
|
|
267
|
+
projectName: stringField(record, "projectName", 80),
|
|
268
|
+
identity: stringField(record, "identity", 600),
|
|
269
|
+
conventions: stringArray(record.conventions, "conventions", 6, 200),
|
|
270
|
+
invariants: stringArray(record.invariants, "invariants", 3, 280),
|
|
271
|
+
sections: structuredSections(record.sections)
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/cli/bootstrap-generate.ts
|
|
276
|
+
var BOOTSTRAP_MAX_OUTPUT_BYTES = 256 * 1024;
|
|
277
|
+
var CONTEXT_BOOTSTRAP_AGENT_ID = "context-bootstrap";
|
|
278
|
+
function resolveBootstrapRoute(settings) {
|
|
279
|
+
for (const agentId of [CONTEXT_BOOTSTRAP_AGENT_ID, "scout"]) {
|
|
280
|
+
const profileName = settings.workers.agentBindings[agentId];
|
|
281
|
+
if (!profileName) continue;
|
|
282
|
+
const profile = settings.workers.profiles[profileName];
|
|
283
|
+
if (!profile) throw new Error(`bootstrap profile '${profileName}' is not configured (bound to '${agentId}')`);
|
|
284
|
+
if (!profile.target) throw new Error(`bootstrap profile '${profileName}' has no target (bound to '${agentId}')`);
|
|
285
|
+
return {
|
|
286
|
+
target: profile.target,
|
|
287
|
+
...profile.model ? { model: profile.model } : {},
|
|
288
|
+
...profile.thinkingLevel ? { thinkingLevel: profile.thinkingLevel } : {}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const fallback = settings.workers.default;
|
|
292
|
+
if (!fallback?.target) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
`bootstrap has no route: workers.agentBindings.${CONTEXT_BOOTSTRAP_AGENT_ID} is unbound and workers.default has no target; bind a profile with 'clio-coder targets profile bind ${CONTEXT_BOOTSTRAP_AGENT_ID} <profile>' or set workers.default.target`
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
target: fallback.target,
|
|
299
|
+
...fallback.model ? { model: fallback.model } : {},
|
|
300
|
+
...fallback.thinkingLevel ? { thinkingLevel: fallback.thinkingLevel } : {}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function isRecord(value) {
|
|
304
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
305
|
+
}
|
|
306
|
+
function assistantTextFromMessage(message) {
|
|
307
|
+
if (!isRecord(message) || message.role !== "assistant") return "";
|
|
308
|
+
const content = message.content;
|
|
309
|
+
if (typeof content === "string") return content.trim();
|
|
310
|
+
if (!Array.isArray(content)) return "";
|
|
311
|
+
return content.map((block) => {
|
|
312
|
+
if (typeof block === "string") return block;
|
|
313
|
+
if (!isRecord(block)) return "";
|
|
314
|
+
return typeof block.text === "string" ? block.text : "";
|
|
315
|
+
}).join("").trim();
|
|
316
|
+
}
|
|
317
|
+
function textDeltaFromEvent(event) {
|
|
318
|
+
if (!isRecord(event) || event.type !== "text_delta") return "";
|
|
319
|
+
return typeof event.text === "string" ? event.text : "";
|
|
320
|
+
}
|
|
321
|
+
function toolNameFromEvent(event) {
|
|
322
|
+
if (!isRecord(event)) return null;
|
|
323
|
+
const payload = event.payload;
|
|
324
|
+
if (!isRecord(payload)) return null;
|
|
325
|
+
return typeof payload.tool === "string" && payload.tool.length > 0 ? payload.tool : null;
|
|
326
|
+
}
|
|
327
|
+
function toolOutcomeFromEvent(event) {
|
|
328
|
+
if (!isRecord(event)) return null;
|
|
329
|
+
const payload = event.payload;
|
|
330
|
+
if (!isRecord(payload)) return null;
|
|
331
|
+
return typeof payload.outcome === "string" && payload.outcome.length > 0 ? payload.outcome : null;
|
|
332
|
+
}
|
|
333
|
+
var BootstrapAttemptError = class extends Error {
|
|
334
|
+
parserOutcome;
|
|
335
|
+
telemetry;
|
|
336
|
+
constructor(error, parserOutcome, telemetry) {
|
|
337
|
+
super(error.message);
|
|
338
|
+
this.name = "BootstrapAttemptError";
|
|
339
|
+
this.parserOutcome = parserOutcome;
|
|
340
|
+
this.telemetry = telemetry;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
var BootstrapOutputLimitError = class extends Error {
|
|
344
|
+
constructor(observedBytes) {
|
|
345
|
+
super(`bootstrap output exceeded ${BOOTSTRAP_MAX_OUTPUT_BYTES} UTF-8 bytes`);
|
|
346
|
+
this.observedBytes = observedBytes;
|
|
347
|
+
this.name = "BootstrapOutputLimitError";
|
|
348
|
+
}
|
|
349
|
+
observedBytes;
|
|
350
|
+
};
|
|
351
|
+
function durationFromReceipt(receipt) {
|
|
352
|
+
const startedAt = Date.parse(receipt.startedAt);
|
|
353
|
+
const endedAt = Date.parse(receipt.endedAt);
|
|
354
|
+
if (!Number.isFinite(startedAt) || !Number.isFinite(endedAt)) return void 0;
|
|
355
|
+
return Math.max(0, endedAt - startedAt);
|
|
356
|
+
}
|
|
357
|
+
function bootstrapTelemetry(prompt, output, startedAt, structuredOutputMode, runId, receipt, observedOutputBytes) {
|
|
358
|
+
const telemetry = {
|
|
359
|
+
structuredOutputMode,
|
|
360
|
+
promptBytes: Buffer.byteLength(prompt, "utf8"),
|
|
361
|
+
outputBytes: observedOutputBytes ?? Buffer.byteLength(output, "utf8"),
|
|
362
|
+
durationMs: receipt ? durationFromReceipt(receipt) ?? Math.max(0, Date.now() - startedAt) : Math.max(0, Date.now() - startedAt),
|
|
363
|
+
...runId ? { runId } : {}
|
|
364
|
+
};
|
|
365
|
+
if (!receipt) return telemetry;
|
|
366
|
+
telemetry.runId = receipt.runId;
|
|
367
|
+
telemetry.targetId = receipt.targetId;
|
|
368
|
+
telemetry.wireModelId = receipt.wireModelId;
|
|
369
|
+
telemetry.runtimeId = receipt.runtimeId;
|
|
370
|
+
telemetry.runtimeKind = receipt.runtimeKind;
|
|
371
|
+
if (receipt.runtimeResolution?.effectiveThinkingLevel) {
|
|
372
|
+
telemetry.thinkingLevel = receipt.runtimeResolution.effectiveThinkingLevel;
|
|
373
|
+
}
|
|
374
|
+
telemetry.tokens = {
|
|
375
|
+
total: receipt.tokenCount,
|
|
376
|
+
...receipt.inputTokenCount !== void 0 ? { input: receipt.inputTokenCount } : {},
|
|
377
|
+
...receipt.outputTokenCount !== void 0 ? { output: receipt.outputTokenCount } : {},
|
|
378
|
+
...receipt.cacheReadTokenCount !== void 0 ? { cacheRead: receipt.cacheReadTokenCount } : {},
|
|
379
|
+
...receipt.cacheWriteTokenCount !== void 0 ? { cacheWrite: receipt.cacheWriteTokenCount } : {},
|
|
380
|
+
...receipt.reasoningTokenCount !== void 0 ? { reasoning: receipt.reasoningTokenCount } : {}
|
|
381
|
+
};
|
|
382
|
+
telemetry.toolCalls = receipt.toolCalls;
|
|
383
|
+
telemetry.toolFailures = receipt.toolStats.reduce((total, stat) => total + stat.errors, 0);
|
|
384
|
+
telemetry.toolBlocked = receipt.toolStats.reduce((total, stat) => total + stat.blocked, 0);
|
|
385
|
+
return telemetry;
|
|
386
|
+
}
|
|
387
|
+
async function collectDispatchAssistantText(events, input) {
|
|
388
|
+
let streamedText = "";
|
|
389
|
+
let streamedBytes = 0;
|
|
390
|
+
let lastAssistantText = "";
|
|
391
|
+
for await (const event of events) {
|
|
392
|
+
if (isRecord(event) && event.type === "route_warning" && typeof event.message === "string") {
|
|
393
|
+
input.progress?.({
|
|
394
|
+
phase: "generate",
|
|
395
|
+
status: "running",
|
|
396
|
+
message: "bootstrap routing changed",
|
|
397
|
+
detail: event.message
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
if (isRecord(event) && event.type === "agent_start") {
|
|
401
|
+
input.progress?.({
|
|
402
|
+
phase: "generate",
|
|
403
|
+
status: "running",
|
|
404
|
+
message: "bootstrap agent started repository exploration"
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (isRecord(event) && event.type === "clio_tool_start") {
|
|
408
|
+
const tool = toolNameFromEvent(event);
|
|
409
|
+
if (tool) {
|
|
410
|
+
input.progress?.({
|
|
411
|
+
phase: "generate",
|
|
412
|
+
status: "running",
|
|
413
|
+
message: `bootstrap running ${tool}`,
|
|
414
|
+
detail: "read-only repository exploration"
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (isRecord(event) && event.type === "clio_tool_finish") {
|
|
419
|
+
const tool = toolNameFromEvent(event);
|
|
420
|
+
const outcome = toolOutcomeFromEvent(event) ?? "done";
|
|
421
|
+
if (tool) {
|
|
422
|
+
input.progress?.({
|
|
423
|
+
phase: "generate",
|
|
424
|
+
status: "running",
|
|
425
|
+
message: `bootstrap ${tool} ${outcome}`
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const delta = textDeltaFromEvent(event);
|
|
430
|
+
if (delta.length > 0) {
|
|
431
|
+
streamedBytes += Buffer.byteLength(delta, "utf8");
|
|
432
|
+
if (streamedBytes > BOOTSTRAP_MAX_OUTPUT_BYTES) {
|
|
433
|
+
throw new BootstrapOutputLimitError(streamedBytes);
|
|
434
|
+
}
|
|
435
|
+
streamedText += delta;
|
|
436
|
+
}
|
|
437
|
+
if (isRecord(event) && event.type === "message_end") {
|
|
438
|
+
const text = assistantTextFromMessage(event.message);
|
|
439
|
+
if (text.length > 0) {
|
|
440
|
+
const bytes = Buffer.byteLength(text, "utf8");
|
|
441
|
+
if (bytes > BOOTSTRAP_MAX_OUTPUT_BYTES) throw new BootstrapOutputLimitError(bytes);
|
|
442
|
+
lastAssistantText = text;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return (lastAssistantText || streamedText).trim();
|
|
447
|
+
}
|
|
448
|
+
function receiptFailure(receipt) {
|
|
449
|
+
const detail = receipt.failureMessage ? `: ${receipt.failureMessage}` : "";
|
|
450
|
+
return `bootstrap agent failed with exit ${receipt.exitCode}${detail}`;
|
|
451
|
+
}
|
|
452
|
+
function responseSchemaRefusal(err) {
|
|
453
|
+
if (err instanceof UnsupportedResponseSchemaError) return err.message;
|
|
454
|
+
if (err instanceof BootstrapAttemptError && isResponseSchemaRejection(err.message)) return err.message;
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
async function attemptBootstrapDispatch(dispatch, input, prompt, startedAt, structuredOutputMode, dispatchBootstrap) {
|
|
458
|
+
const nativeSchema = structuredOutputMode === "native-schema";
|
|
459
|
+
let handle;
|
|
460
|
+
try {
|
|
461
|
+
handle = await dispatchBootstrap(nativeSchema);
|
|
462
|
+
} catch (err) {
|
|
463
|
+
if (nativeSchema && err instanceof UnsupportedResponseSchemaError) throw err;
|
|
464
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
465
|
+
throw new BootstrapAttemptError(error, "not-run", bootstrapTelemetry(prompt, "", startedAt, structuredOutputMode));
|
|
466
|
+
}
|
|
467
|
+
const deadline = armInternalDispatchDeadline(dispatch, handle.runId, "context bootstrap", process.env);
|
|
468
|
+
let text = "";
|
|
469
|
+
let receipt;
|
|
470
|
+
let parserAttempted = false;
|
|
471
|
+
try {
|
|
472
|
+
text = await collectDispatchAssistantText(handle.events, input);
|
|
473
|
+
receipt = await handle.finalPromise;
|
|
474
|
+
if (deadline.timedOut()) throw new Error(deadline.message());
|
|
475
|
+
if (receipt.exitCode !== 0) throw new Error(receiptFailure(receipt));
|
|
476
|
+
if (text.length === 0) throw new Error("bootstrap agent did not return an assistant response");
|
|
477
|
+
parserAttempted = true;
|
|
478
|
+
const output = parseBootstrapModelOutput(text);
|
|
479
|
+
input.progress?.({
|
|
480
|
+
phase: "generate",
|
|
481
|
+
status: "running",
|
|
482
|
+
message: "bootstrap agent returned the handbook payload",
|
|
483
|
+
detail: `${Buffer.byteLength(text, "utf8")} bytes`
|
|
484
|
+
});
|
|
485
|
+
input.reportGeneration?.({
|
|
486
|
+
mode: "model",
|
|
487
|
+
parserOutcome: "parsed",
|
|
488
|
+
run: bootstrapTelemetry(prompt, text, startedAt, structuredOutputMode, handle.runId, receipt)
|
|
489
|
+
});
|
|
490
|
+
return output;
|
|
491
|
+
} catch (err) {
|
|
492
|
+
if (!deadline.timedOut()) dispatch.abort(handle.runId);
|
|
493
|
+
receipt ??= await handle.finalPromise.catch(() => void 0);
|
|
494
|
+
const error = deadline.timedOut() ? new Error(deadline.message()) : err instanceof Error ? err : new Error(String(err));
|
|
495
|
+
throw new BootstrapAttemptError(
|
|
496
|
+
error,
|
|
497
|
+
parserAttempted ? "rejected" : "not-run",
|
|
498
|
+
bootstrapTelemetry(
|
|
499
|
+
prompt,
|
|
500
|
+
text,
|
|
501
|
+
startedAt,
|
|
502
|
+
structuredOutputMode,
|
|
503
|
+
handle.runId,
|
|
504
|
+
receipt,
|
|
505
|
+
err instanceof BootstrapOutputLimitError ? err.observedBytes : void 0
|
|
506
|
+
)
|
|
507
|
+
);
|
|
508
|
+
} finally {
|
|
509
|
+
deadline.clear();
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
async function generateBootstrapWithModel(dispatch, input, route) {
|
|
513
|
+
const prompt = buildBootstrapPrompt(input);
|
|
514
|
+
const startedAt = Date.now();
|
|
515
|
+
input.progress?.({
|
|
516
|
+
phase: "generate",
|
|
517
|
+
status: "running",
|
|
518
|
+
message: "dispatching internal context-bootstrap agent",
|
|
519
|
+
detail: `agent=${CONTEXT_BOOTSTRAP_AGENT_ID}`
|
|
520
|
+
});
|
|
521
|
+
const dispatchBootstrap = (nativeSchema) => dispatch.dispatch({
|
|
522
|
+
agentId: CONTEXT_BOOTSTRAP_AGENT_ID,
|
|
523
|
+
executionRole: "researcher",
|
|
524
|
+
task: prompt,
|
|
525
|
+
cwd: input.cwd,
|
|
526
|
+
requestOrigin: "internal",
|
|
527
|
+
thinkingLevel: route?.thinkingLevel ?? "off",
|
|
528
|
+
noSkills: true,
|
|
529
|
+
...nativeSchema ? { responseSchema: BOOTSTRAP_OUTPUT_JSON_SCHEMA } : {},
|
|
530
|
+
...route ? { target: route.target } : {},
|
|
531
|
+
...route?.model ? { model: route.model } : {}
|
|
532
|
+
});
|
|
533
|
+
try {
|
|
534
|
+
return await attemptBootstrapDispatch(dispatch, input, prompt, startedAt, "native-schema", dispatchBootstrap);
|
|
535
|
+
} catch (err) {
|
|
536
|
+
const refusal = responseSchemaRefusal(err);
|
|
537
|
+
if (refusal === null) throw err;
|
|
538
|
+
input.progress?.({
|
|
539
|
+
phase: "generate",
|
|
540
|
+
status: "running",
|
|
541
|
+
message: "native schema unavailable; using bounded output parser",
|
|
542
|
+
detail: refusal
|
|
543
|
+
});
|
|
544
|
+
return await attemptBootstrapDispatch(dispatch, input, prompt, startedAt, "prompt-parser", dispatchBootstrap);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
async function loadBootstrapDispatch() {
|
|
548
|
+
const loaded = await loadDomains([
|
|
549
|
+
ConfigDomainModule,
|
|
550
|
+
ResourcesDomainModule,
|
|
551
|
+
ProvidersDomainModule,
|
|
552
|
+
SafetyDomainModule,
|
|
553
|
+
createPromptsDomainModule({ noContextFiles: true }),
|
|
554
|
+
AgentsDomainModule,
|
|
555
|
+
MiddlewareDomainModule,
|
|
556
|
+
SessionDomainModule,
|
|
557
|
+
// Same shape as the wiki writer: one internal dispatch in a process that
|
|
558
|
+
// exits with it. The SQLite mirror opens `node:sqlite` on the first
|
|
559
|
+
// dispatch event, which costs `clio-coder context init` a module load it never
|
|
560
|
+
// reads back and prints Node's ExperimentalWarning over the command's own
|
|
561
|
+
// output. Receipts and the ledger still record the run.
|
|
562
|
+
createObservabilityDomainModule({ dispatchTrace: false }),
|
|
563
|
+
SchedulingDomainModule,
|
|
564
|
+
DispatchDomainModule
|
|
565
|
+
]);
|
|
566
|
+
const dispatch = loaded.getContract("dispatch");
|
|
567
|
+
const config = loaded.getContract("config");
|
|
568
|
+
if (!dispatch || !config) {
|
|
569
|
+
await loaded.stop();
|
|
570
|
+
throw new Error("bootstrap dispatch or configuration unavailable");
|
|
571
|
+
}
|
|
572
|
+
return { dispatch, config, loaded };
|
|
573
|
+
}
|
|
574
|
+
function modelBootstrapGenerate(options = {}) {
|
|
575
|
+
return async (input) => {
|
|
576
|
+
let loaded = null;
|
|
577
|
+
try {
|
|
578
|
+
if (options.dispatch) {
|
|
579
|
+
const route = options.route ?? options.resolveRoute?.();
|
|
580
|
+
return await generateBootstrapWithModel(options.dispatch, input, route);
|
|
581
|
+
}
|
|
582
|
+
{
|
|
583
|
+
const lazy = await loadBootstrapDispatch();
|
|
584
|
+
loaded = lazy.loaded;
|
|
585
|
+
const route = options.route ?? resolveBootstrapRoute(lazy.config.get());
|
|
586
|
+
return await generateBootstrapWithModel(lazy.dispatch, input, route);
|
|
587
|
+
}
|
|
588
|
+
} catch (err) {
|
|
589
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
590
|
+
const fallback = fallbackBootstrapOutput(input);
|
|
591
|
+
const generation = {
|
|
592
|
+
mode: fallback.mode,
|
|
593
|
+
parserOutcome: err instanceof BootstrapAttemptError ? err.parserOutcome : "not-run",
|
|
594
|
+
fallbackReason: error.message,
|
|
595
|
+
...err instanceof BootstrapAttemptError ? { run: err.telemetry } : {}
|
|
596
|
+
};
|
|
597
|
+
input.progress?.({
|
|
598
|
+
phase: "generate",
|
|
599
|
+
status: "running",
|
|
600
|
+
message: fallback.mode === "existing" ? "bootstrap agent unavailable; preserving existing CLIO-CODER.md" : "bootstrap agent unavailable; using heuristic bootstrap",
|
|
601
|
+
detail: error.message
|
|
602
|
+
});
|
|
603
|
+
input.reportGeneration?.(generation);
|
|
604
|
+
options.onFallback?.(error, fallback.mode);
|
|
605
|
+
return fallback.output;
|
|
606
|
+
} finally {
|
|
607
|
+
if (loaded) await loaded.stop();
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// src/domains/context/init-options.ts
|
|
613
|
+
var CONTEXT_INIT_FLAG_TABLE = [
|
|
614
|
+
{ flag: "--preview", field: "preview" },
|
|
615
|
+
{ flag: "--adopt", field: "adopt" },
|
|
616
|
+
{ flag: "--apply", field: "applyClioMd" },
|
|
617
|
+
{ flag: "--rewrite", field: "rewriteClioMd" },
|
|
618
|
+
{ flag: "--propose", field: "proposeClioMd" },
|
|
619
|
+
{ flag: "--global", aliases: ["--include-global"], field: "includeGlobalImports" },
|
|
620
|
+
{ flag: "--heuristic", field: "heuristic" }
|
|
621
|
+
];
|
|
622
|
+
function applyInitImplications(options) {
|
|
623
|
+
if (options.applyClioMd === true || options.rewriteClioMd === true) {
|
|
624
|
+
return { ...options, applyClioMd: true };
|
|
625
|
+
}
|
|
626
|
+
return { ...options };
|
|
627
|
+
}
|
|
628
|
+
function validateInitOptions(options) {
|
|
629
|
+
if (options.proposeClioMd === true && (options.adopt === true || options.applyClioMd === true || options.rewriteClioMd === true)) {
|
|
630
|
+
return "clio-coder context init: --propose cannot be combined with --adopt, --apply, or --rewrite";
|
|
631
|
+
}
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
function bootstrapInputFromInitOptions(options) {
|
|
635
|
+
const implied = applyInitImplications(options);
|
|
636
|
+
const input = {};
|
|
637
|
+
for (const field of [
|
|
638
|
+
"preview",
|
|
639
|
+
"adopt",
|
|
640
|
+
"applyClioMd",
|
|
641
|
+
"rewriteClioMd",
|
|
642
|
+
"proposeClioMd",
|
|
643
|
+
"includeGlobalImports"
|
|
644
|
+
]) {
|
|
645
|
+
if (implied[field] !== void 0) {
|
|
646
|
+
input[field] = implied[field];
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return input;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
export {
|
|
653
|
+
resolveBootstrapRoute,
|
|
654
|
+
modelBootstrapGenerate,
|
|
655
|
+
CONTEXT_INIT_FLAG_TABLE,
|
|
656
|
+
validateInitOptions,
|
|
657
|
+
bootstrapInputFromInitOptions
|
|
658
|
+
};
|
|
659
|
+
//# sourceMappingURL=chunk-O4EJEDHO.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
printError
|
|
3
|
+
} from "./chunk-67MTHP2E.js";
|
|
4
|
+
import {
|
|
5
|
+
authStoragePath
|
|
6
|
+
} from "./chunk-5LDRNKX2.js";
|
|
7
|
+
|
|
8
|
+
// src/cli/shared.ts
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
function printPlaintextCredentialWarning() {
|
|
11
|
+
process.stderr.write(
|
|
12
|
+
`${chalk.yellow("warning:")} API key stored unencrypted at ${authStoragePath()} (mode 0600).
|
|
13
|
+
It is readable by any process running as you. To keep the key off disk, configure the
|
|
14
|
+
target with an environment variable instead: clio-coder configure ... --api-key-env <VAR>.
|
|
15
|
+
`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function credentialWriteFailed(auth, subject) {
|
|
19
|
+
const damage = auth.damageReason();
|
|
20
|
+
if (damage === null) return false;
|
|
21
|
+
printError(`${subject}: ${damage}`);
|
|
22
|
+
process.stderr.write(` ${authStoragePath()} is unchanged.
|
|
23
|
+
`);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
printPlaintextCredentialWarning,
|
|
29
|
+
credentialWriteFailed
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=chunk-PIDUD6M2.js.map
|