@kolisachint/hoocode-agent 0.2.2 → 0.2.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.3] - 2026-05-15
4
+
5
+ ### Fixed
6
+
7
+ - Fixed `ERR_UNSUPPORTED_ESM_URL_SCHEME` when running `hoocode` / `hoo` on Windows after `bun add -g`. The bin shim passed raw `path.join(...)` results to dynamic `import()`; Node's ESM loader requires a `file://` URL specifier on Windows. Each `import()` argument is now wrapped with `pathToFileURL().href`.
8
+ - Fixed Windows binary missing default `modes/` and `profiles/` after extracting the release zip. Two causes: `init.ts` resolved templates from `__dirname`, which doesn't map to a real disk path inside Bun-compiled binaries; and `scripts/build-binaries.sh` never copied `templates/` next to the executable. Added `getTemplatesDir()` (mirrors `getThemesDir()` etc.), routed `init.ts` through it, replaced silent `try/catch` with a visible warning, and updated the build script to ship `templates/` in every platform archive.
9
+
3
10
  ## [0.2.2] - 2026-05-13
4
11
 
5
12
  ### Added
package/bin/hoocode.js CHANGED
@@ -1,15 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { fileURLToPath } from "url";
2
+ import { fileURLToPath, pathToFileURL } from "url";
3
3
  import { dirname, join } from "path";
4
4
 
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = dirname(__filename);
7
7
  const distDir = join(__dirname, "..", "dist");
8
8
 
9
- const { initConfig } = await import(join(distDir, "init.js"));
9
+ // Wrap path -> file:// URL so dynamic import() works on Windows.
10
+ // Node's ESM loader rejects raw "C:\\..." paths with ERR_UNSUPPORTED_ESM_URL_SCHEME.
11
+ const toUrl = (p) => pathToFileURL(p).href;
12
+
13
+ const { initConfig } = await import(toUrl(join(distDir, "init.js")));
10
14
  await initConfig();
11
15
 
12
- const { default: hooCore } = await import(join(distDir, "extensions", "core", "hoo-core.js"));
13
- const { main } = await import(join(distDir, "main.js"));
16
+ const { default: hooCore } = await import(toUrl(join(distDir, "extensions", "core", "hoo-core.js")));
17
+ const { main } = await import(toUrl(join(distDir, "main.js")));
14
18
 
15
19
  await main(process.argv.slice(2), { extensionFactories: [hooCore] });
package/dist/config.d.ts CHANGED
@@ -58,6 +58,12 @@ export declare function getChangelogPath(): string;
58
58
  export declare function getInteractiveAssetsDir(): string;
59
59
  /** Get path to a bundled interactive asset */
60
60
  export declare function getBundledInteractiveAssetPath(name: string): string;
61
+ /**
62
+ * Get path to bundled init templates (default modes/profiles seeded into HOOCODE_DIR on first run).
63
+ * - For Bun binary: templates/ next to executable
64
+ * - For Node.js (dist/) and tsx (src/): templates/ at the package root
65
+ */
66
+ export declare function getTemplatesDir(): string;
61
67
  export declare const PACKAGE_NAME: string;
62
68
  export declare const APP_NAME: string;
