@glrs-dev/cli 2.4.0 → 2.6.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/{chunk-HQUCVJ4G.js → chunk-FBXSGZAA.js} +4 -0
  3. package/dist/chunk-J3FXSHMA.js +263 -0
  4. package/dist/{chunk-5ZVUFNCP.js → chunk-S6N5E2GG.js} +8 -1
  5. package/dist/{chunk-2VMFXAJH.js → chunk-UO7WHIKY.js} +18 -5
  6. package/dist/cli.js +10 -3
  7. package/dist/commands/autopilot-tui.d.ts +11 -1
  8. package/dist/commands/autopilot-tui.js +2 -1
  9. package/dist/commands/autopilot.d.ts +2 -0
  10. package/dist/commands/autopilot.js +62 -21
  11. package/dist/commands/debrief.d.ts +2 -0
  12. package/dist/commands/debrief.js +1 -1
  13. package/dist/commands/loop.d.ts +2 -0
  14. package/dist/commands/loop.js +33 -12
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/node_modules/@glrs-dev/adapter-opencode/dist/index.d.ts +270 -0
  18. package/dist/node_modules/@glrs-dev/adapter-opencode/dist/index.js +506 -0
  19. package/dist/node_modules/@glrs-dev/adapter-opencode/package.json +8 -0
  20. package/dist/node_modules/@glrs-dev/autopilot/dist/auto-ship-EVLBKHUZ.js +7 -0
  21. package/dist/node_modules/@glrs-dev/autopilot/dist/changeset-generator-HAHYSSUR.js +15 -0
  22. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-2X3CWH47.js +3288 -0
  23. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-2ZQ6SBV3.js +70 -0
  24. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-6JZQLIRP.js +781 -0
  25. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-AWRK6S6G.js +91 -0
  26. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-BLEIZHET.js +101 -0
  27. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-GXXCEGDD.js +251 -0
  28. package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-S34HOCZ4.js +44 -0
  29. package/dist/node_modules/@glrs-dev/autopilot/dist/index.d.ts +1915 -0
  30. package/dist/node_modules/@glrs-dev/autopilot/dist/index.js +768 -0
  31. package/dist/node_modules/@glrs-dev/autopilot/dist/logger-3XLFMXLN.js +8 -0
  32. package/dist/node_modules/@glrs-dev/autopilot/dist/loop-session-YLCVJGPV.js +9 -0
  33. package/dist/node_modules/@glrs-dev/autopilot/dist/plan-enrichment-4SQYV5FC.js +17 -0
  34. package/dist/node_modules/@glrs-dev/autopilot/package.json +8 -0
  35. package/dist/vendor/harness-opencode/dist/agents/prompts/agents-md-writer.md +1 -1
  36. package/dist/vendor/harness-opencode/dist/agents/prompts/architecture-advisor.md +1 -1
  37. package/dist/vendor/harness-opencode/dist/agents/prompts/code-searcher.md +1 -1
  38. package/dist/vendor/harness-opencode/dist/agents/prompts/docs-maintainer.md +0 -8
  39. package/dist/vendor/harness-opencode/dist/agents/prompts/gap-analyzer.md +1 -3
  40. package/dist/vendor/harness-opencode/dist/agents/prompts/lib-reader.md +1 -1
  41. package/dist/vendor/harness-opencode/dist/agents/prompts/plan-reviewer.md +0 -2
  42. package/dist/vendor/harness-opencode/dist/agents/prompts/plan.md +1 -1
  43. package/dist/vendor/harness-opencode/dist/agents/prompts/prime.md +78 -262
  44. package/dist/vendor/harness-opencode/dist/agents/prompts/research.md +5 -14
  45. package/dist/vendor/harness-opencode/dist/agents/prompts/scoper.md +7 -2
  46. package/dist/vendor/harness-opencode/dist/autopilot/strategies/default.md +29 -0
  47. package/dist/vendor/harness-opencode/dist/index.js +112 -82
  48. package/dist/vendor/harness-opencode/package.json +1 -1
  49. package/package.json +9 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # @glrs-dev/cli
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#79](https://github.com/iceglober/glrs/pull/79) [`3d19166`](https://github.com/iceglober/glrs/commit/3d1916633ff6796238f08616c88038fd5b734174) Thanks [@iceglober](https://github.com/iceglober)! - Refactor harness subagent prompts for consistency and register `glrs loop` CLI subcommand.
8
+
9
+ **Harness prompt refactor:**
10
+
11
+ - Remove inline SPEAR protocol from prime.md (41% reduction); spear-protocol skill is now the sole canonical source
12
+ - Consolidate three identical reviewer permission blocks into one shared `REVIEWER_PERMISSIONS` constant
13
+ - Remove UI evaluation ladder from plan-reviewer and gap-analyzer (neither verifies web UI)
14
+ - Remove repo-specific assumptions from docs-maintainer prompt
15
+ - Fix broken bash snippet reference in scoper.md (was a placeholder, now the actual snippet)
16
+ - Fix circular self-reference in plan.md defensive posture section
17
+ - Standardize question-tool phrasing across all utility agents
18
+ - Clean up research.md self-reference and redundant invocation docs
19
+ - Update test assertions to match refactored content
20
+
21
+ **CLI:**
22
+
23
+ - Register `glrs loop` as a top-level subcommand (was defined but never routed)
24
+ - Add `glrs autopilot` and `glrs loop` to help text
25
+
26
+ ## 2.5.0
27
+
28
+ ### Patch Changes
29
+
30
+ - [#77](https://github.com/iceglober/glrs/pull/77) [`d684392`](https://github.com/iceglober/glrs/commit/d68439287a0a4bd9496011232e3e81d72bbda398) Thanks [@iceglober](https://github.com/iceglober)! - Fix phase cost summaries showing $0.00 by returning cumulativeCostUsd from all runRalphLoop exit paths. Route `glrs autopilot` through cmd-ts so --plan, --fast, and other flags are parsed.
31
+
32
+ - Updated dependencies [[`d684392`](https://github.com/iceglober/glrs/commit/d68439287a0a4bd9496011232e3e81d72bbda398)]:
33
+ - @glrs-dev/autopilot@0.1.1
34
+ - @glrs-dev/adapter-claude-code@0.1.1
35
+ - @glrs-dev/adapter-opencode@0.1.1
36
+
37
+ ## 2.4.1
38
+
39
+ ### Patch Changes
40
+
41
+ - [#75](https://github.com/iceglober/glrs/pull/75) [`9532a63`](https://github.com/iceglober/glrs/commit/9532a63157cc0edad7822452e710848052dde9fa) Thanks [@iceglober](https://github.com/iceglober)! - Fix `@glrs-dev/cli@2.4.0` install failure caused by `workspace:*` references to private packages leaking into the published tarball. The cli now vendors `@glrs-dev/autopilot` and `@glrs-dev/adapter-opencode` into its `dist/node_modules/` and strips workspace references from the published `package.json`.
42
+
3
43
  ## 2.4.0
4
44
 
5
45
  ## 2.3.0
@@ -52,6 +52,8 @@ USAGE
52
52
  SUBCOMMANDS
53
53
  oc OpenCode agent harness (install, pilot, etc.)
54
54
  wt Worktree management (create, list, switch, delete, cleanup)
55
+ autopilot Run the autopilot orchestrator (scope \u2192 plan \u2192 execute)
56
+ loop Run the Ralph loop with a raw prompt
55
57
  dashboard Live TUI dashboard for all running autopilot sessions
56
58
 
57
59
  Run 'glrs <subcommand> --help' for per-command help.
@@ -61,6 +63,8 @@ EXAMPLES
61
63
  glrs wt new
62
64
  glrs wt list
63
65
  glrs wt switch
66
+ glrs autopilot --plan docs/plans/my-plan/
67
+ glrs loop "implement the auth middleware"
64
68
  glrs dashboard
65
69
 
66
70
  REQUIREMENTS
@@ -0,0 +1,263 @@
1
+ // src/adapter-factory.ts
2
+ import { resolveModel } from "@glrs-dev/autopilot";
3
+ var ADAPTER_NAMES = ["opencode", "claude-code-cli"];
4
+ var DEFAULT_ADAPTER = "opencode";
5
+ async function createAdapter(name, config) {
6
+ const resolvedConfig = config || {
7
+ adapter: "opencode",
8
+ models: {
9
+ enrichment: "deep",
10
+ execution: "autopilot-execute",
11
+ debrief: "deep"
12
+ },
13
+ agents: {},
14
+ enrichment: {},
15
+ execution: {},
16
+ hooks: {},
17
+ phases: {},
18
+ adapters: {
19
+ opencode: { agents: {} },
20
+ claude_code_cli: { skip_permissions: true, allowed_tools: [] }
21
+ }
22
+ };
23
+ const adapter = resolvedConfig.adapter || "opencode";
24
+ switch (adapter) {
25
+ case "opencode": {
26
+ const { OpenCodeAdapter } = await import("@glrs-dev/adapter-opencode");
27
+ return new OpenCodeAdapter();
28
+ }
29
+ case "claude-code-cli": {
30
+ const { ClaudeCodeCliAdapter } = await import("@glrs-dev/adapter-claude-code");
31
+ const cliConfig = resolvedConfig.adapters?.claude_code_cli || {};
32
+ return new ClaudeCodeCliAdapter({
33
+ dangerouslySkipPermissions: cliConfig.skip_permissions ?? true,
34
+ models: {
35
+ enrich: resolveModel(resolvedConfig.models?.enrichment || "deep", "claude-code-cli"),
36
+ execute: resolveModel(resolvedConfig.models?.execution || "autopilot-execute", "claude-code-cli")
37
+ },
38
+ ...cliConfig.allowed_tools ? { allowedTools: cliConfig.allowed_tools } : {},
39
+ ...cliConfig.max_turns != null ? { maxTurns: cliConfig.max_turns } : {}
40
+ });
41
+ }
42
+ default:
43
+ throw new Error(
44
+ `Unknown adapter: ${adapter}. Available: ${ADAPTER_NAMES.join(", ")}`
45
+ );
46
+ }
47
+ }
48
+
49
+ // src/autopilot/config-reader.ts
50
+ import * as fs from "fs";
51
+ import * as path from "path";
52
+ import { parse as parseYaml } from "yaml";
53
+ import { z } from "zod";
54
+
55
+ // src/autopilot/autopilot-config.ts
56
+ var DEFAULT_AUTOPILOT_CONFIG = {
57
+ /** Default to OpenCode adapter. */
58
+ adapter: "opencode",
59
+ /** Default models — OpenCode tier names (interpreted by OpenCode adapter). */
60
+ models: {
61
+ enrichment: "deep",
62
+ execution: "autopilot-execute",
63
+ debrief: "deep"
64
+ },
65
+ /** No global agent overrides by default. */
66
+ agents: {},
67
+ /** No enrichment phase config by default. */
68
+ enrichment: {},
69
+ /** No execution phase config by default. */
70
+ execution: {},
71
+ /** No hooks by default. */
72
+ hooks: {},
73
+ /** No phase-specific config by default. */
74
+ phases: {},
75
+ /** No webhook notification by default. */
76
+ notify_url: void 0,
77
+ notify_events: void 0,
78
+ /** Default to TDD execution style. */
79
+ execution_style: "tdd",
80
+ /** Adapter-specific defaults for both adapters. */
81
+ adapters: {
82
+ /** OpenCode adapter — no agent overrides by default. */
83
+ opencode: {
84
+ agents: {}
85
+ },
86
+ /** Claude Code CLI adapter — skip permissions, allow all tools by default. */
87
+ claude_code_cli: {
88
+ skip_permissions: true,
89
+ allowed_tools: []
90
+ }
91
+ }
92
+ };
93
+
94
+ // src/autopilot/config-reader.ts
95
+ var ConfigPath = ".glrs/autopilot.yaml";
96
+ var AgentOverrideSchema = z.record(z.string(), z.unknown());
97
+ var PhaseConfigSchema = z.record(z.string(), z.unknown());
98
+ var ModelsSchema = z.object({
99
+ enrichment: z.string().optional(),
100
+ execution: z.string().optional(),
101
+ debrief: z.string().optional()
102
+ }).strict();
103
+ var OpencodeAdapterSchema = z.object({
104
+ agents: z.record(z.string(), AgentOverrideSchema).optional()
105
+ }).strict();
106
+ var ClaudeCodeCliAdapterSchema = z.object({
107
+ skip_permissions: z.boolean().optional(),
108
+ allowed_tools: z.array(z.string()).optional()
109
+ }).strict();
110
+ var AdaptersSchema = z.object({
111
+ opencode: OpencodeAdapterSchema.optional(),
112
+ claude_code_cli: ClaudeCodeCliAdapterSchema.optional()
113
+ }).strict();
114
+ var WebhookEventTypeSchema = z.enum([
115
+ "iteration_complete",
116
+ "phase_complete",
117
+ "run_complete",
118
+ "error",
119
+ "struggle",
120
+ "stall"
121
+ ]);
122
+ var AutopilotConfigSchema = z.object({
123
+ adapter: z.enum(["opencode", "claude-code-cli"]).optional(),
124
+ models: ModelsSchema.optional(),
125
+ agents: z.record(z.string(), AgentOverrideSchema).optional(),
126
+ enrichment: z.record(z.string(), z.unknown()).optional(),
127
+ execution: z.record(z.string(), z.unknown()).optional(),
128
+ hooks: z.record(z.string(), z.union([z.string(), z.array(z.string())])).optional(),
129
+ phases: z.record(z.string(), PhaseConfigSchema).optional(),
130
+ notify_url: z.string().optional(),
131
+ notify_events: z.array(WebhookEventTypeSchema).optional(),
132
+ adapters: AdaptersSchema.optional()
133
+ }).strict().transform((val) => val);
134
+ function readAutopilotConfig(repoRoot) {
135
+ const configPath = path.join(repoRoot, ConfigPath);
136
+ if (!fs.existsSync(configPath)) {
137
+ return null;
138
+ }
139
+ let fileContent;
140
+ try {
141
+ fileContent = fs.readFileSync(configPath, "utf8");
142
+ } catch (err) {
143
+ throw new Error(`Failed to read ${ConfigPath}: ${err instanceof Error ? err.message : String(err)}`);
144
+ }
145
+ let parsed;
146
+ try {
147
+ parsed = parseYaml(fileContent);
148
+ } catch (err) {
149
+ throw new Error(`Failed to parse ${ConfigPath}: ${err instanceof Error ? err.message : String(err)}`);
150
+ }
151
+ if (parsed === null || parsed === void 0) {
152
+ return {};
153
+ }
154
+ try {
155
+ return AutopilotConfigSchema.parse(parsed);
156
+ } catch (err) {
157
+ if (err instanceof z.ZodError) {
158
+ const unknownFields = err.issues.filter((issue) => issue.code === "unrecognized_keys").flatMap((issue) => issue.keys ? issue.keys : []);
159
+ if (unknownFields.length > 0) {
160
+ const fieldList = unknownFields.map((field) => `"${field}"`).join(", ");
161
+ throw new Error(`Invalid ${ConfigPath}: unknown keys: ${fieldList}`);
162
+ }
163
+ const messages = err.issues.map((issue) => {
164
+ const pathStr = issue.path.join(".");
165
+ return `${pathStr || "root"}: ${issue.message}`;
166
+ });
167
+ throw new Error(`Invalid ${ConfigPath}:
168
+ ${messages.join("\n")}`);
169
+ }
170
+ throw err;
171
+ }
172
+ }
173
+ function derivePlanSlug(planPath) {
174
+ if (!planPath || planPath === ".") {
175
+ return "";
176
+ }
177
+ const normalized = planPath.replace(/\/$/, "");
178
+ const basename2 = path.basename(normalized);
179
+ if (basename2.endsWith(".md")) {
180
+ return basename2.slice(0, -3);
181
+ }
182
+ return basename2;
183
+ }
184
+ function deepMerge(...objects) {
185
+ const result = {};
186
+ for (const obj of objects) {
187
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
188
+ continue;
189
+ }
190
+ for (const key in obj) {
191
+ const srcValue = obj[key];
192
+ if (srcValue && typeof srcValue === "object" && !Array.isArray(srcValue) && !(srcValue instanceof Date)) {
193
+ const targetValue = result[key];
194
+ if (targetValue && typeof targetValue === "object" && !Array.isArray(targetValue) && !(targetValue instanceof Date)) {
195
+ result[key] = deepMerge(
196
+ targetValue,
197
+ srcValue
198
+ );
199
+ } else {
200
+ result[key] = srcValue;
201
+ }
202
+ } else {
203
+ result[key] = srcValue;
204
+ }
205
+ }
206
+ }
207
+ return result;
208
+ }
209
+ function resolveConfig(repoRoot, planPath = ".") {
210
+ const projectConfig = readAutopilotConfig(repoRoot) ?? {};
211
+ const slug = derivePlanSlug(planPath);
212
+ let planConfig = {};
213
+ if (slug) {
214
+ const planConfigPath = path.join(repoRoot, ".glrs", "plans", slug, "autopilot.yaml");
215
+ if (fs.existsSync(planConfigPath)) {
216
+ let fileContent;
217
+ try {
218
+ fileContent = fs.readFileSync(planConfigPath, "utf8");
219
+ } catch (err) {
220
+ throw new Error(`Failed to read plan config at ${planConfigPath}: ${err instanceof Error ? err.message : String(err)}`);
221
+ }
222
+ let parsed;
223
+ try {
224
+ parsed = parseYaml(fileContent);
225
+ } catch (err) {
226
+ throw new Error(`Failed to parse plan config at ${planConfigPath}: ${err instanceof Error ? err.message : String(err)}`);
227
+ }
228
+ if (parsed !== null && parsed !== void 0) {
229
+ try {
230
+ planConfig = AutopilotConfigSchema.parse(parsed);
231
+ } catch (err) {
232
+ if (err instanceof z.ZodError) {
233
+ const unknownFields = err.issues.filter((issue) => issue.code === "unrecognized_keys").flatMap((issue) => issue.keys ? issue.keys : []);
234
+ if (unknownFields.length > 0) {
235
+ const fieldList = unknownFields.map((field) => `"${field}"`).join(", ");
236
+ throw new Error(`Invalid plan config at ${planConfigPath}: unknown keys: ${fieldList}`);
237
+ }
238
+ const messages = err.issues.map((issue) => {
239
+ const pathStr = issue.path.join(".");
240
+ return `${pathStr || "root"}: ${issue.message}`;
241
+ });
242
+ throw new Error(`Invalid plan config at ${planConfigPath}:
243
+ ${messages.join("\n")}`);
244
+ }
245
+ throw err;
246
+ }
247
+ }
248
+ }
249
+ }
250
+ const merged = deepMerge(
251
+ DEFAULT_AUTOPILOT_CONFIG,
252
+ projectConfig,
253
+ planConfig
254
+ );
255
+ return merged;
256
+ }
257
+
258
+ export {
259
+ ADAPTER_NAMES,
260
+ DEFAULT_ADAPTER,
261
+ createAdapter,
262
+ resolveConfig
263
+ };
@@ -1,4 +1,5 @@
1
1
  // src/commands/debrief.ts
2
+ import { resolveModel } from "@glrs-dev/autopilot/src/model-resolver.js";
2
3
  function shouldRunDebrief(opts) {
3
4
  if (opts.noDebrief) return false;
4
5
  const envVal = opts.env["GLRS_AUTOPILOT_DEBRIEF"];
@@ -112,8 +113,14 @@ async function runDebrief(opts) {
112
113
  try {
113
114
  const gitDiffStat = await _execGitDiffStat(opts.cwd).catch(() => "(git diff unavailable)");
114
115
  const contextMessage = buildContextMessage(opts.loopResult, opts.prompt, gitDiffStat);
116
+ const adapterName = adapter.name;
117
+ const cfgObj = opts.config;
118
+ const models = cfgObj?.models;
119
+ const debriefSpecifier = models?.debrief;
120
+ const debriefModel = debriefSpecifier ? resolveModel(debriefSpecifier, adapterName) : void 0;
115
121
  const sessionId = await adapter.createSession(handle, {
116
- agentName: "debriefer"
122
+ agentName: "debriefer",
123
+ model: debriefModel
117
124
  });
118
125
  await adapter.sendAndWait(handle, {
119
126
  sessionId,
@@ -1,3 +1,8 @@
1
+ import {
2
+ DEFAULT_ADAPTER,
3
+ createAdapter,
4
+ resolveConfig
5
+ } from "./chunk-J3FXSHMA.js";
1
6
  import {
2
7
  __require
3
8
  } from "./chunk-3RG5ZIWI.js";
@@ -456,14 +461,19 @@ function LogRow({ entry, maxWidth }) {
456
461
  }
457
462
  function applyEvent(prev, event) {
458
463
  switch (event.type) {
459
- case "session:start":
464
+ case "session:start": {
465
+ const adapterLabel = event.adapter ?? "opencode";
466
+ const branchLabel = event.branch ?? "unknown";
467
+ const logs = appendLog(prev.logEntries, `${event.cwd} \xB7 ${branchLabel} \xB7 ${adapterLabel}`);
468
+ const logs2 = appendLog(logs, `enrich: ${event.enrichModel ?? "unknown"} \xB7 execute: ${event.executeModel ?? "unknown"}`);
460
469
  return {
461
470
  ...prev,
462
471
  planPath: event.planPath,
463
472
  startedAt: Date.now(),
464
473
  executionMode: event.fast ? "fast" : "deep",
465
- logEntries: appendLog(prev.logEntries, `session started (enrich: ${event.enrichModel ?? "prime"} \xB7 execute: ${event.executeModel ?? "build"})`)
474
+ logEntries: logs2
466
475
  };
476
+ }
467
477
  case "enrich:start":
468
478
  return {
469
479
  ...prev,
@@ -728,8 +738,7 @@ function applyEvent(prev, event) {
728
738
 
729
739
  // src/commands/autopilot-tui.ts
730
740
  import { SessionRunner } from "@glrs-dev/autopilot";
731
- import { OpenCodeAdapter } from "@glrs-dev/adapter-opencode";
732
- async function runAutopilot() {
741
+ async function runAutopilot(adapterName) {
733
742
  const cwd = process.cwd();
734
743
  if (!process.stderr.isTTY) {
735
744
  process.stderr.write("glrs autopilot requires a TTY.\n");
@@ -739,7 +748,11 @@ async function runAutopilot() {
739
748
  if (!planPath) {
740
749
  return;
741
750
  }
742
- const adapter = new OpenCodeAdapter();
751
+ const config = resolveConfig(cwd, planPath);
752
+ if (adapterName) {
753
+ config.adapter = adapterName;
754
+ }
755
+ const adapter = await createAdapter(config.adapter ?? DEFAULT_ADAPTER, config);
743
756
  const runner = new SessionRunner({
744
757
  planPath,
745
758
  cwd,
package/dist/cli.js CHANGED
@@ -20,10 +20,11 @@ import {
20
20
  SUBCOMMANDS,
21
21
  WORKTREE_HELP_TEXT,
22
22
  resolveSubcommand
23
- } from "./chunk-HQUCVJ4G.js";
23
+ } from "./chunk-FBXSGZAA.js";
24
24
  import {
25
25
  runAutopilot
26
- } from "./chunk-2VMFXAJH.js";
26
+ } from "./chunk-UO7WHIKY.js";
27
+ import "./chunk-J3FXSHMA.js";
27
28
  import {
28
29
  cleanup
29
30
  } from "./chunk-2P3ETOT2.js";
@@ -97,8 +98,14 @@ if (sub === "wt" || sub === "worktree") {
97
98
  await run(wt, wtArgs);
98
99
  process.exit(0);
99
100
  }
101
+ if (sub === "loop") {
102
+ const { loopCmd } = await import("./commands/loop.js");
103
+ await run(loopCmd, args.slice(1));
104
+ process.exit(0);
105
+ }
100
106
  if (sub === "autopilot") {
101
- await runAutopilot();
107
+ const { autopilotInteractiveCmd } = await import("./commands/autopilot.js");
108
+ await run(autopilotInteractiveCmd, args.slice(1));
102
109
  process.exit(0);
103
110
  }
104
111
  if (sub === "dashboard") {
@@ -1,7 +1,17 @@
1
+ /**
2
+ * Adapter factory — resolves an adapter name to an AgentAdapter instance.
3
+ *
4
+ * Used by autopilot, loop, and TUI commands. Reads the resolved AutopilotConfig
5
+ * to configure adapter-specific settings (models, permissions, etc).
6
+ */
7
+
8
+ declare const ADAPTER_NAMES: readonly ["opencode", "claude-code-cli"];
9
+ type AdapterName = (typeof ADAPTER_NAMES)[number];
10
+
1
11
  /**
2
12
  * `glrs autopilot` — TUI plan picker at cwd, then run the autopilot session
3
13
  * with live event rendering to stderr.
4
14
  */
5
- declare function runAutopilot(): Promise<void>;
15
+ declare function runAutopilot(adapterName?: AdapterName): Promise<void>;
6
16
 
7
17
  export { runAutopilot };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  runAutopilot
3
- } from "../chunk-2VMFXAJH.js";
3
+ } from "../chunk-UO7WHIKY.js";
4
+ import "../chunk-J3FXSHMA.js";
4
5
  import "../chunk-3RG5ZIWI.js";
5
6
  export {
6
7
  runAutopilot
@@ -23,6 +23,7 @@ declare const autopilotInteractiveCmd: Partial<cmd_ts_dist_cjs_argparser_js.Regi
23
23
  parallel: number | undefined;
24
24
  ship: boolean;
25
25
  status: boolean;
26
+ adapter: string | undefined;
26
27
  }>>;
27
28
  } & cmd_ts_dist_cjs_helpdoc_js.PrintHelp & cmd_ts_dist_cjs_helpdoc_js.ProvidesHelp & cmd_ts_dist_cjs_helpdoc_js.Named & Partial<cmd_ts_dist_cjs_helpdoc_js.Versioned> & cmd_ts_dist_cjs_argparser_js.Register & cmd_ts_dist_cjs_runner_js.Handling<{
28
29
  plan: string | undefined;
@@ -32,6 +33,7 @@ declare const autopilotInteractiveCmd: Partial<cmd_ts_dist_cjs_argparser_js.Regi
32
33
  parallel: number | undefined;
33
34
  ship: boolean;
34
35
  status: boolean;
36
+ adapter: string | undefined;
35
37
  }, Promise<void>> & {
36
38
  run(context: cmd_ts_dist_cjs_argparser_js.ParseContext): Promise<cmd_ts_dist_cjs_argparser_js.ParsingResult<Promise<void>>>;
37
39
  } & Partial<cmd_ts_dist_cjs_helpdoc_js.Versioned & cmd_ts_dist_cjs_helpdoc_js.Descriptive & cmd_ts_dist_cjs_helpdoc_js.Aliased>;
@@ -1,10 +1,16 @@
1
+ import {
2
+ ADAPTER_NAMES,
3
+ DEFAULT_ADAPTER,
4
+ createAdapter,
5
+ resolveConfig
6
+ } from "../chunk-J3FXSHMA.js";
1
7
  import "../chunk-3RG5ZIWI.js";
2
8
 
3
9
  // src/commands/autopilot.ts
4
- import { command, flag, option, optional, string as stringType, number as numberType } from "cmd-ts";
10
+ import { command, flag, option, optional, string as stringType, number as numberType, oneOf } from "cmd-ts";
5
11
  import * as path from "path";
6
12
  import * as fs from "fs";
7
- import { formatElapsed, formatCost as formatCost2, EventStreamReader, deriveState } from "@glrs-dev/autopilot";
13
+ import { formatElapsed, formatCost as formatCost2, EventStreamReader, deriveState, applyCLIOverrides } from "@glrs-dev/autopilot";
8
14
  import { SessionRunner } from "@glrs-dev/autopilot";
9
15
 
10
16
  // src/cli-renderer.ts
@@ -218,9 +224,15 @@ var autopilotInteractiveCmd = command({
218
224
  status: flag({
219
225
  long: "status",
220
226
  description: "Read and pretty-print the current autopilot status from .agent/autopilot-status.json. Exits 0 if found, 1 if not running."
227
+ }),
228
+ adapter: option({
229
+ long: "adapter",
230
+ short: "a",
231
+ type: optional(oneOf(ADAPTER_NAMES)),
232
+ description: `Agent adapter to use (default: ${DEFAULT_ADAPTER}). Available: ${ADAPTER_NAMES.join(", ")}`
221
233
  })
222
234
  },
223
- handler: async ({ plan, fast, resume, maxIterationsPerPhase, parallel, ship, status }) => {
235
+ handler: async ({ plan, fast, resume, maxIterationsPerPhase, parallel, ship, status, adapter: adapterName }) => {
224
236
  const cwd = process.cwd();
225
237
  if (status) {
226
238
  const eventFilePath = path.join(cwd, ".agent", "autopilot-events.jsonl");
@@ -340,6 +352,15 @@ var autopilotInteractiveCmd = command({
340
352
  }
341
353
  planPath = picked;
342
354
  }
355
+ const resolvedConfig = resolveConfig(cwd, planPath);
356
+ const config = applyCLIOverrides(resolvedConfig, {
357
+ adapter: adapterName,
358
+ fast,
359
+ resume,
360
+ maxIterationsPerPhase,
361
+ parallel,
362
+ ship
363
+ });
343
364
  const { validatePlan } = await import("@glrs-dev/autopilot");
344
365
  const validation = validatePlan(path.resolve(process.cwd(), planPath));
345
366
  for (const w of validation.warnings) {
@@ -364,30 +385,50 @@ var autopilotInteractiveCmd = command({
364
385
  process.stderr.write("\n\x1B[1m\u2192 Enriching plan for fast execution\x1B[0m (deep model reads codebase, adds context)\n");
365
386
  process.stderr.write(" Adding mirror refs, code pointers, and conventions...\n");
366
387
  }
367
- const runner = new SessionRunner({
368
- planPath: path.resolve(process.cwd(), planPath),
369
- cwd: process.cwd(),
370
- fast,
371
- resume,
372
- maxIterationsPerPhase,
373
- parallel,
374
- ship
375
- });
376
- const renderer = createCliRenderer(runner.events);
377
- const result = await runner.run();
378
- renderer.unsubscribe();
379
- if (fast && planPath) {
380
- process.stderr.write(" \u2713 Plan enriched \u2014 executing with fast model (mid-execute tier)\n\n");
388
+ const priorAgentOverridesEnv = process.env["GLRS_AGENT_OVERRIDES"];
389
+ const finalAdapterName = config.adapter ?? DEFAULT_ADAPTER;
390
+ if (finalAdapterName === "opencode") {
391
+ const agentOverrides = config.adapters?.opencode?.agents;
392
+ if (agentOverrides && Object.keys(agentOverrides).length > 0) {
393
+ process.env["GLRS_AGENT_OVERRIDES"] = JSON.stringify(agentOverrides);
394
+ }
381
395
  }
382
- const costStr = result.loopResult.cumulativeCostUsd ? ` \xB7 $${result.loopResult.cumulativeCostUsd.toFixed(2)}` : "";
383
- process.stdout.write(
384
- `
396
+ try {
397
+ const adapter = await createAdapter(finalAdapterName, config);
398
+ const runner = new SessionRunner({
399
+ planPath: path.resolve(process.cwd(), planPath),
400
+ cwd: process.cwd(),
401
+ fast,
402
+ resume,
403
+ maxIterationsPerPhase,
404
+ parallel,
405
+ ship,
406
+ adapter,
407
+ enrichmentConfig: config.enrichment,
408
+ config
409
+ });
410
+ const renderer = createCliRenderer(runner.events);
411
+ const result = await runner.run();
412
+ renderer.unsubscribe();
413
+ if (fast && planPath) {
414
+ process.stderr.write(" \u2713 Plan enriched \u2014 executing with fast model (mid-execute tier)\n\n");
415
+ }
416
+ const costStr = result.loopResult.cumulativeCostUsd ? ` \xB7 $${result.loopResult.cumulativeCostUsd.toFixed(2)}` : "";
417
+ process.stdout.write(
418
+ `
385
419
  \x1B[1m\u2713 Autopilot complete\x1B[0m
386
420
  Plan: ${result.planPath}
387
421
  Result: ${result.loopResult.exitReason} after ${result.loopResult.iterations} iteration(s)${costStr}
388
422
 
389
423
  `
390
- );
424
+ );
425
+ } finally {
426
+ if (priorAgentOverridesEnv === void 0) {
427
+ delete process.env["GLRS_AGENT_OVERRIDES"];
428
+ } else {
429
+ process.env["GLRS_AGENT_OVERRIDES"] = priorAgentOverridesEnv;
430
+ }
431
+ }
391
432
  }
392
433
  });
393
434
  export {
@@ -26,6 +26,8 @@ interface DebriefOptions {
26
26
  prompt: string;
27
27
  /** Working directory (used for git diff stat). */
28
28
  cwd: string;
29
+ /** Autopilot configuration (for model resolution). */
30
+ config?: unknown;
29
31
  /**
30
32
  * Injectable dependencies for testing.
31
33
  * @internal
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  runDebrief,
3
3
  shouldRunDebrief
4
- } from "../chunk-5ZVUFNCP.js";
4
+ } from "../chunk-S6N5E2GG.js";
5
5
  import "../chunk-3RG5ZIWI.js";
6
6
  export {
7
7
  runDebrief,
@@ -26,6 +26,7 @@ declare const loopCmd: Partial<cmd_ts_dist_cjs_argparser_js.Register> & {
26
26
  noDebrief: boolean;
27
27
  notify: string | undefined;
28
28
  debriefOnly: boolean;
29
+ adapter: string | undefined;
29
30
  }>>;
30
31
  } & cmd_ts_dist_cjs_helpdoc_js.PrintHelp & cmd_ts_dist_cjs_helpdoc_js.ProvidesHelp & cmd_ts_dist_cjs_helpdoc_js.Named & Partial<cmd_ts_dist_cjs_helpdoc_js.Versioned> & cmd_ts_dist_cjs_argparser_js.Register & cmd_ts_dist_cjs_runner_js.Handling<{
31
32
  prompt: string;
@@ -35,6 +36,7 @@ declare const loopCmd: Partial<cmd_ts_dist_cjs_argparser_js.Register> & {
35
36
  noDebrief: boolean;
36
37
  notify: string | undefined;
37
38
  debriefOnly: boolean;
39
+ adapter: string | undefined;
38
40
  }, Promise<never>> & {
39
41
  run(context: cmd_ts_dist_cjs_argparser_js.ParseContext): Promise<cmd_ts_dist_cjs_argparser_js.ParsingResult<Promise<never>>>;
40
42
  } & Partial<cmd_ts_dist_cjs_helpdoc_js.Versioned & cmd_ts_dist_cjs_helpdoc_js.Descriptive & cmd_ts_dist_cjs_helpdoc_js.Aliased>;