@draht/coding-agent 2026.3.5 → 2026.3.6

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 (63) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/agents/architect.md +1 -0
  3. package/agents/debugger.md +1 -0
  4. package/agents/git-committer.md +1 -0
  5. package/agents/implementer.md +1 -0
  6. package/agents/reviewer.md +1 -0
  7. package/agents/security-auditor.md +1 -0
  8. package/agents/verifier.md +1 -0
  9. package/dist/agents/architect.md +1 -0
  10. package/dist/agents/debugger.md +1 -0
  11. package/dist/agents/git-committer.md +1 -0
  12. package/dist/agents/implementer.md +1 -0
  13. package/dist/agents/reviewer.md +1 -0
  14. package/dist/agents/security-auditor.md +1 -0
  15. package/dist/agents/verifier.md +1 -0
  16. package/dist/config.d.ts +7 -0
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +15 -0
  19. package/dist/config.js.map +1 -1
  20. package/dist/core/package-manager.d.ts.map +1 -1
  21. package/dist/core/package-manager.js +7 -7
  22. package/dist/core/package-manager.js.map +1 -1
  23. package/dist/core/prompt-templates.d.ts.map +1 -1
  24. package/dist/core/prompt-templates.js +4 -4
  25. package/dist/core/prompt-templates.js.map +1 -1
  26. package/dist/core/resource-loader.d.ts.map +1 -1
  27. package/dist/core/resource-loader.js +9 -8
  28. package/dist/core/resource-loader.js.map +1 -1
  29. package/dist/core/settings-manager.d.ts.map +1 -1
  30. package/dist/core/settings-manager.js +2 -2
  31. package/dist/core/settings-manager.js.map +1 -1
  32. package/dist/core/skills.d.ts.map +1 -1
  33. package/dist/core/skills.js +3 -3
  34. package/dist/core/skills.js.map +1 -1
  35. package/dist/migrations.d.ts.map +1 -1
  36. package/dist/migrations.js +2 -2
  37. package/dist/migrations.js.map +1 -1
  38. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  39. package/dist/modes/interactive/components/config-selector.js +3 -3
  40. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  41. package/dist/prompts/commands/discuss-phase.md +10 -0
  42. package/dist/prompts/commands/execute-phase.md +51 -34
  43. package/dist/prompts/commands/fix.md +8 -6
  44. package/dist/prompts/commands/init-project.md +12 -0
  45. package/dist/prompts/commands/map-codebase.md +17 -18
  46. package/dist/prompts/commands/new-project.md +12 -0
  47. package/dist/prompts/commands/next-milestone.md +5 -3
  48. package/dist/prompts/commands/plan-phase.md +27 -5
  49. package/dist/prompts/commands/quick.md +12 -5
  50. package/dist/prompts/commands/review.md +10 -10
  51. package/dist/prompts/commands/verify-work.md +31 -17
  52. package/package.json +4 -4
  53. package/prompts/commands/discuss-phase.md +10 -0
  54. package/prompts/commands/execute-phase.md +51 -34
  55. package/prompts/commands/fix.md +8 -6
  56. package/prompts/commands/init-project.md +12 -0
  57. package/prompts/commands/map-codebase.md +17 -18
  58. package/prompts/commands/new-project.md +12 -0
  59. package/prompts/commands/next-milestone.md +5 -3
  60. package/prompts/commands/plan-phase.md +27 -5
  61. package/prompts/commands/quick.md +12 -5
  62. package/prompts/commands/review.md +10 -10
  63. package/prompts/commands/verify-work.md +31 -17
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [2026.3.6] - 2026-03-06
4
+
5
+ ### Added
6
+
7
+ - add legacy .pi config directory fallback
8
+
9
+ ### Fixed
10
+
11
+ - clarify workflow between phases, restrict /next-milestone to milestone transitions
12
+ - prevent subagents from running draht/pi commands
13
+ - use subagents for parallel execution in builtin commands
14
+
3
15
  ## [2026.3.5] - 2026-03-05
4
16
 
5
17
  ### Added
@@ -43,3 +43,4 @@ Numbered list of concrete tasks. For each task:
43
43
  - DO NOT produce code — only plans
44
44
  - DO NOT make assumptions about APIs without reading the source