63
69
  export declare const APP_TITLE: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from \"child_process\";\nimport { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { shouldUseWindowsShell } from \"./utils/child-process.js\";\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\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageName = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [...prefixArgs, \"install\", \"-g\", updatePackageName]);\n\t\t\tconst uninstallStep =\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\tshell: shouldUseWindowsShell(command),\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\treturn root ? [root, dirname(root)] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath: string;\n\ttry {\n\t\tnormalizedPath = realpathSync(resolvedPath);\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDir = normalizeExistingPathForComparison(getPackageDir());\n\treturn (\n\t\t!!packageDir &&\n\t\tgetGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\t\tconst normalizedRoot = normalizeExistingPathForComparison(root);\n\t\t\treturn (\n\t\t\t\t!!normalizedRoot &&\n\t\t\t\tpackageDir.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`)\n\t\t\t);\n\t\t})\n\t);\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/kolisachint/hoocode/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\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.HOOCODE_PACKAGE_DIR ?? process.env.PI_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(getPackageDir(), \"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(getPackageDir(), \"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 * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json hoocodeConfig — accepts legacy piConfig)\n// =============================================================================\n\ninterface AppConfigBlock {\n\tname?: string;\n\tconfigDir?: string;\n}\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\thoocodeConfig?: AppConfigBlock;\n\tpiConfig?: AppConfigBlock;\n}\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n\nconst appConfig: AppConfigBlock = pkg.hoocodeConfig ?? pkg.piConfig ?? {};\nconst appConfigName: string | undefined = appConfig.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@kolisachint/hoocode-agent\";\nexport const APP_NAME: string = appConfigName || \"hoocode\";\nexport const APP_TITLE: string = appConfigName ? APP_NAME : \"HooCode\";\nexport const CONFIG_DIR_NAME: string = appConfig.configDir || \".hoocode\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., HOOCODE_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\tif (path === \"~\") return homedir();\n\tif (path.startsWith(\"~/\")) return homedir() + path.slice(1);\n\treturn path;\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://hoocode.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl =\n\t\t(process.env.HOOCODE_SHARE_VIEWER_URL ?? process.env.PI_SHARE_VIEWER_URL) || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.hoocode/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.hoocode/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get the hoocode config root directory (parent of agent dir).\n * Returns parent of getAgentDir(), e.g.:\n * HOOCODE_CODING_AGENT_DIR=/custom/agent -> /custom\n * (no env var) -> ~/.hoocode\n */\nexport function getHooCodeDir(): string {\n\treturn dirname(getAgentDir());\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/** 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":"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","sourcesContent":["import { spawnSync } from \"child_process\";\nimport { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { shouldUseWindowsShell } from \"./utils/child-process.js\";\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\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageName = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [...prefixArgs, \"install\", \"-g\", updatePackageName]);\n\t\t\tconst uninstallStep =\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\tshell: shouldUseWindowsShell(command),\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\treturn root ? [root, dirname(root)] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath: string;\n\ttry {\n\t\tnormalizedPath = realpathSync(resolvedPath);\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDir = normalizeExistingPathForComparison(getPackageDir());\n\treturn (\n\t\t!!packageDir &&\n\t\tgetGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\t\tconst normalizedRoot = normalizeExistingPathForComparison(root);\n\t\t\treturn (\n\t\t\t\t!!normalizedRoot &&\n\t\t\t\tpackageDir.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`)\n\t\t\t);\n\t\t})\n\t);\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/kolisachint/hoocode/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\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.HOOCODE_PACKAGE_DIR ?? process.env.PI_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(getPackageDir(), \"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(getPackageDir(), \"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 * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n/**\n * Get path to bundled init templates (default modes/profiles seeded into HOOCODE_DIR on first run).\n * - For Bun binary: templates/ next to executable\n * - For Node.js (dist/) and tsx (src/): templates/ at the package root\n */\nexport function getTemplatesDir(): string {\n\treturn join(getPackageDir(), \"templates\");\n}\n\n// =============================================================================\n// App Config (from package.json hoocodeConfig — accepts legacy piConfig)\n// =============================================================================\n\ninterface AppConfigBlock {\n\tname?: string;\n\tconfigDir?: string;\n}\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\thoocodeConfig?: AppConfigBlock;\n\tpiConfig?: AppConfigBlock;\n}\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n\nconst appConfig: AppConfigBlock = pkg.hoocodeConfig ?? pkg.piConfig ?? {};\nconst appConfigName: string | undefined = appConfig.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@kolisachint/hoocode-agent\";\nexport const APP_NAME: string = appConfigName || \"hoocode\";\nexport const APP_TITLE: string = appConfigName ? APP_NAME : \"HooCode\";\nexport const CONFIG_DIR_NAME: string = appConfig.configDir || \".hoocode\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., HOOCODE_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\tif (path === \"~\") return homedir();\n\tif (path.startsWith(\"~/\")) return homedir() + path.slice(1);\n\treturn path;\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://hoocode.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl =\n\t\t(process.env.HOOCODE_SHARE_VIEWER_URL ?? process.env.PI_SHARE_VIEWER_URL) || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.hoocode/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.hoocode/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get the hoocode config root directory (parent of agent dir).\n * Returns parent of getAgentDir(), e.g.:\n * HOOCODE_CODING_AGENT_DIR=/custom/agent -> /custom\n * (no env var) -> ~/.hoocode\n */\nexport function getHooCodeDir(): string {\n\treturn dirname(getAgentDir());\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/** 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
@@ -326,6 +326,14 @@ export function getInteractiveAssetsDir() {
326
326
  export function getBundledInteractiveAssetPath(name) {
327
327
  return join(getInteractiveAssetsDir(), name);
328
328
  }
329
+ /**
330
+ * Get path to bundled init templates (default modes/profiles seeded into HOOCODE_DIR on first run).
331
+ * - For Bun binary: templates/ next to executable
332
+ * - For Node.js (dist/) and tsx (src/): templates/ at the package root
333
+ */
334
+ export function getTemplatesDir() {
335
+ return join(getPackageDir(), "templates");
336
+ }
329
337
  const pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
330
338
  const appConfig = pkg.hoocodeConfig ?? pkg.piConfig ?? {};
331
339
  const appConfigName = appConfig.name;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from \"child_process\";\nimport { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { shouldUseWindowsShell } from \"./utils/child-process.js\";\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\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageName = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [...prefixArgs, \"install\", \"-g\", updatePackageName]);\n\t\t\tconst uninstallStep =\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\tshell: shouldUseWindowsShell(command),\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\treturn root ? [root, dirname(root)] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath: string;\n\ttry {\n\t\tnormalizedPath = realpathSync(resolvedPath);\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDir = normalizeExistingPathForComparison(getPackageDir());\n\treturn (\n\t\t!!packageDir &&\n\t\tgetGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\t\tconst normalizedRoot = normalizeExistingPathForComparison(root);\n\t\t\treturn (\n\t\t\t\t!!normalizedRoot &&\n\t\t\t\tpackageDir.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`)\n\t\t\t);\n\t\t})\n\t);\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/kolisachint/hoocode/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\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.HOOCODE_PACKAGE_DIR ?? process.env.PI_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(getPackageDir(), \"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(getPackageDir(), \"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 * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json hoocodeConfig — accepts legacy piConfig)\n// =============================================================================\n\ninterface AppConfigBlock {\n\tname?: string;\n\tconfigDir?: string;\n}\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\thoocodeConfig?: AppConfigBlock;\n\tpiConfig?: AppConfigBlock;\n}\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n\nconst appConfig: AppConfigBlock = pkg.hoocodeConfig ?? pkg.piConfig ?? {};\nconst appConfigName: string | undefined = appConfig.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@kolisachint/hoocode-agent\";\nexport const APP_NAME: string = appConfigName || \"hoocode\";\nexport const APP_TITLE: string = appConfigName ? APP_NAME : \"HooCode\";\nexport const CONFIG_DIR_NAME: string = appConfig.configDir || \".hoocode\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., HOOCODE_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\tif (path === \"~\") return homedir();\n\tif (path.startsWith(\"~/\")) return homedir() + path.slice(1);\n\treturn path;\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://hoocode.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl =\n\t\t(process.env.HOOCODE_SHARE_VIEWER_URL ?? process.env.PI_SHARE_VIEWER_URL) || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.hoocode/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.hoocode/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get the hoocode config root directory (parent of agent dir).\n * Returns parent of getAgentDir(), e.g.:\n * HOOCODE_CODING_AGENT_DIR=/custom/agent -> /custom\n * (no env var) -> ~/.hoocode\n */\nexport function getHooCodeDir(): string {\n\treturn dirname(getAgentDir());\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/** 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 { spawnSync } from \"child_process\";\nimport { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { shouldUseWindowsShell } from \"./utils/child-process.js\";\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\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageName = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\"install\", \"-g\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [...prefixArgs, \"install\", \"-g\", updatePackageName]);\n\t\t\tconst uninstallStep =\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\tshell: shouldUseWindowsShell(command),\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\treturn root ? [root, dirname(root)] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath: string;\n\ttry {\n\t\tnormalizedPath = realpathSync(resolvedPath);\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDir = normalizeExistingPathForComparison(getPackageDir());\n\treturn (\n\t\t!!packageDir &&\n\t\tgetGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\t\tconst normalizedRoot = normalizeExistingPathForComparison(root);\n\t\t\treturn (\n\t\t\t\t!!normalizedRoot &&\n\t\t\t\tpackageDir.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`)\n\t\t\t);\n\t\t})\n\t);\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/kolisachint/hoocode/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\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.HOOCODE_PACKAGE_DIR ?? process.env.PI_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(getPackageDir(), \"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(getPackageDir(), \"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 * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n/**\n * Get path to bundled init templates (default modes/profiles seeded into HOOCODE_DIR on first run).\n * - For Bun binary: templates/ next to executable\n * - For Node.js (dist/) and tsx (src/): templates/ at the package root\n */\nexport function getTemplatesDir(): string {\n\treturn join(getPackageDir(), \"templates\");\n}\n\n// =============================================================================\n// App Config (from package.json hoocodeConfig — accepts legacy piConfig)\n// =============================================================================\n\ninterface AppConfigBlock {\n\tname?: string;\n\tconfigDir?: string;\n}\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\thoocodeConfig?: AppConfigBlock;\n\tpiConfig?: AppConfigBlock;\n}\n\nconst pkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n\nconst appConfig: AppConfigBlock = pkg.hoocodeConfig ?? pkg.piConfig ?? {};\nconst appConfigName: string | undefined = appConfig.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@kolisachint/hoocode-agent\";\nexport const APP_NAME: string = appConfigName || \"hoocode\";\nexport const APP_TITLE: string = appConfigName ? APP_NAME : \"HooCode\";\nexport const CONFIG_DIR_NAME: string = appConfig.configDir || \".hoocode\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., HOOCODE_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\tif (path === \"~\") return homedir();\n\tif (path.startsWith(\"~/\")) return homedir() + path.slice(1);\n\treturn path;\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://hoocode.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl =\n\t\t(process.env.HOOCODE_SHARE_VIEWER_URL ?? process.env.PI_SHARE_VIEWER_URL) || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.hoocode/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.hoocode/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get the hoocode config root directory (parent of agent dir).\n * Returns parent of getAgentDir(), e.g.:\n * HOOCODE_CODING_AGENT_DIR=/custom/agent -> /custom\n * (no env var) -> ~/.hoocode\n */\nexport function getHooCodeDir(): string {\n\treturn dirname(getAgentDir());\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/** 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 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAwCA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA4ChD","sourcesContent":["import { copyFile, mkdir, readdir, stat } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getHooCodeDir } from \"./config.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst HOOCODE_DIR = getHooCodeDir();\nconst TEMPLATES_DIR = join(__dirname, \"..\", \"templates\");\n\nasync function exists(p: string): Promise<boolean> {\n\ttry {\n\t\tawait stat(p);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function _copyDir(srcDir: string, destDir: string): Promise<void> {\n\tawait mkdir(destDir, { recursive: true });\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(srcDir);\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const entry of entries) {\n\t\tconst srcPath = join(srcDir, entry);\n\t\tconst destPath = join(destDir, entry);\n\t\tconst entryStat = await stat(srcPath);\n\t\tif (entryStat.isDirectory()) {\n\t\t\tawait _copyDir(srcPath, destPath);\n\t\t} else {\n\t\t\tawait copyFile(srcPath, destPath);\n\t\t}\n\t}\n}\n\nexport async function initConfig(): Promise<void> {\n\tconst configPath = join(HOOCODE_DIR, \"agent\", \"hoo-config.json\");\n\n\tif (await exists(configPath)) {\n\t\treturn;\n\t}\n\n\tawait mkdir(join(HOOCODE_DIR, \"modes\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"profiles\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"mcp-servers\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"extensions\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"agent\"), { recursive: true });\n\n\tawait copyFile(join(TEMPLATES_DIR, \"default-config.json\"), configPath);\n\n\tconst modesDir = join(TEMPLATES_DIR, \"modes\");\n\tlet modeNames: string[] = [];\n\ttry {\n\t\tmodeNames = await readdir(modesDir);\n\t} catch {}\n\n\tfor (const modeName of modeNames) {\n\t\tconst src = join(modesDir, modeName, \"system.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"modes\", modeName, \"system.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n\n\tconst profilesDir = join(TEMPLATES_DIR, \"profiles\");\n\tlet profileNames: string[] = [];\n\ttry {\n\t\tprofileNames = await readdir(profilesDir);\n\t} catch {}\n\n\tfor (const profileName of profileNames) {\n\t\tconst src = join(profilesDir, profileName, \"context.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"profiles\", profileName, \"context.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AA8CA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAsChD","sourcesContent":["import { copyFile, mkdir, readdir, stat } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { getHooCodeDir, getTemplatesDir } from \"./config.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\nconst TEMPLATES_DIR = getTemplatesDir();\n\nasync function exists(p: string): Promise<boolean> {\n\ttry {\n\t\tawait stat(p);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function _copyDir(srcDir: string, destDir: string): Promise<void> {\n\tawait mkdir(destDir, { recursive: true });\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(srcDir);\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const entry of entries) {\n\t\tconst srcPath = join(srcDir, entry);\n\t\tconst destPath = join(destDir, entry);\n\t\tconst entryStat = await stat(srcPath);\n\t\tif (entryStat.isDirectory()) {\n\t\t\tawait _copyDir(srcPath, destPath);\n\t\t} else {\n\t\t\tawait copyFile(srcPath, destPath);\n\t\t}\n\t}\n}\n\nasync function readDirOrWarn(dir: string, label: string): Promise<string[]> {\n\ttry {\n\t\treturn await readdir(dir);\n\t} catch (err) {\n\t\tconst reason = err instanceof Error ? err.message : String(err);\n\t\tconsole.warn(`hoocode init: could not read bundled ${label} at ${dir} (${reason}). Skipping.`);\n\t\treturn [];\n\t}\n}\n\nexport async function initConfig(): Promise<void> {\n\tconst configPath = join(HOOCODE_DIR, \"agent\", \"hoo-config.json\");\n\n\tif (await exists(configPath)) {\n\t\treturn;\n\t}\n\n\tawait mkdir(join(HOOCODE_DIR, \"modes\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"profiles\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"mcp-servers\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"extensions\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"agent\"), { recursive: true });\n\n\tawait copyFile(join(TEMPLATES_DIR, \"default-config.json\"), configPath);\n\n\tconst modesDir = join(TEMPLATES_DIR, \"modes\");\n\tconst modeNames = await readDirOrWarn(modesDir, \"modes\");\n\n\tfor (const modeName of modeNames) {\n\t\tconst src = join(modesDir, modeName, \"system.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"modes\", modeName, \"system.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n\n\tconst profilesDir = join(TEMPLATES_DIR, \"profiles\");\n\tconst profileNames = await readDirOrWarn(profilesDir, \"profiles\");\n\n\tfor (const profileName of profileNames) {\n\t\tconst src = join(profilesDir, profileName, \"context.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"profiles\", profileName, \"context.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n}\n"]}
package/dist/init.js CHANGED
@@ -1,11 +1,8 @@
1
1
  import { copyFile, mkdir, readdir, stat } from "fs/promises";
2
2
  import { dirname, join } from "path";
3
- import { fileURLToPath } from "url";
4
- import { getHooCodeDir } from "./config.js";
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = dirname(__filename);
3
+ import { getHooCodeDir, getTemplatesDir } from "./config.js";
7
4
  const HOOCODE_DIR = getHooCodeDir();
8
- const TEMPLATES_DIR = join(__dirname, "..", "templates");
5
+ const TEMPLATES_DIR = getTemplatesDir();
9
6
  async function exists(p) {
10
7
  try {
11
8
  await stat(p);
@@ -36,6 +33,16 @@ async function _copyDir(srcDir, destDir) {
36
33
  }
37
34
  }
38
35
  }
36
+ async function readDirOrWarn(dir, label) {
37
+ try {
38
+ return await readdir(dir);
39
+ }
40
+ catch (err) {
41
+ const reason = err instanceof Error ? err.message : String(err);
42
+ console.warn(`hoocode init: could not read bundled ${label} at ${dir} (${reason}). Skipping.`);
43
+ return [];
44
+ }
45
+ }
39
46
  export async function initConfig() {
40
47
  const configPath = join(HOOCODE_DIR, "agent", "hoo-config.json");
41
48
  if (await exists(configPath)) {
@@ -48,11 +55,7 @@ export async function initConfig() {
48
55
  await mkdir(join(HOOCODE_DIR, "agent"), { recursive: true });
49
56
  await copyFile(join(TEMPLATES_DIR, "default-config.json"), configPath);
50
57
  const modesDir = join(TEMPLATES_DIR, "modes");
51
- let modeNames = [];
52
- try {
53
- modeNames = await readdir(modesDir);
54
- }
55
- catch { }
58
+ const modeNames = await readDirOrWarn(modesDir, "modes");
56
59
  for (const modeName of modeNames) {
57
60
  const src = join(modesDir, modeName, "system.md");
58
61
  const dest = join(HOOCODE_DIR, "modes", modeName, "system.md");
@@ -62,11 +65,7 @@ export async function initConfig() {
62
65
  }
63
66
  }
64
67
  const profilesDir = join(TEMPLATES_DIR, "profiles");
65
- let profileNames = [];
66
- try {
67
- profileNames = await readdir(profilesDir);
68
- }
69
- catch { }
68
+ const profileNames = await readDirOrWarn(profilesDir, "profiles");
70
69
  for (const profileName of profileNames) {
71
70
  const src = join(profilesDir, profileName, "context.md");
72
71
  const dest = join(HOOCODE_DIR, "profiles", profileName, "context.md");
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFile, mkdir, readdir, stat } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getHooCodeDir } from \"./config.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst HOOCODE_DIR = getHooCodeDir();\nconst TEMPLATES_DIR = join(__dirname, \"..\", \"templates\");\n\nasync function exists(p: string): Promise<boolean> {\n\ttry {\n\t\tawait stat(p);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function _copyDir(srcDir: string, destDir: string): Promise<void> {\n\tawait mkdir(destDir, { recursive: true });\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(srcDir);\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const entry of entries) {\n\t\tconst srcPath = join(srcDir, entry);\n\t\tconst destPath = join(destDir, entry);\n\t\tconst entryStat = await stat(srcPath);\n\t\tif (entryStat.isDirectory()) {\n\t\t\tawait _copyDir(srcPath, destPath);\n\t\t} else {\n\t\t\tawait copyFile(srcPath, destPath);\n\t\t}\n\t}\n}\n\nexport async function initConfig(): Promise<void> {\n\tconst configPath = join(HOOCODE_DIR, \"agent\", \"hoo-config.json\");\n\n\tif (await exists(configPath)) {\n\t\treturn;\n\t}\n\n\tawait mkdir(join(HOOCODE_DIR, \"modes\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"profiles\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"mcp-servers\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"extensions\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"agent\"), { recursive: true });\n\n\tawait copyFile(join(TEMPLATES_DIR, \"default-config.json\"), configPath);\n\n\tconst modesDir = join(TEMPLATES_DIR, \"modes\");\n\tlet modeNames: string[] = [];\n\ttry {\n\t\tmodeNames = await readdir(modesDir);\n\t} catch {}\n\n\tfor (const modeName of modeNames) {\n\t\tconst src = join(modesDir, modeName, \"system.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"modes\", modeName, \"system.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n\n\tconst profilesDir = join(TEMPLATES_DIR, \"profiles\");\n\tlet profileNames: string[] = [];\n\ttry {\n\t\tprofileNames = await readdir(profilesDir);\n\t} catch {}\n\n\tfor (const profileName of profileNames) {\n\t\tconst src = join(profilesDir, profileName, \"context.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"profiles\", profileName, \"context.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFile, mkdir, readdir, stat } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { getHooCodeDir, getTemplatesDir } from \"./config.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\nconst TEMPLATES_DIR = getTemplatesDir();\n\nasync function exists(p: string): Promise<boolean> {\n\ttry {\n\t\tawait stat(p);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function _copyDir(srcDir: string, destDir: string): Promise<void> {\n\tawait mkdir(destDir, { recursive: true });\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(srcDir);\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const entry of entries) {\n\t\tconst srcPath = join(srcDir, entry);\n\t\tconst destPath = join(destDir, entry);\n\t\tconst entryStat = await stat(srcPath);\n\t\tif (entryStat.isDirectory()) {\n\t\t\tawait _copyDir(srcPath, destPath);\n\t\t} else {\n\t\t\tawait copyFile(srcPath, destPath);\n\t\t}\n\t}\n}\n\nasync function readDirOrWarn(dir: string, label: string): Promise<string[]> {\n\ttry {\n\t\treturn await readdir(dir);\n\t} catch (err) {\n\t\tconst reason = err instanceof Error ? err.message : String(err);\n\t\tconsole.warn(`hoocode init: could not read bundled ${label} at ${dir} (${reason}). Skipping.`);\n\t\treturn [];\n\t}\n}\n\nexport async function initConfig(): Promise<void> {\n\tconst configPath = join(HOOCODE_DIR, \"agent\", \"hoo-config.json\");\n\n\tif (await exists(configPath)) {\n\t\treturn;\n\t}\n\n\tawait mkdir(join(HOOCODE_DIR, \"modes\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"profiles\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"mcp-servers\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"extensions\"), { recursive: true });\n\tawait mkdir(join(HOOCODE_DIR, \"agent\"), { recursive: true });\n\n\tawait copyFile(join(TEMPLATES_DIR, \"default-config.json\"), configPath);\n\n\tconst modesDir = join(TEMPLATES_DIR, \"modes\");\n\tconst modeNames = await readDirOrWarn(modesDir, \"modes\");\n\n\tfor (const modeName of modeNames) {\n\t\tconst src = join(modesDir, modeName, \"system.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"modes\", modeName, \"system.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n\n\tconst profilesDir = join(TEMPLATES_DIR, \"profiles\");\n\tconst profileNames = await readDirOrWarn(profilesDir, \"profiles\");\n\n\tfor (const profileName of profileNames) {\n\t\tconst src = join(profilesDir, profileName, \"context.md\");\n\t\tconst dest = join(HOOCODE_DIR, \"profiles\", profileName, \"context.md\");\n\t\tif (await exists(src)) {\n\t\t\tawait mkdir(dirname(dest), { recursive: true });\n\t\t\tawait copyFile(src, dest);\n\t\t}\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-sandbox",
3
3
  "private": true,
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-agent",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "hoocodeConfig": {
@@ -42,9 +42,9 @@
42
42
  "prepublishOnly": "npm run clean && npm run build"
43
43
  },
44
44
  "dependencies": {
45
- "@kolisachint/hoocode-agent-core": "^0.1.4",
46
- "@kolisachint/hoocode-ai": "^0.1.4",
47
- "@kolisachint/hoocode-tui": "^0.1.4",
45
+ "@kolisachint/hoocode-agent-core": "^0.2.3",
46
+ "@kolisachint/hoocode-ai": "^0.2.3",
47
+ "@kolisachint/hoocode-tui": "^0.2.3",
48
48
  "@silvia-odwyer/photon-node": "^0.3.4",
49
49
  "chalk": "^5.5.0",
50
50
  "cli-highlight": "^2.1.11",