@cardor/agent-harness-kit 1.6.8 → 1.7.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/README.md CHANGED
@@ -161,7 +161,9 @@ ahk init --name "my-app" --provider claude-code --docs ./docs --tasks local
161
161
  ahk init --name "my-app" --provider codex-cli --docs ./docs --tasks local
162
162
  ```
163
163
 
164
- Run this once per project. Safe to re-run it will not overwrite files you've customized.
164
+ Run this once per project. If the project is already initialized, the command prints an 'already initialized' message with suggested next-step commands (`ahk build`, `ahk build --sync`, `ahk reset`, `ahk serve`) and exits without overwriting anything.
165
+
166
+ The config file extension is chosen automatically: `.ts` if a `tsconfig.json` is present, `.mjs` for ESM-only projects (`"type": "module"` in `package.json`), or `.cjs` otherwise.
165
167
 
166
168
  ---
167
169
 
@@ -339,7 +341,7 @@ ahk export --sql --output dump.sql # SQL dump to file
339
341
 
340
342
  ```
341
343
  your-project/
342
- ├── agent-harness-kit.config.ts
344
+ ├── agent-harness-kit.config.{ts|mjs|cjs}
343
345
  ├── AGENTS.md
344
346
  ├── CLAUDE.md
345
347
  ├── health.sh
@@ -361,7 +363,7 @@ your-project/
361
363
 
362
364
  ```
363
365
  your-project/
364
- ├── agent-harness-kit.config.ts
366
+ ├── agent-harness-kit.config.{ts|mjs|cjs}
365
367
  ├── AGENTS.md
366
368
  ├── health.sh
367
369
  ├── opencode.json ← MCP server + default_agent + compaction config
@@ -378,7 +380,7 @@ your-project/
378
380
 
379
381
  ```
380
382
  your-project/
381
- ├── agent-harness-kit.config.ts
383
+ ├── agent-harness-kit.config.{ts|mjs|cjs}
382
384
  ├── AGENTS.md
383
385
  ├── health.sh
384
386
  ├── .harness/
@@ -5,7 +5,8 @@ import { createJiti } from "jiti";
5
5
  var CONFIG_NAMES = [
6
6
  "agent-harness-kit.config.ts",
7
7
  "agent-harness-kit.config",
8
- "agent-harness-kit.config.mjs"
8
+ "agent-harness-kit.config.mjs",
9
+ "agent-harness-kit.config.cjs"
9
10
  ];