45
45
  - DO NOT suggest removing existing functionality unless explicitly asked
46
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -55,3 +55,4 @@ Show that the fix works (test output, command output).
55
55
  - Keep fixes minimal — do not refactor unrelated code
56
56
  - If the fix is non-obvious, add a comment explaining why
57
57
  - Run verification after fixing to confirm the issue is resolved
58
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -39,6 +39,7 @@ Use the package directory name (e.g., `ai`, `tui`, `agent`, `coding-agent`).
39
39
  - NEVER use `git add -A` or `git add .` — always stage specific files
40
40
  - NEVER use `git commit --no-verify`
41
41
  - NEVER force push
42
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
42
43
  - Review the diff before committing to ensure nothing unexpected is included
43
44
  - One commit per logical change — split unrelated changes into separate commits
44
45
  - Keep the first line under 72 characters
@@ -20,6 +20,7 @@ You are the Implementer agent. Your job is to write code that fulfills the given
20
20
  - NEVER use `any` types unless absolutely necessary
21
21
  - NEVER use inline imports — always use standard top-level imports
22
22
  - NEVER remove existing functionality unless the task explicitly requires it
23
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
23
24
  - Keep changes minimal — do only what the task asks for
24
25
  - If a task is ambiguous, implement the most conservative interpretation
25
26
  - Run `npm run check` or equivalent after changes if the project has one
@@ -50,3 +50,4 @@ If no issues found, state that explicitly.
50
50
  - Be actionable — say what to change, not just what is wrong
51
51
  - Do not nitpick formatting if the project has a formatter
52
52
  - Focus on substance over style
53
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -59,3 +59,4 @@ For each vulnerability:
59
59
  - Be specific about the attack vector
60
60
  - Prioritize by exploitability and impact
61
61
  - If no security issues found, state that explicitly
62
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -42,3 +42,4 @@ State whether the code is ready for production or what must be fixed first.
42
42
  - Do not attempt to fix issues — only report them
43
43
  - If a check command is not found, note it and move on
44
44
  - Include the full error output for failures (truncated if very long)
45
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -43,3 +43,4 @@ Numbered list of concrete tasks. For each task:
43
43
  - DO NOT produce code — only plans
44
44
  - DO NOT make assumptions about APIs without reading the source
45
45
  - DO NOT suggest removing existing functionality unless explicitly asked
46
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -55,3 +55,4 @@ Show that the fix works (test output, command output).
55
55
  - Keep fixes minimal — do not refactor unrelated code
56
56
  - If the fix is non-obvious, add a comment explaining why
57
57
  - Run verification after fixing to confirm the issue is resolved
58
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -39,6 +39,7 @@ Use the package directory name (e.g., `ai`, `tui`, `agent`, `coding-agent`).
39
39
  - NEVER use `git add -A` or `git add .` — always stage specific files
40
40
  - NEVER use `git commit --no-verify`
41
41
  - NEVER force push
42
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
42
43
  - Review the diff before committing to ensure nothing unexpected is included
43
44
  - One commit per logical change — split unrelated changes into separate commits
44
45
  - Keep the first line under 72 characters
@@ -20,6 +20,7 @@ You are the Implementer agent. Your job is to write code that fulfills the given
20
20
  - NEVER use `any` types unless absolutely necessary
21
21
  - NEVER use inline imports — always use standard top-level imports
22
22
  - NEVER remove existing functionality unless the task explicitly requires it
23
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
23
24
  - Keep changes minimal — do only what the task asks for
24
25
  - If a task is ambiguous, implement the most conservative interpretation
25
26
  - Run `npm run check` or equivalent after changes if the project has one
@@ -50,3 +50,4 @@ If no issues found, state that explicitly.
50
50
  - Be actionable — say what to change, not just what is wrong
51
51
  - Do not nitpick formatting if the project has a formatter
52
52
  - Focus on substance over style
53
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -59,3 +59,4 @@ For each vulnerability:
59
59
  - Be specific about the attack vector
60
60
  - Prioritize by exploitability and impact
61
61
  - If no security issues found, state that explicitly
62
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
@@ -42,3 +42,4 @@ State whether the code is ready for production or what must be fixed first.
42
42
  - Do not attempt to fix issues — only report them
