@glrs-dev/cli 1.2.0 → 2.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-assessor.md +77 -0
  3. package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-builder.md +24 -116
  4. package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-planner.md +38 -160
  5. package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-scoper.md +58 -0
  6. package/dist/vendor/harness-opencode/dist/{chunk-BWERBERN.js → chunk-6CZPRUMJ.js} +12 -62
  7. package/dist/vendor/harness-opencode/dist/chunk-DZG4D3OH.js +54 -0
  8. package/dist/vendor/harness-opencode/dist/chunk-OYRKOEXK.js +88 -0
  9. package/dist/vendor/harness-opencode/dist/cli.js +1631 -4224
  10. package/dist/vendor/harness-opencode/dist/index.js +831 -166
  11. package/dist/vendor/harness-opencode/dist/{install-5JKWK6Z4.js → install-6775ZBDG.js} +1 -1
  12. package/dist/vendor/harness-opencode/dist/paths-WZ23ZQOV.js +18 -0
  13. package/dist/vendor/harness-opencode/package.json +1 -1
  14. package/package.json +1 -1
  15. package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-builder.open.md +0 -129
  16. package/dist/vendor/harness-opencode/dist/chunk-57EOY72Y.js +0 -174
  17. package/dist/vendor/harness-opencode/dist/chunk-5TAMY7P6.js +0 -67
  18. package/dist/vendor/harness-opencode/dist/chunk-BKTFWXLG.js +0 -204
  19. package/dist/vendor/harness-opencode/dist/chunk-EK7K4NTV.js +0 -747
  20. package/dist/vendor/harness-opencode/dist/chunk-KB7M7JXU.js +0 -145
  21. package/dist/vendor/harness-opencode/dist/chunk-RNRCXQ65.js +0 -56
  22. package/dist/vendor/harness-opencode/dist/paths-LT3QQKCF.js +0 -18
  23. package/dist/vendor/harness-opencode/dist/pilot/mcp/status-server.d.ts +0 -1
  24. package/dist/vendor/harness-opencode/dist/pilot/mcp/status-server.js +0 -228
  25. package/dist/vendor/harness-opencode/dist/pilot-config-7LJZ23YK.js +0 -55
  26. package/dist/vendor/harness-opencode/dist/runs-QWPL3TKV.js +0 -18
  27. package/dist/vendor/harness-opencode/dist/safety-gate-WM3EWOCY.js +0 -10
  28. package/dist/vendor/harness-opencode/dist/setup-hook-FHTXMAQL.js +0 -88
  29. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/SKILL.md +0 -80
  30. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/dag-shape.md +0 -47
  31. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/decomposition.md +0 -63
  32. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/first-principles.md +0 -29
  33. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/milestones.md +0 -57
  34. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/qa-expectations.md +0 -120
  35. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/self-review.md +0 -46
  36. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/task-context.md +0 -47
  37. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/touches-scope.md +0 -81
  38. package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/verify-design.md +0 -163
  39. package/dist/vendor/harness-opencode/dist/tasks-KJ3WN2KY.js +0 -32
@@ -181,29 +181,6 @@ import * as fs2 from "fs";
181
181
  import * as path2 from "path";
182
182
  import * as os from "os";
183
183
  import { select, checkbox, confirm } from "@inquirer/prompts";