10
11
  function findConfigFile(cwd) {
11
12
  for (const name of CONFIG_NAMES) {
@@ -76,7 +77,8 @@ function applyDefaults(config) {
76
77
  }
77
78
 
78
79
  export {
80
+ findConfigFile,
79
81
  loadConfig,
80
82
  defineHarness
81
83
  };
82
- //# sourceMappingURL=chunk-X7FOJOZB.js.map
84
+ //# sourceMappingURL=chunk-OEPZRC7J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/config.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createJiti } from 'jiti'\n\nimport type { HarnessConfig } from '@/types'\n\nconst CONFIG_NAMES = [\n 'agent-harness-kit.config.ts',\n 'agent-harness-kit.config',\n 'agent-harness-kit.config.mjs',\n 'agent-harness-kit.config.cjs',\n]\n\nexport function findConfigFile(cwd: string): string | null {\n for (const name of CONFIG_NAMES) {\n const candidate = join(cwd, name)\n if (existsSync(candidate)) return candidate\n }\n return null\n}\n\nexport async function loadConfig(cwd: string): Promise<HarnessConfig> {\n const configPath = findConfigFile(cwd)\n if (!configPath) {\n throw new Error('No agent-harness-kit.config found. Run: ahk init')\n }\n\n const jiti = createJiti(import.meta.url)\n const mod = await jiti.import(configPath) as { default?: HarnessConfig } | HarnessConfig\n const config = (mod as { default?: HarnessConfig }).default ?? (mod as HarnessConfig)\n\n if (!config || typeof config !== 'object') {\n throw new Error(`agent-harness-kit.config must export a default HarnessConfig object.`)\n }\n\n return applyDefaults(config as HarnessConfig)\n}\n\nexport function defineHarness(config: HarnessConfig): HarnessConfig {\n return config\n}\n\nfunction applyDefaults(config: HarnessConfig): HarnessConfig {\n const c = config as Partial<HarnessConfig>\n return {\n ...config,\n provider: c.provider ?? 'claude-code',\n project: {\n docsPath: './docs',\n agentsMd: './AGENTS.md',\n ...c.project,\n } as HarnessConfig['project'],\n agents: {\n lead: { instructionsPath: null },\n explorer: { instructionsPath: null },\n builder: { instructionsPath: null },\n reviewer: { instructionsPath: null },\n custom: [],\n ...c.agents,\n } as HarnessConfig['agents'],\n database: c.database ?? { type: 'sqlite' as const, path: '.harness/harness.db' },\n storage: {\n dir: '.harness',\n tasks: { adapter: 'local' as const },\n sections: {\n toolsUsed: true,\n filesModified: true,\n result: true,\n blockers: true,\n nextSteps: false,\n },\n markdownFallback: { enabled: true, path: '.harness/current.md' },\n ...c.storage,\n } as HarnessConfig['storage'],\n health: {\n scriptPath: './health.sh',\n required: true,\n ...c.health,\n },\n tools: {\n mcp: { enabled: true, port: 3742 },\n scripts: { enabled: true, outputDir: './.harness/scripts' },\n ...c.tools,\n } as HarnessConfig['tools'],\n }\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAI3B,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,eAAe,KAA4B;AACzD,aAAW,QAAQ,cAAc;AAC/B,UAAM,YAAY,KAAK,KAAK,IAAI;AAChC,QAAI,WAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,eAAsB,WAAW,KAAqC;AACpE,QAAM,aAAa,eAAe,GAAG;AACrC,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,QAAM,OAAO,WAAW,YAAY,GAAG;AACvC,QAAM,MAAM,MAAM,KAAK,OAAO,UAAU;AACxC,QAAM,SAAU,IAAoC,WAAY;AAEhE,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AAEA,SAAO,cAAc,MAAuB;AAC9C;AAEO,SAAS,cAAc,QAAsC;AAClE,SAAO;AACT;AAEA,SAAS,cAAc,QAAsC;AAC3D,QAAM,IAAI;AACV,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,EAAE,YAAY;AAAA,IACxB,SAAS;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,MACV,GAAG,EAAE;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,MAAM,EAAE,kBAAkB,KAAK;AAAA,MAC/B,UAAU,EAAE,kBAAkB,KAAK;AAAA,MACnC,SAAS,EAAE,kBAAkB,KAAK;AAAA,MAClC,UAAU,EAAE,kBAAkB,KAAK;AAAA,MACnC,QAAQ,CAAC;AAAA,MACT,GAAG,EAAE;AAAA,IACP;AAAA,IACA,UAAU,EAAE,YAAY,EAAE,MAAM,UAAmB,MAAM,sBAAsB;AAAA,IAC/E,SAAS;AAAA,MACP,KAAK;AAAA,MACL,OAAO,EAAE,SAAS,QAAiB;AAAA,MACnC,UAAU;AAAA,QACR,WAAW;AAAA,QACX,eAAe;AAAA,QACf,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,MACA,kBAAkB,EAAE,SAAS,MAAM,MAAM,sBAAsB;AAAA,MAC/D,GAAG,EAAE;AAAA,IACP;AAAA,IACA,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,GAAG,EAAE;AAAA,IACP;AAAA,IACA,OAAO;AAAA,MACL,KAAK,EAAE,SAAS,MAAM,MAAM,KAAK;AAAA,MACjC,SAAS,EAAE,SAAS,MAAM,WAAW,qBAAqB;AAAA,MAC1D,GAAG,EAAE;AAAA,IACP;AAAA,EACF;AACF;","names":[]}
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
+ findConfigFile,
2
3
  loadConfig
3
- } from "./chunk-X7FOJOZB.js";
4
+ } from "./chunk-OEPZRC7J.js";
4
5
 
5
6
  // src/cli.ts
6
7
  import { Command } from "commander";
@@ -499,6 +500,57 @@ export default defineHarness({
499
500
  })
