harnessed 3.9.20 → 3.9.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1231,7 +1231,7 @@ var init_auto_install = __esm({
1231
1231
 
1232
1232
  // package.json
1233
1233
  var package_default = {
1234
- version: "3.9.20"};
1234
+ version: "3.9.22"};
1235
1235
 
1236
1236
  // src/manifest/errors.ts
1237
1237
  function instancePathToKeyPath(instancePath) {
@@ -5479,7 +5479,58 @@ function registerRun(program2) {
5479
5479
  const stage = name.includes("-") ? name.split("-")[0] ?? "" : name;
5480
5480
  const gateContext = {
5481
5481
  task,
5482
- phase: { stage, is_critical_module: true },
5482
+ phase: {
5483
+ stage,
5484
+ // verify-stage gates
5485
+ is_critical_module: true,
5486
+ // verify-paranoid fires
5487
+ is_final_step: true,
5488
+ // verify-simplify fires
5489
+ is_major_release: false,
5490
+ // verify-multispec only for major
5491
+ has_auth_or_secrets: false,
5492
+ has_design_changes: false,
5493
+ has_ui_changes: false,
5494
+ requires_creative_polish: false,
5495
+ // plan-stage gates
5496
+ is_complex_architecture: true,
5497
+ // plan-architecture fires
5498
+ // discuss-stage gates
5499
+ has_cross_phase_data_flow: true,
5500
+ // discuss-phase fires
5501
+ open_decisions: 2,
5502
+ // ≥2 fires phase-gate
5503
+ scope_days: 2,
5504
+ // >1 day fires phase-gate
5505
+ scope_locked_in_history: false,
5506
+ single_task: false,
5507
+ type: "general"
5508
+ },
5509
+ subtask: {
5510
+ // subtask brainstorming gate
5511
+ approaches: 2,
5512
+ // ≥2 fires
5513
+ core_algorithm: true,
5514
+ has_api_contract: true,
5515
+ error_cost: "high",
5516
+ lines: 50,
5517
+ // ≥20 → no skip
5518
+ type: "general",
5519
+ // not crud/standard_lib_call → no skip
5520
+ // tdd gate
5521
+ is_core_business_logic: true,
5522
+ is_algorithm: true,
5523
+ is_data_processing: true,
5524
+ regression_risk: "high",
5525
+ reliability_required: true,
5526
+ // misc
5527
+ communication_needed: false,
5528
+ needs_lib_docs: false,
5529
+ needs_web_search: false,
5530
+ parallel_count: 1,
5531
+ search_type: "general",
5532
+ test_type: "general"
5533
+ },
5483
5534
  ...raw.model ? { modelOverride: raw.model } : {},
5484
5535
  ...raw.maxIterations ? { maxIterations: raw.maxIterations } : {},
5485
5536
  ...raw.staged ? { staged: true } : {},
@@ -6144,6 +6195,7 @@ async function runStepBInstall(manifestPaths, runOpts = {}) {
6144
6195
  quiet: runOpts.quiet === true
6145
6196
  };
6146
6197
  const start = Date.now();
6198
+ const componentTypes = {};
6147
6199
  const settled = await Promise.allSettled(
6148
6200
  manifestPaths.map(async (path) => {
6149
6201
  let yamlSrc;
@@ -6161,6 +6213,7 @@ async function runStepBInstall(manifestPaths, runOpts = {}) {
6161
6213
  };
6162
6214
  }
6163
6215
  const name = v.manifest.metadata.name;
6216
+ componentTypes[name] = v.manifest.spec.component_type;
6164
6217
  const r = await runInstall(v.manifest, opts);
6165
6218
  if ("aborted" in r) return { status: "skipped", name, reason: r.reason };
6166
6219
  if (r.ok && "alreadyInstalled" in r && r.alreadyInstalled)
@@ -6187,7 +6240,14 @@ async function runStepBInstall(manifestPaths, runOpts = {}) {
6187
6240
  } else
6188
6241
  failed.push(`${v.name}: ${v.reason}`);
6189
6242
  }
6190
- return { installed, alreadyInstalled, skipped, failed, elapsedMs: Date.now() - start };
6243
+ return {
6244
+ installed,
6245
+ alreadyInstalled,
6246
+ skipped,
6247
+ failed,
6248
+ elapsedMs: Date.now() - start,
6249
+ componentTypes
6250
+ };
6191
6251
  }
6192
6252
 
6193
6253
  // src/cli/setup.ts
@@ -6202,6 +6262,42 @@ async function listBaseManifests2(pkgRoot) {
6202
6262
  }
6203
6263
  return out;
6204
6264
  }
6265
+ function printGrouped(b, prefix = "") {
6266
+ const GROUP_LABELS = {
6267
+ "mcp-tool": "MCP servers",
6268
+ command: "Commands & Skills",
6269
+ "cli-binary": "CLI tools",
6270
+ other: "Other"
6271
+ };
6272
+ const GROUP_ORDER = ["mcp-tool", "command", "cli-binary", "other"];
6273
+ const groupOf = (n) => b.componentTypes[n] ?? "other";
6274
+ const buckets = {};
6275
+ for (const n of b.failed) {
6276
+ const m = n.match(/^([^:]+):/);
6277
+ const baseName = m?.[1] ?? n;
6278
+ (buckets[groupOf(baseName)] ??= []).push({ status: "failed", name: n });
6279
+ }
6280
+ for (const n of b.installed) (buckets[groupOf(n)] ??= []).push({ status: "installed", name: n });
6281
+ for (const s of b.skipped)
6282
+ (buckets[groupOf(s.name)] ??= []).push({
6283
+ status: "skipped",
6284
+ name: s.name,
6285
+ suffix: ` \u2014 ${s.reason}`
6286
+ });
6287
+ for (const n of b.alreadyInstalled)
6288
+ (buckets[groupOf(n)] ??= []).push({ status: "already-installed", name: n });
6289
+ for (const g of GROUP_ORDER) {
6290
+ const entries = buckets[g];
6291
+ if (!entries || entries.length === 0) continue;
6292
+ console.log(`
6293
+ ${prefix}${GROUP_LABELS[g] ?? g} (${entries.length})`);
6294
+ for (const e of entries) {
6295
+ const line = ` ${e.status.padEnd(18)} ${e.name}${e.suffix ?? ""}`;
6296
+ if (e.status === "failed") console.error(line);
6297
+ else console.log(line);
6298
+ }
6299
+ }
6300
+ }
6205
6301
  function registerSetup(program2) {
6206
6302
  program2.command("setup").description(
6207
6303
  "One-shot onboarding: install workflow skills + base manifests to ~/.claude/ (immediate by default \u2014 use --dry-run for preview)"
@@ -6310,10 +6406,7 @@ function registerSetup(program2) {
6310
6406
  seconds: stepBMs
6311
6407
  })
6312
6408
  );
6313
- for (const n of b.installed) console.log(` [B] installed ${n}`);
6314
- for (const n of b.alreadyInstalled) console.log(` [B] already-installed ${n}`);
6315
- for (const s of b.skipped) console.log(` [B] skipped ${s.name} \u2014 ${s.reason}`);
6316
- for (const n of b.failed) console.error(` [B] failed ${n}`);
6409
+ printGrouped(b);
6317
6410
  if (!forceFirstPass && !dryRun && raw.nonInteractive !== true && b.alreadyInstalled.length > 0) {
6318
6411
  const isTty = process.stdin.isTTY === true && process.stdout.isTTY === true;
6319
6412
  if (isTty) {
@@ -6329,12 +6422,7 @@ function registerSetup(program2) {
6329
6422
  `
6330
6423
  Force-update pass complete: ${b2.installed.length} installed / ${b2.alreadyInstalled.length} still-already-installed (MCP) / ${b2.skipped.length} skipped / ${b2.failed.length} failed [parallel ${stepB2Ms}s]`
6331
6424
  );
6332
- for (const n of b2.installed) console.log(` [B*] installed ${n}`);
6333
- for (const n of b2.alreadyInstalled)
6334
- console.log(` [B*] already-installed ${n} (MCP / no force-update)`);
6335
- for (const s of b2.skipped)
6336
- console.log(` [B*] skipped ${s.name} \u2014 ${s.reason}`);
6337
- for (const n of b2.failed) console.error(` [B*] failed ${n}`);
6425
+ printGrouped(b2, "[force-update] ");
6338
6426
  }
6339
6427
  }
6340
6428
  }