43
43
  - If a check command is not found, note it and move on
44
44
  - Include the full error output for failures (truncated if very long)
45
+ - NEVER run `draht`, `draht-tools`, `draht help`, or `pi` commands — these are orchestrator commands that launch interactive sessions and will block your process
package/dist/config.d.ts CHANGED
@@ -41,7 +41,14 @@ export declare function getExamplesPath(): string;
41
41
  export declare function getChangelogPath(): string;
42
42
  export declare const APP_NAME: string;
43
43
  export declare const CONFIG_DIR_NAME: string;
44
+ export declare const LEGACY_CONFIG_DIR_NAME = ".pi";
44
45
  export declare const VERSION: string;
46
+ /**
47
+ * Resolve the project config directory. Prefers `CONFIG_DIR_NAME` (`.draht`),
48
+ * falls back to `LEGACY_CONFIG_DIR_NAME` (`.pi`) if the primary doesn't exist
49
+ * but the legacy one does.
50
+ */
51
+ export declare function getProjectConfigDir(cwd: string): string;
45
52
  export declare const ENV_AGENT_DIR: string;
46
53
  /** Get the share viewer URL for a gist ID */
47
54
  export declare function getShareViewerUrl(gistId: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,eAAO,MAAM,WAAW,SACqF,CAAC;AAE9G,gEAAgE;AAChE,eAAO,MAAM,YAAY,SAAyB,CAAC;AAMnD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEvF,wBAAgB,mBAAmB,IAAI,aAAa,CAqBnD;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAgBhE;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAuBtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C;AAED,+BAA+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAQD,eAAO,MAAM,QAAQ,EAAE,MAAyC,CAAC;AACjE,eAAO,MAAM,eAAe,EAAE,MAA+C,CAAC;AAC9E,eAAO,MAAM,OAAO,EAAE,MAAwE,CAAC;AAG/F,eAAO,MAAM,aAAa,QAA+C,CAAC;AAI1E,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAMD,6DAA6D;AAC7D,wBAAgB,WAAW,IAAI,MAAM,CASpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC","sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase();\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\") || resolvedPath.includes(\"\\\\pnpm\\\\\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\") || resolvedPath.includes(\"\\\\yarn\\\\\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\") || resolvedPath.includes(\"\\\\npm\\\\\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn `Download from: https://github.com/draht-dev/draht/releases/latest`;\n\t\tcase \"pnpm\":\n\t\t\treturn `Run: pnpm install -g ${packageName}`;\n\t\tcase \"yarn\":\n\t\t\treturn `Run: yarn global add ${packageName}`;\n\t\tcase \"bun\":\n\t\t\treturn `Run: bun install -g ${packageName}`;\n\t\tcase \"npm\":\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t\tdefault:\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t}\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.DRAHT_PACKAGE_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n// =============================================================================\n// App Config (from package.json drahtConfig)\n// =============================================================================\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\"));\n\nexport const APP_NAME: string = pkg.drahtConfig?.name || \"draht\";\nexport const CONFIG_DIR_NAME: string = pkg.drahtConfig?.configDir || \".draht\";\nexport const VERSION: string = existsSync(join(getPackageDir(), \".dev\")) ? \"dev\" : pkg.version;\n\n// e.g., DRAHT_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://draht.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.DRAHT_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.draht/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.draht/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\t// Expand tilde to home directory\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped prompt templates (bundled with the package).\n * - For Bun binary: prompts/ next to executable\n * - For Node.js: prompts/ at package root\n */\nexport function getShippedPromptsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"prompts\");\n\t}\n\treturn join(getPackageDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped hooks (bundled with the package).\n */\nexport function getShippedHooksDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"hooks\");\n\t}\n\treturn join(getPackageDir(), \"hooks\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,eAAO,MAAM,WAAW,SACqF,CAAC;AAE9G,gEAAgE;AAChE,eAAO,MAAM,YAAY,SAAyB,CAAC;AAMnD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEvF,wBAAgB,mBAAmB,IAAI,aAAa,CAqBnD;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAgBhE;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAuBtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C;AAED,+BAA+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAQD,eAAO,MAAM,QAAQ,EAAE,MAAyC,CAAC;AACjE,eAAO,MAAM,eAAe,EAAE,MAA+C,CAAC;AAC9E,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,OAAO,EAAE,MAAwE,CAAC;AAE/F;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMvD;AAGD,eAAO,MAAM,aAAa,QAA+C,CAAC;AAI1E,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAMD,6DAA6D;AAC7D,wBAAgB,WAAW,IAAI,MAAM,CASpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC","sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase();\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\") || resolvedPath.includes(\"\\\\pnpm\\\\\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\") || resolvedPath.includes(\"\\\\yarn\\\\\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\") || resolvedPath.includes(\"\\\\npm\\\\\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn `Download from: https://github.com/draht-dev/draht/releases/latest`;\n\t\tcase \"pnpm\":\n\t\t\treturn `Run: pnpm install -g ${packageName}`;\n\t\tcase \"yarn\":\n\t\t\treturn `Run: yarn global add ${packageName}`;\n\t\tcase \"bun\":\n\t\t\treturn `Run: bun install -g ${packageName}`;\n\t\tcase \"npm\":\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t\tdefault:\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t}\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.DRAHT_PACKAGE_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n// =============================================================================\n// App Config (from package.json drahtConfig)\n// =============================================================================\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\"));\n\nexport const APP_NAME: string = pkg.drahtConfig?.name || \"draht\";\nexport const CONFIG_DIR_NAME: string = pkg.drahtConfig?.configDir || \".draht\";\nexport const LEGACY_CONFIG_DIR_NAME = \".pi\";\nexport const VERSION: string = existsSync(join(getPackageDir(), \".dev\")) ? \"dev\" : pkg.version;\n\n/**\n * Resolve the project config directory. Prefers `CONFIG_DIR_NAME` (`.draht`),\n * falls back to `LEGACY_CONFIG_DIR_NAME` (`.pi`) if the primary doesn't exist\n * but the legacy one does.\n */\nexport function getProjectConfigDir(cwd: string): string {\n\tconst primary = join(cwd, CONFIG_DIR_NAME);\n\tif (existsSync(primary)) return primary;\n\tconst legacy = join(cwd, LEGACY_CONFIG_DIR_NAME);\n\tif (existsSync(legacy)) return legacy;\n\treturn primary; // default to primary even if it doesn't exist yet\n}\n\n// e.g., DRAHT_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://draht.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.DRAHT_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.draht/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.draht/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\t// Expand tilde to home directory\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped prompt templates (bundled with the package).\n * - For Bun binary: prompts/ next to executable\n * - For Node.js: prompts/ at package root\n */\nexport function getShippedPromptsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"prompts\");\n\t}\n\treturn join(getPackageDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped hooks (bundled with the package).\n */\nexport function getShippedHooksDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"hooks\");\n\t}\n\treturn join(getPackageDir(), \"hooks\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
package/dist/config.js CHANGED
@@ -139,7 +139,22 @@ export function getChangelogPath() {
139
139
  const pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
140
140
  export const APP_NAME = pkg.drahtConfig?.name || "draht";
141
141
  export const CONFIG_DIR_NAME = pkg.drahtConfig?.configDir || ".draht";
142
+ export const LEGACY_CONFIG_DIR_NAME = ".pi";
142
143
  export const VERSION = existsSync(join(getPackageDir(), ".dev")) ? "dev" : pkg.version;
144
+ /**
145
+ * Resolve the project config directory. Prefers `CONFIG_DIR_NAME` (`.draht`),
146
+ * falls back to `LEGACY_CONFIG_DIR_NAME` (`.pi`) if the primary doesn't exist
147
+ * but the legacy one does.
148
+ */
149
+ export function getProjectConfigDir(cwd) {
150
+ const primary = join(cwd, CONFIG_DIR_NAME);
151
+ if (existsSync(primary))
152
+ return primary;
153
+ const legacy = join(cwd, LEGACY_CONFIG_DIR_NAME);
154
+ if (existsSync(legacy))
155
+ return legacy;
156
+ return primary; // default to primary even if it doesn't exist yet
157
+ }
143
158
  // e.g., DRAHT_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR
144
159
  export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
145
160
  const DEFAULT_SHARE_VIEWER_URL = "https://draht.dev/session/";
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase();\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\") || resolvedPath.includes(\"\\\\pnpm\\\\\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\") || resolvedPath.includes(\"\\\\yarn\\\\\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\") || resolvedPath.includes(\"\\\\npm\\\\\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn `Download from: https://github.com/draht-dev/draht/releases/latest`;\n\t\tcase \"pnpm\":\n\t\t\treturn `Run: pnpm install -g ${packageName}`;\n\t\tcase \"yarn\":\n\t\t\treturn `Run: yarn global add ${packageName}`;\n\t\tcase \"bun\":\n\t\t\treturn `Run: bun install -g ${packageName}`;\n\t\tcase \"npm\":\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t\tdefault:\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t}\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.DRAHT_PACKAGE_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n// =============================================================================\n// App Config (from package.json drahtConfig)\n// =============================================================================\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\"));\n\nexport const APP_NAME: string = pkg.drahtConfig?.name || \"draht\";\nexport const CONFIG_DIR_NAME: string = pkg.drahtConfig?.configDir || \".draht\";\nexport const VERSION: string = existsSync(join(getPackageDir(), \".dev\")) ? \"dev\" : pkg.version;\n\n// e.g., DRAHT_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://draht.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.DRAHT_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.draht/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.draht/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\t// Expand tilde to home directory\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped prompt templates (bundled with the package).\n * - For Bun binary: prompts/ next to executable\n * - For Node.js: prompts/ at package root\n */\nexport function getShippedPromptsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"prompts\");\n\t}\n\treturn join(getPackageDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped hooks (bundled with the package).\n */\nexport function getShippedHooksDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"hooks\");\n\t}\n\treturn join(getPackageDir(), \"hooks\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase();\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\") || resolvedPath.includes(\"\\\\pnpm\\\\\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\") || resolvedPath.includes(\"\\\\yarn\\\\\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\") || resolvedPath.includes(\"\\\\npm\\\\\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn `Download from: https://github.com/draht-dev/draht/releases/latest`;\n\t\tcase \"pnpm\":\n\t\t\treturn `Run: pnpm install -g ${packageName}`;\n\t\tcase \"yarn\":\n\t\t\treturn `Run: yarn global add ${packageName}`;\n\t\tcase \"bun\":\n\t\t\treturn `Run: bun install -g ${packageName}`;\n\t\tcase \"npm\":\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t\tdefault:\n\t\t\treturn `Run: npm install -g ${packageName}`;\n\t}\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.DRAHT_PACKAGE_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n// =============================================================================\n// App Config (from package.json drahtConfig)\n// =============================================================================\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\"));\n\nexport const APP_NAME: string = pkg.drahtConfig?.name || \"draht\";\nexport const CONFIG_DIR_NAME: string = pkg.drahtConfig?.configDir || \".draht\";\nexport const LEGACY_CONFIG_DIR_NAME = \".pi\";\nexport const VERSION: string = existsSync(join(getPackageDir(), \".dev\")) ? \"dev\" : pkg.version;\n\n/**\n * Resolve the project config directory. Prefers `CONFIG_DIR_NAME` (`.draht`),\n * falls back to `LEGACY_CONFIG_DIR_NAME` (`.pi`) if the primary doesn't exist\n * but the legacy one does.\n */\nexport function getProjectConfigDir(cwd: string): string {\n\tconst primary = join(cwd, CONFIG_DIR_NAME);\n\tif (existsSync(primary)) return primary;\n\tconst legacy = join(cwd, LEGACY_CONFIG_DIR_NAME);\n\tif (existsSync(legacy)) return legacy;\n\treturn primary; // default to primary even if it doesn't exist yet\n}\n\n// e.g., DRAHT_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://draht.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.DRAHT_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.draht/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.draht/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\t// Expand tilde to home directory\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped prompt templates (bundled with the package).\n * - For Bun binary: prompts/ next to executable\n * - For Node.js: prompts/ at package root\n */\nexport function getShippedPromptsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"prompts\");\n\t}\n\treturn join(getPackageDir(), \"prompts\");\n}\n\n/**\n * Get path to shipped hooks (bundled with the package).\n */\nexport function getShippedHooksDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(dirname(process.execPath), \"hooks\");\n\t}\n\treturn join(getPackageDir(), \"hooks\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}