@cardor/agent-harness-kit 1.10.3 → 1.10.4

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.js CHANGED
@@ -1,15 +1,18 @@
1
1
  import {
2
2
  findConfigFile,
3
3
  loadConfig
4
- } from "./chunk-ADV7OPU2.js";
4
+ } from "./chunk-D64KK6UU.js";
5
5
  import {
6
+ DEFAULT_MARKDOWN_PATH,
7
+ DEFAULT_SQLITE_PATH,
6
8
  getRowCounts,
7
9
  isEmptyDatabase,
8
10
  openDB,
9
11
  readStorageStateFile,
10
12
  resolveGlobalStorageDir,
13
+ resolveSqlitePath,
11
14
  resolveSqlitePathForScope
12
- } from "./chunk-DNFFWQWR.js";
15
+ } from "./chunk-6PEIJ2D5.js";
13
16
 
14
17
  // src/cli.ts
15
18
  import { Command } from "commander";
@@ -532,6 +535,8 @@ function modelField(model) {
532
535
  }
533
536
  function configObjectBody(params) {
534
537
  const models = params.models ?? {};
538
+ const isGlobal = params.scope === "global";
539
+ const markdownFallbackLine = isGlobal ? `markdownFallback: { enabled: true },` : `markdownFallback: { enabled: true, path: '.harness/current.md' },`;
535
540
  return ` project: {
536
541
  name: ${JSON.stringify(params.name)},
537
542
  description: ${JSON.stringify(params.description)},
@@ -552,7 +557,7 @@ function configObjectBody(params) {
552
557
  // SQLite (default). Switch to postgres/mysql by changing database.type.
553
558
  // database: { type: 'postgres', connectionString: process.env.DATABASE_URL },
554
559
  // database: { type: 'mysql', connectionString: process.env.DATABASE_URL },
555
- database: { type: 'sqlite', path: '.harness/harness.db' },
560
+ database: { type: 'sqlite' },
556
561
 
557
562
  storage: {
558
563
  dir: '.harness',
@@ -564,7 +569,7 @@ function configObjectBody(params) {
564
569
  blockers: true,
565
570
  nextSteps: false,
566
571
  },
567
- markdownFallback: { enabled: true, path: '.harness/current.md' },
572
+ ${markdownFallbackLine}
568
573
  // 'local' \u2014 DB lives in .harness/ (project-relative). 'global' \u2014 DB lives
569
574
  // under ~/.harness/dbs/<projectId>/, outside the project tree.
570
575
  scope: '${params.scope}',
@@ -763,7 +768,7 @@ var ClaudeCodeMaterializer = class {
763
768
  }
764
769
  const tasks = opts.firstTask ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }] : [];
765
770
  write(cwd2, "feature_list.json", featureListJson(tasks));
766
- if (!existsSync4(join5(cwd2, config.storage.markdownFallback.path))) {
771
+ if (config.storage.scope === "local" && !existsSync4(join5(cwd2, config.storage.markdownFallback.path))) {
767
772
  write(
768
773
  cwd2,
769
774
  config.storage.markdownFallback.path,
@@ -875,7 +880,7 @@ var CodexCliMaterializer = class {
875
880
  }
876
881
  const tasks = opts.firstTask ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }] : [];
877
882
  write2(join6(config.storage.dir, "feature_list.json"), featureListJson(tasks));
878
- if (!existsSync5(join6(cwd2, config.storage.markdownFallback.path))) {
883
+ if (config.storage.scope === "local" && !existsSync5(join6(cwd2, config.storage.markdownFallback.path))) {
879
884
  write2(
880
885
  config.storage.markdownFallback.path,
881
886
  `<!-- AUTO-GENERATED by agent-harness-kit \u2014 DO NOT EDIT MANUALLY -->
@@ -954,7 +959,7 @@ var OpenCodeMaterializer = class {
954
959
  }
955
960
  const tasks = opts.firstTask ? [{ slug: slugify(opts.firstTask.title), ...opts.firstTask }] : [];
956
961
  write2(join7(config.storage.dir, "feature_list.json"), featureListJson(tasks));
957
- if (!existsSync6(join7(cwd2, config.storage.markdownFallback.path))) {
962
+ if (config.storage.scope === "local" && !existsSync6(join7(cwd2, config.storage.markdownFallback.path))) {
958
963
  write2(
959
964
  config.storage.markdownFallback.path,
960
965
  `<!-- AUTO-GENERATED by agent-harness-kit \u2014 DO NOT EDIT MANUALLY -->
@@ -1059,7 +1064,8 @@ async function buildOnce(cwd2) {
1059
1064
  }
1060
1065
 
1061
1066
  // src/commands/dashboard.ts
1062
- import { dirname as dirname4, join as join9, resolve as resolve6 } from "path";
1067
+ import { homedir } from "os";
1068
+ import { dirname as dirname4, join as join9 } from "path";
1063
1069
  import { fileURLToPath as fileURLToPath3 } from "url";
1064
1070
  import pc2 from "picocolors";
1065
1071
 
@@ -1074,11 +1080,11 @@ import { WebSocketServer } from "ws";
1074
1080
  // src/core/port-utils.ts
1075
1081
  import { createServer } from "net";
1076
1082
  function isPortFree(port) {
1077
- return new Promise((resolve13) => {
1083
+ return new Promise((resolve12) => {
1078
1084
  const server = createServer();
1079
- server.once("error", () => resolve13(false));
1085
+ server.once("error", () => resolve12(false));
1080
1086
  server.once("listening", () => {
1081
- server.close(() => resolve13(true));
1087
+ server.close(() => resolve12(true));
1082
1088
  });
1083
1089
  server.listen(port, "127.0.0.1");
1084
1090
  });
@@ -1272,7 +1278,7 @@ var __dirname3 = dirname4(fileURLToPath3(import.meta.url));
1272
1278
  async function runDashboard(cwd2, opts) {
1273
1279
  const config = await loadConfig(cwd2);
1274
1280
  const db = await openDB(config, cwd2);
1275
- const dbPath = config.database.type === "sqlite" ? resolve6(cwd2, config.database.path) : null;
1281
+ const dbPath = config.database.type === "sqlite" ? resolveSqlitePath(config, cwd2, homedir()) : null;
1276
1282
  const staticPath = join9(__dirname3, "dashboard-dist");
1277
1283
  const { url } = await startDashboardServer(db, dbPath, staticPath, opts.port);
1278
1284
  console.log(pc2.green(`\u2713`) + ` Dashboard running at ${pc2.bold(pc2.cyan(url))}`);
@@ -1601,7 +1607,8 @@ async function runExport(cwd2, opts) {
1601
1607
  // src/commands/health.ts
1602
1608
  import { spawnSync } from "child_process";
1603
1609
  import { existsSync as existsSync10 } from "fs";
1604
- import { join as join12, resolve as resolve7 } from "path";
1610
+ import { homedir as homedir2 } from "os";
1611
+ import { join as join12, resolve as resolve6 } from "path";
1605
1612
  import pc5 from "picocolors";
1606
1613
  function checkLine(label, ok3, message, indent = 0) {
1607
1614
  const prefix = label ? pc5.cyan(`[${label}] `) : " ".repeat(indent);
@@ -1619,9 +1626,9 @@ async function runHealth(cwd2) {
1619
1626
  let allOk = true;
1620
1627
  let dbOk;
1621
1628
  if (config.database.type === "sqlite") {
1622
- const dbPath = resolve7(cwd2, config.database.path);
1629
+ const dbPath = resolveSqlitePath(config, cwd2, homedir2());
1623
1630
  dbOk = existsSync10(dbPath);
1624
- checkLine("checking DB", dbOk, `${config.database.path} reachable`);
1631
+ checkLine("checking DB", dbOk, `${dbPath} reachable`);
1625
1632
  } else {
1626
1633
  dbOk = true;
1627
1634
  checkLine("checking DB", true, `${config.database.type}://${config.database.connectionString.replace(/:[^:@]*@/, ":***@")} configured`);
@@ -1645,7 +1652,7 @@ async function runHealth(cwd2) {
1645
1652
  }
1646
1653
  if (config.tools.mcp.enabled) {
1647
1654
  const mcpFile = providerFiles.mcpFile;
1648
- const mcpPath = resolve7(cwd2, mcpFile);
1655
+ const mcpPath = resolve6(cwd2, mcpFile);
1649
1656
  const mcpOk = existsSync10(mcpPath);
1650
1657
  checkLine("checking MCP", mcpOk, `${mcpFile} valid`);
1651
1658
  if (!mcpOk) allOk = false;
@@ -1655,7 +1662,7 @@ async function runHealth(cwd2) {
1655
1662
  console.error(pc5.red("\u2717 Harness checks failed \u2014 fix the above before running health.sh"));
1656
1663
  process.exit(1);
1657
1664
  }
1658
- const scriptPath = resolve7(cwd2, config.health.scriptPath);
1665
+ const scriptPath = resolve6(cwd2, config.health.scriptPath);
1659
1666
  if (!existsSync10(scriptPath)) {
1660
1667
  console.error(pc5.red(`\u2717 health.sh not found: ${scriptPath}`));
1661
1668
  console.error(" Run ahk init first.");
@@ -1778,6 +1785,20 @@ function detectConfigExtension(cwd2) {
1778
1785
  }
1779
1786
  function applyConfigDefaults(params) {
1780
1787
  const models = params.models ?? {};
1788
+ const scope = params.scope ?? "local";
1789
+ const projectId = params.projectId ?? randomUUID();
1790
+ const baseStorage = {
1791
+ dir: ".harness",
1792
+ tasks: { adapter: params.tasksAdapter },
1793
+ sections: {
1794
+ toolsUsed: true,
1795
+ filesModified: true,
1796
+ result: true,
1797
+ blockers: true,
1798
+ nextSteps: false
1799
+ }
1800
+ };
1801
+ const storage = scope === "global" ? { ...baseStorage, markdownFallback: { enabled: true }, scope: "global", projectId } : { ...baseStorage, markdownFallback: { enabled: true, path: ".harness/current.md" }, scope: "local", projectId };
1781
1802
  return {
1782
1803
  provider: params.provider,
1783
1804
  project: {
@@ -1802,21 +1823,8 @@ function applyConfigDefaults(params) {
1802
1823
  ...models.consultant && { consultant: { instructionsPath: null, model: models.consultant } },
1803
1824
  custom: []
1804
1825
  },
1805
- database: { type: "sqlite", path: ".harness/harness.db" },
1806
- storage: {
1807
- dir: ".harness",
1808
- tasks: { adapter: params.tasksAdapter },
1809
- sections: {
1810
- toolsUsed: true,
1811
- filesModified: true,
1812
- result: true,
1813
- blockers: true,
1814
- nextSteps: false
1815
- },
1816
- markdownFallback: { enabled: true, path: ".harness/current.md" },
1817
- scope: params.scope ?? "local",
1818
- projectId: params.projectId ?? randomUUID()
1819
- },
1826
+ database: { type: "sqlite" },
1827
+ storage,
1820
1828
  health: {
1821
1829
  scriptPath: "./health.sh",
1822
1830
  required: true
@@ -2205,8 +2213,8 @@ async function runMigrate(cwd2, opts) {
2205
2213
 
2206
2214
  // src/commands/migrate-storage.ts
2207
2215
  import { copyFileSync, existsSync as existsSync12, mkdirSync as mkdirSync8, rmSync, writeFileSync as writeFileSync9 } from "fs";
2208
- import { homedir } from "os";
2209
- import { dirname as dirname7, join as join15, resolve as resolve8 } from "path";
2216
+ import { homedir as homedir3 } from "os";
2217
+ import { dirname as dirname7, join as join15, resolve as resolve7 } from "path";
2210
2218
  import pc9 from "picocolors";
2211
2219
  function log5(msg) {
2212
2220
  console.log(msg);
@@ -2214,11 +2222,17 @@ function log5(msg) {
2214
2222
  function fail(msg) {
2215
2223
  throw new Error(msg);
2216
2224
  }
2225
+ function defaultMarkdownPathForConfig(config) {
2226
+ return config.storage.scope === "local" ? config.storage.markdownFallback.path : DEFAULT_MARKDOWN_PATH;
2227
+ }
2217
2228
  function currentMdPathForScope(scope, config, cwd2, homeDir) {
2218
- return scope === "global" ? join15(resolveGlobalStorageDir(config, homeDir), "current.md") : resolve8(cwd2, config.storage.markdownFallback.path);
2229
+ return scope === "global" ? join15(resolveGlobalStorageDir(config, homeDir), "current.md") : resolve7(cwd2, defaultMarkdownPathForConfig(config));
2230
+ }
2231
+ function defaultSqlitePathForConfig(config) {
2232
+ return config.storage.scope === "local" && config.database.type === "sqlite" ? config.storage.sqlitePath ?? DEFAULT_SQLITE_PATH : DEFAULT_SQLITE_PATH;
2219
2233
  }
2220
2234
  async function backupDestination(cwd2, storageDir, data) {
2221
- const backupsDir = resolve8(cwd2, storageDir, "backups");
2235
+ const backupsDir = resolve7(cwd2, storageDir, "backups");
2222
2236
  const path = join15(backupsDir, `pre-migrate-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.json`);
2223
2237
  try {
2224
2238
  mkdirSync8(backupsDir, { recursive: true });
@@ -2242,14 +2256,14 @@ function copySqliteFile(srcPath, destPath) {
2242
2256
  throw new Error(`Copy verification failed: ${destPath} does not exist after copy.`);
2243
2257
  }
2244
2258
  }
2245
- async function runMigrateStorage(cwd2, opts, homeDir = homedir()) {
2259
+ async function runMigrateStorage(cwd2, opts, homeDir = homedir3()) {
2246
2260
  const config = await loadConfig(cwd2);
2247
2261
  const storageDir = config.storage.dir;
2248
2262
  const state = readStorageStateFile(cwd2, storageDir);
2249
2263
  let realScope;
2250
2264
  let realDbType;
2251
2265
  if (!state) {
2252
- const defaultSqlitePath = config.database.type === "sqlite" ? config.database.path : ".harness/harness.db";
2266
+ const defaultSqlitePath = defaultSqlitePathForConfig(config);
2253
2267
  const localPath = resolveSqlitePathForScope("local", defaultSqlitePath, cwd2, config, homeDir);
2254
2268
  const globalPath = resolveSqlitePathForScope("global", defaultSqlitePath, cwd2, config, homeDir);
2255
2269
  const localCount = await probeTaskCount(localPath);
@@ -2309,7 +2323,7 @@ async function probeTaskCount(dbPath) {
2309
2323
  }
2310
2324
  }
2311
2325
  async function migrateScopeOnly(cwd2, config, homeDir, fromScope, toScope, opts) {
2312
- const sqlitePath = config.database.type === "sqlite" ? config.database.path : ".harness/harness.db";
2326
+ const sqlitePath = defaultSqlitePathForConfig(config);
2313
2327
  const srcDb = resolveSqlitePathForScope(fromScope, sqlitePath, cwd2, config, homeDir);
2314
2328
  const destDb = resolveSqlitePathForScope(toScope, sqlitePath, cwd2, config, homeDir);
2315
2329
  const srcMd = currentMdPathForScope(fromScope, config, cwd2, homeDir);
@@ -2339,8 +2353,8 @@ async function migrateScopeOnly(cwd2, config, homeDir, fromScope, toScope, opts)
2339
2353
  let data;
2340
2354
  try {
2341
2355
  await backupDriver.ensureSchema();
2342
- const { HarnessDB } = await import("./db-QQ7BR5K7.js");
2343
- const tmpDb = new HarnessDB(backupDriver, { ...config, storage: { ...config.storage, scope: toScope } }, homeDir);
2356
+ const { HarnessDB } = await import("./db-3OXHRFAR.js");
2357
+ const tmpDb = new HarnessDB(backupDriver, config, homeDir);
2344
2358
  data = await tmpDb.exportJson();
2345
2359
  } finally {
2346
2360
  await backupDriver.close();
@@ -2373,7 +2387,7 @@ async function migrateScopeOnly(cwd2, config, homeDir, fromScope, toScope, opts)
2373
2387
  log5(pc9.green(`\u2713 Storage migrated: scope ${fromScope} \u2192 ${toScope}`));
2374
2388
  }
2375
2389
  async function migrateAcrossDbType(cwd2, config, homeDir, sourceScope, opts) {
2376
- const sqlitePath = config.database.type === "sqlite" ? config.database.path : ".harness/harness.db";
2390
+ const sqlitePath = defaultSqlitePathForConfig(config);
2377
2391
  const srcPath = resolveSqlitePathForScope(sourceScope, sqlitePath, cwd2, config, homeDir);
2378
2392
  if (!existsSync12(srcPath)) {
2379
2393
  fail(`Source sqlite database not found at ${srcPath} (expected ${sourceScope} scope) \u2014 nothing to migrate.`);
@@ -2385,8 +2399,8 @@ async function migrateAcrossDbType(cwd2, config, homeDir, sourceScope, opts) {
2385
2399
  try {
2386
2400
  await srcDriver.ensureSchema();
2387
2401
  sourceCounts = await getRowCounts(srcDriver);
2388
- const { HarnessDB } = await import("./db-QQ7BR5K7.js");
2389
- const srcDb = new HarnessDB(srcDriver, { ...config, storage: { ...config.storage, scope: sourceScope }, database: { type: "sqlite", path: sqlitePath } }, homeDir);
2402
+ const { HarnessDB } = await import("./db-3OXHRFAR.js");
2403
+ const srcDb = new HarnessDB(srcDriver, config, homeDir);
2390
2404
  sourceData = await srcDb.exportJson();
2391
2405
  } finally {
2392
2406
  await srcDriver.close();
@@ -2439,13 +2453,14 @@ async function migrateAcrossDbType(cwd2, config, homeDir, sourceScope, opts) {
2439
2453
 
2440
2454
  // src/commands/reset.ts
2441
2455
  import { existsSync as existsSync13, readdirSync, rmSync as rmSync2 } from "fs";
2442
- import { join as join16, resolve as resolve9 } from "path";
2456
+ import { homedir as homedir4 } from "os";
2457
+ import { join as join16, resolve as resolve8 } from "path";
2443
2458
  import * as p5 from "@clack/prompts";
2444
2459
  import pc10 from "picocolors";
2445
2460
  var AGENT_MD_FILES = ["lead", "explorer", "consultant", "builder", "reviewer"];
2446
2461
  async function resetAgentMds(cwd2, provider) {
2447
2462
  const agentDir = provider === "claude-code" ? ".claude/agents" : ".opencode/agents";
2448
- const agentDirPath = resolve9(cwd2, agentDir);
2463
+ const agentDirPath = resolve8(cwd2, agentDir);
2449
2464
  if (!existsSync13(agentDirPath)) {
2450
2465
  console.log(pc10.yellow(` Skipping agent files \u2014 directory not found: ${agentDirPath}`));
2451
2466
  return;
@@ -2497,8 +2512,8 @@ async function runReset(cwd2, opts) {
2497
2512
  process.exit(1);
2498
2513
  }
2499
2514
  const storageDir = config.storage.dir || ".harness";
2500
- const dbPath = config.database.type === "sqlite" ? resolve9(cwd2, config.database.path) : null;
2501
- const featureListPath = resolve9(cwd2, storageDir, "feature_list.json");
2515
+ const dbPath = config.database.type === "sqlite" ? resolveSqlitePath(config, cwd2, homedir4()) : null;
2516
+ const featureListPath = resolve8(cwd2, storageDir, "feature_list.json");
2502
2517
  let resetDb = false;
2503
2518
  let resetFeatureList = false;
2504
2519
  let resetAgentMdsFlag = false;
@@ -2511,7 +2526,7 @@ async function runReset(cwd2, opts) {
2511
2526
  resetDb = false;
2512
2527
  } else {
2513
2528
  const confirm3 = await p5.confirm({
2514
- message: `Delete database (${config.database.path})?`,
2529
+ message: `Delete database (${dbPath})?`,
2515
2530
  initialValue: true
2516
2531
  });
2517
2532
  if (p5.isCancel(confirm3)) {
@@ -2574,7 +2589,7 @@ async function runReset(cwd2, opts) {
2574
2589
 
2575
2590
  // src/core/mcp-server.ts
2576
2591
  import { existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync2, readFileSync as readFileSync10, statSync, writeFileSync as writeFileSync10 } from "fs";
2577
- import { join as join18, resolve as resolve10 } from "path";
2592
+ import { join as join18, resolve as resolve9 } from "path";
2578
2593
  import { Server } from "@modelcontextprotocol/sdk/server";
2579
2594
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2580
2595
  import {
@@ -2886,7 +2901,7 @@ var TOOLS = [
2886
2901
  ];
2887
2902
  async function startMcpServer(config, cwd2) {
2888
2903
  const db = await openDB(config, cwd2);
2889
- const docsPath = resolve10(cwd2, config.project.docsPath);
2904
+ const docsPath = resolve9(cwd2, config.project.docsPath);
2890
2905
  const server = new Server(
2891
2906
  { name: "agent-harness-kit", version: VERSION },
2892
2907
  { capabilities: { tools: {} } }
@@ -3286,12 +3301,12 @@ async function runStatus(cwd2, opts) {
3286
3301
 
3287
3302
  // src/commands/sync.ts
3288
3303
  import { existsSync as existsSync16, readFileSync as readFileSync11 } from "fs";
3289
- import { join as join19, resolve as resolve11 } from "path";
3304
+ import { join as join19, resolve as resolve10 } from "path";
3290
3305
  import pc12 from "picocolors";
3291
3306
  async function runSync(cwd2, opts) {
3292
3307
  const config = await loadConfig(cwd2);
3293
3308
  const direction = opts.direction ?? "both";
3294
- const featureListPath = resolve11(join19(cwd2, config.storage.dir, "feature_list.json"));
3309
+ const featureListPath = resolve10(join19(cwd2, config.storage.dir, "feature_list.json"));
3295
3310
  const db = await openDB(config, cwd2);
3296
3311
  try {
3297
3312
  if (direction === "in" || direction === "both") {
@@ -3397,12 +3412,12 @@ async function runTaskAdd(cwd2) {
3397
3412
  // src/commands/task/done.ts
3398
3413
  import { spawnSync as spawnSync2 } from "child_process";
3399
3414
  import { existsSync as existsSync17 } from "fs";
3400
- import { resolve as resolve12 } from "path";
3415
+ import { resolve as resolve11 } from "path";
3401
3416
  import pc14 from "picocolors";
3402
3417
  async function runTaskDone(cwd2, idOrSlug) {
3403
3418
  const config = await loadConfig(cwd2);
3404
3419
  if (config.health.required) {
3405
- const scriptPath = resolve12(cwd2, config.health.scriptPath);
3420
+ const scriptPath = resolve11(cwd2, config.health.scriptPath);
3406
3421
  if (existsSync17(scriptPath)) {
3407
3422
  const result = spawnSync2("bash", [scriptPath], { cwd: cwd2, stdio: "pipe", encoding: "utf8" });
3408
3423
  if (result.status !== 0) {
@@ -3616,15 +3631,15 @@ import pc18 from "picocolors";
3616
3631
  var REGISTRY_URL2 = `https://registry.npmjs.org/${pkg.name}/latest`;
3617
3632
  var TIMEOUT_MS2 = 2500;
3618
3633
  function checkForUpdate(currentVersion) {
3619
- return new Promise((resolve13) => {
3620
- const timer = setTimeout(() => resolve13(null), TIMEOUT_MS2);
3634
+ return new Promise((resolve12) => {
3635
+ const timer = setTimeout(() => resolve12(null), TIMEOUT_MS2);
3621
3636
  fetch(REGISTRY_URL2).then((res) => res.json()).then((data) => {
3622
3637
  clearTimeout(timer);
3623
3638
  const latest = data.version;
3624
- resolve13(isNewer2(latest, currentVersion) ? { current: currentVersion, latest } : null);
3639
+ resolve12(isNewer2(latest, currentVersion) ? { current: currentVersion, latest } : null);
3625
3640
  }).catch(() => {
3626
3641
  clearTimeout(timer);
3627
- resolve13(null);
3642
+ resolve12(null);
3628
3643
  });
3629
3644
  });
3630
3645
  }