500
501
  `;
501
502
  }
503
+ var configMjs = configTs;
504
+ function configCjs(params) {
505
+ return `const { defineHarness } = require('@cardor/agent-harness-kit')
506
+
507
+ module.exports = defineHarness({
508
+ project: {
509
+ name: '${params.name}',
510
+ description: '${params.description}',
511
+ docsPath: '${params.docsPath}',
512
+ },
513
+
514
+ provider: '${params.provider}',
515
+
516
+ agents: {
517
+ lead: { instructionsPath: null },
518
+ explorer: { instructionsPath: null, allowedPaths: ['${params.docsPath}', './src'] },
519
+ builder: { instructionsPath: null, writablePaths: ['./src', './tests'] },
520
+ reviewer: { instructionsPath: null },
521
+ custom: [],
522
+ },
523
+
524
+ // SQLite (default). Switch to postgres/mysql by changing database.type.
525
+ // database: { type: 'postgres', connectionString: process.env.DATABASE_URL },
526
+ // database: { type: 'mysql', connectionString: process.env.DATABASE_URL },
527
+ database: { type: 'sqlite', path: '.harness/harness.db' },
528
+
529
+ storage: {
530
+ dir: '.harness',
531
+ tasks: { adapter: '${params.tasksAdapter}' },
532
+ sections: {
533
+ toolsUsed: true,
534
+ filesModified: true,
535
+ result: true,
536
+ blockers: true,
537
+ nextSteps: false,
538
+ },
539
+ markdownFallback: { enabled: true, path: '.harness/current.md' },
540
+ },
541
+
542
+ health: {
543
+ scriptPath: './health.sh',
544
+ required: true,
545
+ },
546
+
547
+ tools: {
548
+ mcp: { enabled: true, port: ${params.port} },
549
+ scripts: { enabled: true, outputDir: './.harness/scripts' },
550
+ },
551
+ })
552
+ `;
553
+ }
502
554
  function agentLead(vars) {
503
555
  return loadAgentTemplate("lead", vars);
504
556
  }
@@ -1942,6 +1994,17 @@ function readProjectNameFromPackageJson(cwd2) {
1942
1994
  return null;
1943
1995
  }
1944
1996
  }
1997
+ function detectConfigExtension(cwd2) {
1998
+ try {
1999
+ if (existsSync8(join11(cwd2, "tsconfig.json"))) return "ts";
2000
+ const pkgPath2 = join11(cwd2, "package.json");
2001
+ if (!existsSync8(pkgPath2)) return "cjs";
2002
+ const pkg2 = JSON.parse(readFileSync5(pkgPath2, "utf8"));
2003
+ if (pkg2?.type === "module") return "mjs";
2004
+ } catch {
2005
+ }
2006
+ return "cjs";
2007
+ }
1945
2008
  function applyConfigDefaults(params) {
1946
2009
  return {
1947
2010
  provider: params.provider,
@@ -2016,6 +2079,23 @@ function printWelcomeMessage(projectName) {
2016
2079
 
2017
2080
  // src/commands/init.ts
2018
2081
  async function runInit(cwd2, flags) {
2082
+ const existingConfig = findConfigFile(cwd2);
2083
+ if (existingConfig) {
2084
+ console.log(
2085
+ pc6.yellow("\u26A0") + " " + pc6.bold("Project already initialized.") + pc6.dim(` (${existingConfig})`)
2086
+ );
2087
+ console.log();
2088
+ console.log(pc6.dim("Suggested next steps:"));
2089
+ console.log(
2090
+ " " + pc6.cyan("ahk build") + pc6.dim(" \u2014 re-sync agent files after updating the library")
2091
+ );
2092
+ console.log(" " + pc6.cyan("ahk build --sync") + pc6.dim(" \u2014 also sync agent permissions"));
2093
+ console.log(
2094
+ " " + pc6.cyan("ahk reset") + pc6.dim(" \u2014 wipe and re-initialize from scratch")
2095
+ );
2096
+ console.log(" " + pc6.cyan("ahk dashboard") + pc6.dim(" \u2014 open the harness dashboard"));
2097
+ process.exit(0);
2098
+ }
2019
2099
  const detectedName = flags.name ?? readProjectNameFromPackageJson(cwd2);
2020
2100
  const projectName = detectedName || "my-project";
2021
2101
  printWelcomeMessage(projectName);
@@ -2134,13 +2214,17 @@ async function runInit(cwd2, flags) {
2134
2214
  }
2135
2215
  firstTask = { title: taskTitle, description: taskDesc, acceptance };
2136
2216
  }
2217
+ let configExt = "ts";
2137
2218
  const spinner6 = p3.spinner();
2138
2219
  spinner6.start("Scaffolding...");
2139
2220
  try {
2140
2221
  const config = applyConfigDefaults({ name, description, provider, docsPath, tasksAdapter });
2141
2222
  const materializer = getMaterializer(provider);
2142
2223
  const installDir = cwd2;
2143
- const configContent = configTs({
2224
+ configExt = detectConfigExtension(cwd2);
2225
+ const configFileName = `agent-harness-kit.config.${configExt}`;
2226
+ const templateFn = configExt === "ts" ? configTs : configExt === "mjs" ? configMjs : configCjs;
2227
+ const configContent = templateFn({
2144
2228
  name,
2145
2229
  description,
2146
2230
  provider,
@@ -2148,7 +2232,7 @@ async function runInit(cwd2, flags) {
2148
2232
  tasksAdapter,
2149
2233
  port: config.tools.mcp.port
2150
2234
  });
2151
- writeFileSync9(join12(installDir, "agent-harness-kit.config.ts"), configContent, "utf8");
2235
+ writeFileSync9(join12(installDir, configFileName), configContent, "utf8");
2152
2236
  mkdirSync8(join12(installDir, config.storage.dir), { recursive: true });
2153
2237
  const db = await openDB(config, installDir);
2154
2238
  await materializer.scaffold(config, { cwd: installDir, firstTask });
@@ -2172,7 +2256,7 @@ async function runInit(cwd2, flags) {
2172
2256
  const agentsDir = provider === "claude-code" ? ".claude/agents/" : ".opencode/agents/";
2173
2257
  const mcpFile = provider === "claude-code" ? ".claude/mcp.json" : "./opencode.json";
2174
2258
  console.log("");
2175
- console.log(pc6.green("\u2713 agent-harness-kit.config.ts"));
2259
+ console.log(pc6.green(`\u2713 agent-harness-kit.config.${configExt}`));
2176
2260
  console.log(pc6.green("\u2713 AGENTS.md"));
2177
2261
  console.log(pc6.green("\u2713 health.sh"));
2178
2262
  console.log(pc6.green("\u2713 .harness/harness.db"));