184
- var PLUGIN_NAME = "@glrs-dev/harness-plugin-opencode";
185
- function getOpencodeConfigPath() {
186
- const configHome = process.env["XDG_CONFIG_HOME"] ?? path2.join(os.homedir(), ".config");
187
- return path2.join(configHome, "opencode", "opencode.json");
188
- }
189
- function isPluginInstalled() {
190
- const configPath = getOpencodeConfigPath();
191
- if (!fs2.existsSync(configPath)) return false;
192
- try {
193
- const config = JSON.parse(fs2.readFileSync(configPath, "utf8"));
194
- const plugins = Array.isArray(config.plugin) ? config.plugin : [];
195
- return plugins.some((p) => {
196
- const name = typeof p === "string" ? p : Array.isArray(p) ? p[0] : null;
197
- return name === PLUGIN_NAME || String(name ?? "").startsWith(`${PLUGIN_NAME}@`);
198
- });
199
- } catch {
200
- return false;
201
- }
202
- }
203
- async function promptYesNo(question) {
204
- if (!process.stdin.isTTY) return false;
205
- return confirm({ message: question, default: false });
206
- }
207
184
  async function promptChoice(question, choices, defaultIndex = 0) {
208
185
  if (!process.stdin.isTTY) return defaultIndex;
209
186
  const answer = await select({
@@ -234,32 +211,6 @@ async function promptMulti(question, choices) {
234
211
  });
235
212
  return new Set(answers);
236
213
  }
237
- async function requirePlugin() {
238
- if (isPluginInstalled()) return;
239
- const c2 = {
240
- reset: "\x1B[0m",
241
- yellow: "\x1B[33m",
242
- red: "\x1B[31m"
243
- };
244
- console.error(
245
- `${c2.yellow}!${c2.reset} The OpenCode plugin is not installed. Pilot commands need the plugin to register the pilot-builder and pilot-planner agents.`
246
- );
247
- if (!process.stdin.isTTY) {
248
- console.error(
249
- `${c2.red}\u2717${c2.reset} Non-interactive terminal. Run: glrs-oc install-plugin`
250
- );
251
- process.exit(1);
252
- }
253
- const yes = await promptYesNo("Install the plugin now?");
254
- if (!yes) {
255
- console.error(
256
- `${c2.red}\u2717${c2.reset} Plugin required. Run: glrs-oc install-plugin`
257
- );
258
- process.exit(1);
259
- }
260
- const { install: install2 } = await import("./install-5JKWK6Z4.js");
261
- await install2({ nonInteractive: true });
262
- }
263
214
 
264
215
  // src/cli/models-dev.ts
265
216
  var MODELS_DEV_URL = "https://models.dev/api.json";
@@ -361,7 +312,7 @@ async function fetchModelsDevProviders() {
361
312
  }
362
313
 
363
314
  // src/cli/install.ts
364
- var PLUGIN_NAME2 = "@glrs-dev/harness-plugin-opencode";
315
+ var PLUGIN_NAME = "@glrs-dev/harness-plugin-opencode";
365
316
  var c = {
366
317
  reset: "\x1B[0m",
367
318
  green: "\x1B[32m",
@@ -405,7 +356,7 @@ function extractPluginOptions(config) {
405
356
  const plugins = config.plugin;
406
357
  if (!Array.isArray(plugins)) return null;
407
358
  for (const entry of plugins) {
408
- if (Array.isArray(entry) && entry.length >= 2 && (entry[0] === PLUGIN_NAME2 || String(entry[0]).startsWith(`${PLUGIN_NAME2}@`))) {
359
+ if (Array.isArray(entry) && entry.length >= 2 && (entry[0] === PLUGIN_NAME || String(entry[0]).startsWith(`${PLUGIN_NAME}@`))) {
409
360
  return entry[1];
410
361
  }
411
362
  }
@@ -421,17 +372,17 @@ function readPackageVersion() {
421
372
  try {
422
373
  const raw = fs3.readFileSync(candidate, "utf8");
423
374
  const parsed = JSON.parse(raw);
424
- if (parsed.name === PLUGIN_NAME2 && typeof parsed.version === "string") {
375
+ if (parsed.name === PLUGIN_NAME && typeof parsed.version === "string") {
425
376
  return parsed.version;
426
377
  }
427
378
  } catch {
428
379
  }
429
380
  }
430
381
  throw new Error(
431
- `Could not locate ${PLUGIN_NAME2}'s package.json to read version`
382
+ `Could not locate ${PLUGIN_NAME}'s package.json to read version`
432
383
  );
433
384
  }
434
- function getOpencodeConfigPath2() {
385
+ function getOpencodeConfigPath() {
435
386
  const configHome = process.env["XDG_CONFIG_HOME"] ?? path3.join(os2.homedir(), ".config");
436
387
  return path3.join(configHome, "opencode", "opencode.json");
437
388
  }
@@ -488,11 +439,11 @@ function migrateHarnessKeyToPluginOptions(configPath) {
488
439
  const plugins = Array.isArray(config.plugin) ? config.plugin : [];
489
440
  const pluginIdx = plugins.findIndex((entry) => {
490
441
  const name = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : null;
491
- return name === PLUGIN_NAME2 || String(name ?? "").startsWith(`${PLUGIN_NAME2}@`);
442
+ return name === PLUGIN_NAME || String(name ?? "").startsWith(`${PLUGIN_NAME}@`);
492
443
  });
493
444
  if (pluginIdx < 0) return;
494
445
  const current = plugins[pluginIdx];
495
- const existingName = typeof current === "string" ? current : Array.isArray(current) ? current[0] : PLUGIN_NAME2;
446
+ const existingName = typeof current === "string" ? current : Array.isArray(current) ? current[0] : PLUGIN_NAME;
496
447
  const existingOpts = Array.isArray(current) && current.length >= 2 ? current[1] : {};
497
448
  const merged = { ...config.harness, ...existingOpts };
498
449
  plugins[pluginIdx] = [existingName, merged];
@@ -533,13 +484,13 @@ function writePluginOption(configPath, subKey, value, opts) {
533
484
  }
534
485
  const pluginIdx = config.plugin.findIndex((entry) => {
535
486
  const name = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : null;
536
- return name === PLUGIN_NAME2 || String(name ?? "").startsWith(`${PLUGIN_NAME2}@`);
487
+ return name === PLUGIN_NAME || String(name ?? "").startsWith(`${PLUGIN_NAME}@`);
537
488
  });
538
489
  if (pluginIdx < 0) {
539
490
  return { changed: false };
540
491
  }
541
492
  const current = config.plugin[pluginIdx];
542
- const existingName = typeof current === "string" ? current : Array.isArray(current) ? current[0] : PLUGIN_NAME2;
493
+ const existingName = typeof current === "string" ? current : Array.isArray(current) ? current[0] : PLUGIN_NAME;
543
494
  const existingOpts = Array.isArray(current) && current.length >= 2 ? current[1] : {};
544
495
  if (deepEqual(existingOpts[subKey], value)) {
545
496
  return { changed: false };
@@ -617,14 +568,14 @@ function writeMcpToggles(configPath, enabledSet, opts) {
617
568
  }
618
569
  async function install(opts = {}) {
619
570
  const { dryRun = false, pin = false, nonInteractive = false } = opts;
620
- const configPath = getOpencodeConfigPath2();
621
- const pluginEntry = pin ? `${PLUGIN_NAME2}@${readPackageVersion()}` : PLUGIN_NAME2;
571
+ const configPath = getOpencodeConfigPath();
572
+ const pluginEntry = pin ? `${PLUGIN_NAME}@${readPackageVersion()}` : PLUGIN_NAME;
622
573
  const interactive = !nonInteractive && process.stdin.isTTY === true;
623
574
  const existing = readExistingConfig(configPath);
624
575
  const hasPlugin = existing ? (Array.isArray(existing.plugin) ? existing.plugin : []).some(
625
576
  (p) => {
626
577
  const name = typeof p === "string" ? p : Array.isArray(p) ? p[0] : null;
627
- return name === PLUGIN_NAME2 || String(name ?? "").startsWith(`${PLUGIN_NAME2}@`);
578
+ return name === PLUGIN_NAME || String(name ?? "").startsWith(`${PLUGIN_NAME}@`);
628
579
  }
629
580
  ) : false;
630
581
  const existingProvider = detectModelProvider(existing);
@@ -911,7 +862,6 @@ ${c.bold}Ready.${c.reset} Run ${c.green}opencode${c.reset} to start.
911
862
  }
912
863
 
913
864
  export {
914
- requirePlugin,
915
865
  MODEL_PRESETS,
916
866
  writePluginOption,
917
867
  writeMcpToggles,
@@ -0,0 +1,54 @@
1
+ // src/model-validator.ts
2
+ var CATWALK_PROVIDER_PATTERN = /^(?:bedrock|vertex|vertexai)\//;
3
+ var LEGACY_PRE_100_PATTERN = /^(bedrock|vertex|vertexai)\/claude-(opus|sonnet|haiku)(-\d+)?$/;
4
+ var LEGACY_TO_MODELS_DEV = {
5
+ // --- Pre-PR-#100 Bedrock (no subpath) ---
6
+ "bedrock/claude-opus": "amazon-bedrock/global.anthropic.claude-opus-4-7",
7
+ "bedrock/claude-opus-4": "amazon-bedrock/global.anthropic.claude-opus-4-7",
8
+ "bedrock/claude-sonnet": "amazon-bedrock/global.anthropic.claude-sonnet-4-6",
9
+ "bedrock/claude-sonnet-4": "amazon-bedrock/global.anthropic.claude-sonnet-4-6",
10
+ "bedrock/claude-haiku": "amazon-bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0",
11
+ "bedrock/claude-haiku-4": "amazon-bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0",
12
+ // --- Pre-Models.dev Bedrock (had subpath, but wrong provider prefix) ---
13
+ "bedrock/anthropic.claude-opus-4-6": "amazon-bedrock/global.anthropic.claude-opus-4-7",
14
+ "bedrock/anthropic.claude-opus-4-7": "amazon-bedrock/global.anthropic.claude-opus-4-7",
15
+ "bedrock/anthropic.claude-sonnet-4-6": "amazon-bedrock/global.anthropic.claude-sonnet-4-6",
16
+ "bedrock/anthropic.claude-haiku-4-5-20251001-v1:0": "amazon-bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0",
17
+ // --- Pre-PR-#100 Vertex (no @date suffix) ---
18
+ "vertex/claude-opus": "google-vertex-anthropic/claude-opus-4-7@default",
19
+ "vertex/claude-opus-4": "google-vertex-anthropic/claude-opus-4-7@default",
20
+ "vertex/claude-sonnet": "google-vertex-anthropic/claude-sonnet-4-6@default",
21
+ "vertex/claude-sonnet-4": "google-vertex-anthropic/claude-sonnet-4-6@default",
22
+ "vertex/claude-haiku": "google-vertex-anthropic/claude-haiku-4-5@20251001",
23
+ "vertex/claude-haiku-4": "google-vertex-anthropic/claude-haiku-4-5@20251001",
24
+ "vertexai/claude-opus": "google-vertex-anthropic/claude-opus-4-7@default",
25
+ "vertexai/claude-opus-4": "google-vertex-anthropic/claude-opus-4-7@default",
26
+ "vertexai/claude-sonnet": "google-vertex-anthropic/claude-sonnet-4-6@default",
27
+ "vertexai/claude-sonnet-4": "google-vertex-anthropic/claude-sonnet-4-6@default",
28
+ "vertexai/claude-haiku": "google-vertex-anthropic/claude-haiku-4-5@20251001",
29
+ "vertexai/claude-haiku-4": "google-vertex-anthropic/claude-haiku-4-5@20251001",
30
+ // --- Pre-Models.dev Vertex (had @date suffix, wrong provider prefix) ---
31
+ "vertexai/claude-opus-4-6@20250610": "google-vertex-anthropic/claude-opus-4-6@default",
32
+ "vertexai/claude-opus-4-7@20250610": "google-vertex-anthropic/claude-opus-4-7@default",
33
+ "vertexai/claude-sonnet-4-6@20250725": "google-vertex-anthropic/claude-sonnet-4-6@default",
34
+ "vertexai/claude-haiku-4-5@20251001": "google-vertex-anthropic/claude-haiku-4-5@20251001"
35
+ };
36
+ function validateModelOverride(id) {
37
+ if (typeof id !== "string") return { valid: true };
38
+ if (id.length === 0) return { valid: true };
39
+ if (CATWALK_PROVIDER_PATTERN.test(id)) {
40
+ const suggestion = LEGACY_TO_MODELS_DEV[id] ?? "run `bunx @glrs-dev/harness-plugin-opencode install` to pick a current preset";
41
+ const reason = LEGACY_PRE_100_PATTERN.test(id) ? `"${id}" is a pre-PR-#100 model ID format that does not resolve in OpenCode. Bedrock IDs need the \`amazon-bedrock\` provider prefix (not \`bedrock\`); Vertex Claude IDs need the \`google-vertex-anthropic\` provider prefix (not \`vertex\` / \`vertexai\`).` : `"${id}" uses a provider prefix (\`${id.split("/")[0]}\`) that does not exist in OpenCode's runtime. AWS Bedrock's provider ID is \`amazon-bedrock\`; Vertex Claude's is \`google-vertex-anthropic\`.`;
42
+ return { valid: false, reason, suggestion };
43
+ }
44
+ return { valid: true };
45
+ }
46
+ function formatModelOverrideWarning(id, source, suggestion) {
47
+ const suggestionText = suggestion ? ` Suggested replacement: \`${suggestion}\`.` : "";
48
+ return `[@glrs-dev/harness-plugin-opencode] Warning: invalid model override "${id}" (from ${source}).${suggestionText} Run \`bunx @glrs-dev/harness-plugin-opencode doctor\` for details.`;
49
+ }
50
+
51
+ export {
52
+ validateModelOverride,
53
+ formatModelOverrideWarning
54
+ };
@@ -0,0 +1,88 @@
1
+ // src/pilot/paths.ts
2
+ import { execFile } from "child_process";
3
+ import * as fs from "fs/promises";
4
+ import * as os from "os";
5
+ import * as path from "path";
6
+ function execFileP(file, args, opts = {}) {
7
+ const { cwd, timeoutMs = 5e3 } = opts;
8
+ return new Promise((resolve2, reject) => {
9
+ const controller = new AbortController();
10
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
11
+ execFile(
12
+ file,
13
+ args,
14
+ { signal: controller.signal, cwd, encoding: "utf8" },
15
+ (err, stdout) => {
16
+ clearTimeout(timer);
17
+ if (err) {
18
+ reject(err);
19
+ return;
20
+ }
21
+ resolve2(stdout ?? "");
22
+ }
23
+ );
24
+ });
25
+ }
26
+ function expandTilde(p) {
27
+ if (p === "~") return os.homedir();
28
+ if (p.startsWith("~/")) return path.join(os.homedir(), p.slice(2));
29
+ return p;
30
+ }
31
+ async function getRepoFolder(cwd) {
32
+ let stdout;
33
+ try {
34
+ stdout = await execFileP("git", ["rev-parse", "--git-common-dir"], { cwd });
35
+ } catch (err) {
36
+ throw new Error(
37
+ `pilot paths: could not determine repo folder from ${JSON.stringify(cwd)}: ${err instanceof Error ? err.message : String(err)}`
38
+ );
39
+ }
40
+ const gitCommonDir = stdout.trim();
41
+ const abs = path.isAbsolute(gitCommonDir) ? gitCommonDir : path.resolve(cwd, gitCommonDir);
42
+ return path.basename(path.dirname(abs));
43
+ }
44
+ async function getPilotDir(cwd) {
45
+ const override = process.env["GLORIOUS_PILOT_DIR"];
46
+ if (override) {
47
+ const dir = expandTilde(override);
48
+ await fs.mkdir(dir, { recursive: true });
49
+ return dir;
50
+ }
51
+ const repoFolder = await getRepoFolder(cwd);
52
+ const base = path.join(os.homedir(), ".glorious", "opencode", repoFolder, "pilot");
53
+ await fs.mkdir(base, { recursive: true });
54
+ return base;
55
+ }
56
+ async function getStateDbPath(cwd) {
57
+ const base = await getPilotDir(cwd);
58
+ return path.join(base, "state.sqlite");
59
+ }
60
+ async function getCurrentScopePath(cwd) {
61
+ const base = await getPilotDir(cwd);
62
+ return path.join(base, "current-scope.json");
63
+ }
64
+ async function getScopeArtifactPath(cwd, workflowId) {
65
+ const base = await getPilotDir(cwd);
66
+ const dir = path.join(base, "scopes", workflowId);
67
+ await fs.mkdir(dir, { recursive: true });
68
+ return path.join(dir, "scope.json");
69
+ }
70
+ async function getPlanArtifactPath(cwd, workflowId) {
71
+ const base = await getPilotDir(cwd);
72
+ const dir = path.join(base, "scopes", workflowId);
73
+ await fs.mkdir(dir, { recursive: true });
74
+ return path.join(dir, "plan.json");
75
+ }
76
+ function getPilotConfigPath(cwd) {
77
+ return path.join(cwd, ".glrs", "pilot.json");
78
+ }
79
+
80
+ export {
81
+ getRepoFolder,
82
+ getPilotDir,
83
+ getStateDbPath,
84
+ getCurrentScopePath,
85
+ getScopeArtifactPath,
86
+ getPlanArtifactPath,
87
+ getPilotConfigPath
88
+ };