@kolisachint/hoocode-agent 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +2 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/init-templates.generated.d.ts +4 -0
- package/dist/init-templates.generated.d.ts.map +1 -0
- package/dist/init-templates.generated.js +17 -0
- package/dist/init-templates.generated.js.map +1 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +11 -52
- package/dist/init.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.4] - 2026-05-15
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Fixed Windows standalone `.exe` (winget) and zip binary still failing to seed default `modes/` and `profiles/` on first run. The Bun-compiled entry point (`src/bun/cli.ts`) never invoked `initConfig()` — only the Node wrapper `bin/hoocode.js` did — so `~/.hoocode/{modes,profiles}` stayed empty for users installing via zip or winget. Added the `initConfig()` call to the Bun entry, and embedded the seed templates into the compiled binary itself (new `scripts/embed-templates.mjs` generates `src/init-templates.generated.ts` at build time, and `init.ts` now writes from these constants instead of reading the on-disk `templates/` folder). This also lets the standalone `.exe` self-seed without a sibling `templates/` directory.
|
|
8
|
+
- Dropped the redundant `cp -r templates …` step from `scripts/build-binaries.sh` now that seed content ships inside the binary; this slims every release archive.
|
|
9
|
+
|
|
3
10
|
## [0.2.3] - 2026-05-15
|
|
4
11
|
|
|
5
12
|
### Fixed
|
package/dist/bun/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.js\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.js\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.js\");\nawait import(\"../cli.js\");\n"]}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.js\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.js\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.js\");\nconst { initConfig } = await import(\"../init.js\");\nawait initConfig();\nawait import(\"../cli.js\");\n"]}
|
package/dist/bun/cli.js
CHANGED
|
@@ -5,5 +5,7 @@ process.emitWarning = (() => { });
|
|
|
5
5
|
import { restoreSandboxEnv } from "./restore-sandbox-env.js";
|
|
6
6
|
restoreSandboxEnv();
|
|
7
7
|
await import("./register-bedrock.js");
|
|
8
|
+
const { initConfig } = await import("../init.js");
|
|
9
|
+
await initConfig();
|
|
8
10
|
await import("../cli.js");
|
|
9
11
|
//# sourceMappingURL=cli.js.map
|
package/dist/bun/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAA+B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,EAAE,CAAC;AAEpB,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;AACtC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.js\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.js\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.js\");\nawait import(\"../cli.js\");\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAA+B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,EAAE,CAAC;AAEpB,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;AACtC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;AAClD,MAAM,UAAU,EAAE,CAAC;AACnB,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.js\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.js\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.js\");\nconst { initConfig } = await import(\"../init.js\");\nawait initConfig();\nawait import(\"../cli.js\");\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-templates.generated.d.ts","sourceRoot":"","sources":["../src/init-templates.generated.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,EAAE,MAAo2C,CAAC;AAE34C,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMjD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIpD,CAAC","sourcesContent":["// AUTO-GENERATED by scripts/embed-templates.mjs — do not edit.\n// Source of truth: packages/coding-agent/templates/**\n// Regenerated on every `npm run build`.\n\nexport const EMBEDDED_DEFAULT_CONFIG: string = \"{\\n \\\"version\\\": \\\"1.0\\\",\\n \\\"active_mode\\\": \\\"build\\\",\\n \\\"active_profile\\\": \\\"default\\\",\\n \\\"llm\\\": {\\n \\\"default_provider\\\": \\\"anthropic\\\",\\n \\\"providers\\\": {\\n \\\"anthropic\\\": { \\\"api_key_env\\\": \\\"ANTHROPIC_API_KEY\\\" },\\n \\\"openai\\\": { \\\"api_key_env\\\": \\\"OPENAI_API_KEY\\\" }\\n }\\n },\\n \\\"modes\\\": {\\n \\\"ask\\\": { \\\"auto_allow\\\": [\\\"read\\\"] },\\n \\\"plan\\\": { \\\"auto_allow\\\": [\\\"read\\\", \\\"write\\\"] },\\n \\\"build\\\": { \\\"auto_allow\\\": [\\\"read\\\"] },\\n \\\"agent\\\": { \\\"auto_allow\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] },\\n \\\"debug\\\": { \\\"auto_allow\\\": [\\\"read\\\", \\\"bash\\\"] }\\n },\\n \\\"profiles\\\": {\\n \\\"default\\\": { \\\"enabled_tools\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] },\\n \\\"data\\\": { \\\"enabled_tools\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] },\\n \\\"devops\\\": { \\\"enabled_tools\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] }\\n },\\n \\\"profile_detectors\\\": [\\n { \\\"marker\\\": \\\"dbt_project.yml\\\", \\\"profile\\\": \\\"data\\\" },\\n { \\\"marker\\\": \\\"*.sql\\\", \\\"profile\\\": \\\"data\\\" },\\n { \\\"marker\\\": \\\"terraform.tf\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\".github/workflows\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\"Dockerfile\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\"docker-compose.yml\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\"k8s/\\\", \\\"profile\\\": \\\"devops\\\" }\\n ]\\n}\\n\";\n\nexport const EMBEDDED_MODES: Record<string, string> = {\n\t\"agent\": \"You are in **agent mode** — multi-step autonomy within guardrails.\\n\\nBehaviour:\\n- Use auto-allowed tools freely without per-call confirmation.\\n- Report progress to the user every 3–5 steps: what was done, what is next.\\n- If you encounter genuine ambiguity that would require guessing intent, **stop**, write a clarifying question, and switch to plan mode (`/mode plan`) rather than proceeding on an assumption.\\n- When the task is complete, output a summary:\\n - Files modified (path + one-line description of change).\\n - Tests run and their outcomes.\\n - Any follow-up actions the user should take.\\n\",\n\t\"ask\": \"You are in **ask mode** — read-only Q&A.\\n\\nPermitted: read files, run grep/find, explain code, trace logic, compare approaches, debug conceptually.\\nForbidden: edit files, write files, run commands that modify state.\\n\\nWhen answering:\\n- Cite file paths and line numbers.\\n- Prefer precise over verbose.\\n- If a question requires a code change to answer properly, describe the change; do not apply it.\\n- If the user asks you to edit something, decline and suggest switching to build mode with `/mode build`.\\n\",\n\t\"build\": \"You are in **build mode** — implement carefully, one step at a time.\\n\\nRules:\\n- **One tool per turn.** Plan the action, call the tool, wait for the result before proceeding.\\n- **Read before editing.** Never write to a file you have not read in this session.\\n- **Show diffs** before applying non-trivial edits; wait for implicit acceptance.\\n- **Dangerous ops** (delete, force-push, drop table, rm -rf): state what you are about to do and wait for explicit confirmation.\\n- **Match existing style** — indentation, naming, import order.\\n- **Run tests** after every logical unit of change. Fix failures before continuing.\\n\",\n\t\"debug\": \"You are in **debug mode** — root-cause analysis only, no file modifications.\\n\\nProcess:\\n1. **Gather evidence** — read logs, error traces, and relevant source. Run safe diagnostic commands (grep, find, read, non-mutating shell commands).\\n2. **Reproduce** — identify the minimal condition that triggers the bug.\\n3. **Trace** — follow the full call path from entry point to failure site, citing file and line at each step.\\n4. **State the root cause** in one clear sentence.\\n5. **Describe the fix** — files, lines, and what to change — but do not apply it.\\n\\nForbidden: edit or write any file. To apply a fix, switch to build mode with `/mode build`.\\n\",\n\t\"plan\": \"You are in **plan mode** — explore and design, no source edits.\\n\\nYour job: produce a complete, actionable implementation plan.\\n\\nSteps:\\n1. Read relevant files and ask clarifying questions before drafting.\\n2. Write the finished plan to `.hoocode/plan.md` with these sections:\\n - **Goal** — one sentence.\\n - **Files to modify** — path, line range, what changes.\\n - **New files** — path, purpose.\\n - **Tests** — what to add or update.\\n - **Verification** — commands to confirm correctness.\\n3. After writing the plan, tell the user: \\\"Plan written to `.hoocode/plan.md`. Run `/approve` to begin execution.\\\"\\n\\nForbidden: edit any source file. Only `.hoocode/plan.md` may be written.\\n\",\n};\n\nexport const EMBEDDED_PROFILES: Record<string, string> = {\n\t\"data\": \"**Profile: data / BigQuery / SQL**\\n\\n- **Dry-run first.** Never execute a mutating SQL statement (INSERT, UPDATE, DELETE, MERGE, CREATE, DROP) without a dry-run or explicit user confirmation.\\n- **No `SELECT *` on large tables.** Always scope columns; add a LIMIT during exploration.\\n- **Inspect schema before querying** — run `INFORMATION_SCHEMA` or `bq show` to confirm field names, types, and partition keys.\\n- **DDL changes**: show the diff and wait for confirmation before applying.\\n- **Validate before trusting results**: check for nulls in join keys, unexpected cardinality changes, and partition/date freshness.\\n\",\n\t\"default\": \"**Profile: general full-stack**\\n\\n- Match existing patterns in the codebase — naming, structure, import style — before introducing new ones.\\n- Prefer the smallest change that satisfies the requirement. Avoid refactoring beyond the task scope.\\n- Standard tooling assumptions: Node.js, TypeScript, npm workspaces, vitest, ESLint/Biome.\\n- When multiple approaches are equivalent, choose the one already present elsewhere in the repo.\\n\",\n\t\"devops\": \"**Profile: infrastructure / DevOps**\\n\\n- **Never run `terraform apply`, `kubectl delete`, or equivalent destructive commands** without showing the plan/diff and receiving explicit confirmation.\\n- **Plan before apply**: always run `terraform plan` or `kubectl diff` first and surface the output.\\n- **Prefer declarative config** — Terraform HCL, Kubernetes manifests, Helm values — over imperative CLI sequences.\\n- **Secrets**: reference vault paths or secret manager keys; never hardcode or echo credentials.\\n- **Every change must include a rollback strategy** — previous state, revert command, or rollback manifest.\\n\",\n};\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// AUTO-GENERATED by scripts/embed-templates.mjs — do not edit.
|
|
2
|
+
// Source of truth: packages/coding-agent/templates/**
|
|
3
|
+
// Regenerated on every `npm run build`.
|
|
4
|
+
export const EMBEDDED_DEFAULT_CONFIG = "{\n \"version\": \"1.0\",\n \"active_mode\": \"build\",\n \"active_profile\": \"default\",\n \"llm\": {\n \"default_provider\": \"anthropic\",\n \"providers\": {\n \"anthropic\": { \"api_key_env\": \"ANTHROPIC_API_KEY\" },\n \"openai\": { \"api_key_env\": \"OPENAI_API_KEY\" }\n }\n },\n \"modes\": {\n \"ask\": { \"auto_allow\": [\"read\"] },\n \"plan\": { \"auto_allow\": [\"read\", \"write\"] },\n \"build\": { \"auto_allow\": [\"read\"] },\n \"agent\": { \"auto_allow\": [\"read\", \"bash\", \"edit\", \"write\"] },\n \"debug\": { \"auto_allow\": [\"read\", \"bash\"] }\n },\n \"profiles\": {\n \"default\": { \"enabled_tools\": [\"read\", \"bash\", \"edit\", \"write\"] },\n \"data\": { \"enabled_tools\": [\"read\", \"bash\", \"edit\", \"write\"] },\n \"devops\": { \"enabled_tools\": [\"read\", \"bash\", \"edit\", \"write\"] }\n },\n \"profile_detectors\": [\n { \"marker\": \"dbt_project.yml\", \"profile\": \"data\" },\n { \"marker\": \"*.sql\", \"profile\": \"data\" },\n { \"marker\": \"terraform.tf\", \"profile\": \"devops\" },\n { \"marker\": \".github/workflows\", \"profile\": \"devops\" },\n { \"marker\": \"Dockerfile\", \"profile\": \"devops\" },\n { \"marker\": \"docker-compose.yml\", \"profile\": \"devops\" },\n { \"marker\": \"k8s/\", \"profile\": \"devops\" }\n ]\n}\n";
|
|
5
|
+
export const EMBEDDED_MODES = {
|
|
6
|
+
"agent": "You are in **agent mode** — multi-step autonomy within guardrails.\n\nBehaviour:\n- Use auto-allowed tools freely without per-call confirmation.\n- Report progress to the user every 3–5 steps: what was done, what is next.\n- If you encounter genuine ambiguity that would require guessing intent, **stop**, write a clarifying question, and switch to plan mode (`/mode plan`) rather than proceeding on an assumption.\n- When the task is complete, output a summary:\n - Files modified (path + one-line description of change).\n - Tests run and their outcomes.\n - Any follow-up actions the user should take.\n",
|
|
7
|
+
"ask": "You are in **ask mode** — read-only Q&A.\n\nPermitted: read files, run grep/find, explain code, trace logic, compare approaches, debug conceptually.\nForbidden: edit files, write files, run commands that modify state.\n\nWhen answering:\n- Cite file paths and line numbers.\n- Prefer precise over verbose.\n- If a question requires a code change to answer properly, describe the change; do not apply it.\n- If the user asks you to edit something, decline and suggest switching to build mode with `/mode build`.\n",
|
|
8
|
+
"build": "You are in **build mode** — implement carefully, one step at a time.\n\nRules:\n- **One tool per turn.** Plan the action, call the tool, wait for the result before proceeding.\n- **Read before editing.** Never write to a file you have not read in this session.\n- **Show diffs** before applying non-trivial edits; wait for implicit acceptance.\n- **Dangerous ops** (delete, force-push, drop table, rm -rf): state what you are about to do and wait for explicit confirmation.\n- **Match existing style** — indentation, naming, import order.\n- **Run tests** after every logical unit of change. Fix failures before continuing.\n",
|
|
9
|
+
"debug": "You are in **debug mode** — root-cause analysis only, no file modifications.\n\nProcess:\n1. **Gather evidence** — read logs, error traces, and relevant source. Run safe diagnostic commands (grep, find, read, non-mutating shell commands).\n2. **Reproduce** — identify the minimal condition that triggers the bug.\n3. **Trace** — follow the full call path from entry point to failure site, citing file and line at each step.\n4. **State the root cause** in one clear sentence.\n5. **Describe the fix** — files, lines, and what to change — but do not apply it.\n\nForbidden: edit or write any file. To apply a fix, switch to build mode with `/mode build`.\n",
|
|
10
|
+
"plan": "You are in **plan mode** — explore and design, no source edits.\n\nYour job: produce a complete, actionable implementation plan.\n\nSteps:\n1. Read relevant files and ask clarifying questions before drafting.\n2. Write the finished plan to `.hoocode/plan.md` with these sections:\n - **Goal** — one sentence.\n - **Files to modify** — path, line range, what changes.\n - **New files** — path, purpose.\n - **Tests** — what to add or update.\n - **Verification** — commands to confirm correctness.\n3. After writing the plan, tell the user: \"Plan written to `.hoocode/plan.md`. Run `/approve` to begin execution.\"\n\nForbidden: edit any source file. Only `.hoocode/plan.md` may be written.\n",
|
|
11
|
+
};
|
|
12
|
+
export const EMBEDDED_PROFILES = {
|
|
13
|
+
"data": "**Profile: data / BigQuery / SQL**\n\n- **Dry-run first.** Never execute a mutating SQL statement (INSERT, UPDATE, DELETE, MERGE, CREATE, DROP) without a dry-run or explicit user confirmation.\n- **No `SELECT *` on large tables.** Always scope columns; add a LIMIT during exploration.\n- **Inspect schema before querying** — run `INFORMATION_SCHEMA` or `bq show` to confirm field names, types, and partition keys.\n- **DDL changes**: show the diff and wait for confirmation before applying.\n- **Validate before trusting results**: check for nulls in join keys, unexpected cardinality changes, and partition/date freshness.\n",
|
|
14
|
+
"default": "**Profile: general full-stack**\n\n- Match existing patterns in the codebase — naming, structure, import style — before introducing new ones.\n- Prefer the smallest change that satisfies the requirement. Avoid refactoring beyond the task scope.\n- Standard tooling assumptions: Node.js, TypeScript, npm workspaces, vitest, ESLint/Biome.\n- When multiple approaches are equivalent, choose the one already present elsewhere in the repo.\n",
|
|
15
|
+
"devops": "**Profile: infrastructure / DevOps**\n\n- **Never run `terraform apply`, `kubectl delete`, or equivalent destructive commands** without showing the plan/diff and receiving explicit confirmation.\n- **Plan before apply**: always run `terraform plan` or `kubectl diff` first and surface the output.\n- **Prefer declarative config** — Terraform HCL, Kubernetes manifests, Helm values — over imperative CLI sequences.\n- **Secrets**: reference vault paths or secret manager keys; never hardcode or echo credentials.\n- **Every change must include a rollback strategy** — previous state, revert command, or rollback manifest.\n",
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=init-templates.generated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-templates.generated.js","sourceRoot":"","sources":["../src/init-templates.generated.ts"],"names":[],"mappings":"AAAA,iEAA+D;AAC/D,sDAAsD;AACtD,wCAAwC;AAExC,MAAM,CAAC,MAAM,uBAAuB,GAAW,21CAA21C,CAAC;AAE34C,MAAM,CAAC,MAAM,cAAc,GAA2B;IACrD,OAAO,EAAE,umBAAmmB;IAC5mB,KAAK,EAAE,ogBAAkgB;IACzgB,OAAO,EAAE,unBAAmnB;IAC5nB,OAAO,EAAE,6pBAAipB;IAC1pB,MAAM,EAAE,4sBAAgsB;CACxsB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACxD,MAAM,EAAE,qnBAAmnB;IAC3nB,SAAS,EAAE,0bAAsb;IACjc,QAAQ,EAAE,snBAAgnB;CAC1nB,CAAC","sourcesContent":["// AUTO-GENERATED by scripts/embed-templates.mjs — do not edit.\n// Source of truth: packages/coding-agent/templates/**\n// Regenerated on every `npm run build`.\n\nexport const EMBEDDED_DEFAULT_CONFIG: string = \"{\\n \\\"version\\\": \\\"1.0\\\",\\n \\\"active_mode\\\": \\\"build\\\",\\n \\\"active_profile\\\": \\\"default\\\",\\n \\\"llm\\\": {\\n \\\"default_provider\\\": \\\"anthropic\\\",\\n \\\"providers\\\": {\\n \\\"anthropic\\\": { \\\"api_key_env\\\": \\\"ANTHROPIC_API_KEY\\\" },\\n \\\"openai\\\": { \\\"api_key_env\\\": \\\"OPENAI_API_KEY\\\" }\\n }\\n },\\n \\\"modes\\\": {\\n \\\"ask\\\": { \\\"auto_allow\\\": [\\\"read\\\"] },\\n \\\"plan\\\": { \\\"auto_allow\\\": [\\\"read\\\", \\\"write\\\"] },\\n \\\"build\\\": { \\\"auto_allow\\\": [\\\"read\\\"] },\\n \\\"agent\\\": { \\\"auto_allow\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] },\\n \\\"debug\\\": { \\\"auto_allow\\\": [\\\"read\\\", \\\"bash\\\"] }\\n },\\n \\\"profiles\\\": {\\n \\\"default\\\": { \\\"enabled_tools\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] },\\n \\\"data\\\": { \\\"enabled_tools\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] },\\n \\\"devops\\\": { \\\"enabled_tools\\\": [\\\"read\\\", \\\"bash\\\", \\\"edit\\\", \\\"write\\\"] }\\n },\\n \\\"profile_detectors\\\": [\\n { \\\"marker\\\": \\\"dbt_project.yml\\\", \\\"profile\\\": \\\"data\\\" },\\n { \\\"marker\\\": \\\"*.sql\\\", \\\"profile\\\": \\\"data\\\" },\\n { \\\"marker\\\": \\\"terraform.tf\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\".github/workflows\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\"Dockerfile\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\"docker-compose.yml\\\", \\\"profile\\\": \\\"devops\\\" },\\n { \\\"marker\\\": \\\"k8s/\\\", \\\"profile\\\": \\\"devops\\\" }\\n ]\\n}\\n\";\n\nexport const EMBEDDED_MODES: Record<string, string> = {\n\t\"agent\": \"You are in **agent mode** — multi-step autonomy within guardrails.\\n\\nBehaviour:\\n- Use auto-allowed tools freely without per-call confirmation.\\n- Report progress to the user every 3–5 steps: what was done, what is next.\\n- If you encounter genuine ambiguity that would require guessing intent, **stop**, write a clarifying question, and switch to plan mode (`/mode plan`) rather than proceeding on an assumption.\\n- When the task is complete, output a summary:\\n - Files modified (path + one-line description of change).\\n - Tests run and their outcomes.\\n - Any follow-up actions the user should take.\\n\",\n\t\"ask\": \"You are in **ask mode** — read-only Q&A.\\n\\nPermitted: read files, run grep/find, explain code, trace logic, compare approaches, debug conceptually.\\nForbidden: edit files, write files, run commands that modify state.\\n\\nWhen answering:\\n- Cite file paths and line numbers.\\n- Prefer precise over verbose.\\n- If a question requires a code change to answer properly, describe the change; do not apply it.\\n- If the user asks you to edit something, decline and suggest switching to build mode with `/mode build`.\\n\",\n\t\"build\": \"You are in **build mode** — implement carefully, one step at a time.\\n\\nRules:\\n- **One tool per turn.** Plan the action, call the tool, wait for the result before proceeding.\\n- **Read before editing.** Never write to a file you have not read in this session.\\n- **Show diffs** before applying non-trivial edits; wait for implicit acceptance.\\n- **Dangerous ops** (delete, force-push, drop table, rm -rf): state what you are about to do and wait for explicit confirmation.\\n- **Match existing style** — indentation, naming, import order.\\n- **Run tests** after every logical unit of change. Fix failures before continuing.\\n\",\n\t\"debug\": \"You are in **debug mode** — root-cause analysis only, no file modifications.\\n\\nProcess:\\n1. **Gather evidence** — read logs, error traces, and relevant source. Run safe diagnostic commands (grep, find, read, non-mutating shell commands).\\n2. **Reproduce** — identify the minimal condition that triggers the bug.\\n3. **Trace** — follow the full call path from entry point to failure site, citing file and line at each step.\\n4. **State the root cause** in one clear sentence.\\n5. **Describe the fix** — files, lines, and what to change — but do not apply it.\\n\\nForbidden: edit or write any file. To apply a fix, switch to build mode with `/mode build`.\\n\",\n\t\"plan\": \"You are in **plan mode** — explore and design, no source edits.\\n\\nYour job: produce a complete, actionable implementation plan.\\n\\nSteps:\\n1. Read relevant files and ask clarifying questions before drafting.\\n2. Write the finished plan to `.hoocode/plan.md` with these sections:\\n - **Goal** — one sentence.\\n - **Files to modify** — path, line range, what changes.\\n - **New files** — path, purpose.\\n - **Tests** — what to add or update.\\n - **Verification** — commands to confirm correctness.\\n3. After writing the plan, tell the user: \\\"Plan written to `.hoocode/plan.md`. Run `/approve` to begin execution.\\\"\\n\\nForbidden: edit any source file. Only `.hoocode/plan.md` may be written.\\n\",\n};\n\nexport const EMBEDDED_PROFILES: Record<string, string> = {\n\t\"data\": \"**Profile: data / BigQuery / SQL**\\n\\n- **Dry-run first.** Never execute a mutating SQL statement (INSERT, UPDATE, DELETE, MERGE, CREATE, DROP) without a dry-run or explicit user confirmation.\\n- **No `SELECT *` on large tables.** Always scope columns; add a LIMIT during exploration.\\n- **Inspect schema before querying** — run `INFORMATION_SCHEMA` or `bq show` to confirm field names, types, and partition keys.\\n- **DDL changes**: show the diff and wait for confirmation before applying.\\n- **Validate before trusting results**: check for nulls in join keys, unexpected cardinality changes, and partition/date freshness.\\n\",\n\t\"default\": \"**Profile: general full-stack**\\n\\n- Match existing patterns in the codebase — naming, structure, import style — before introducing new ones.\\n- Prefer the smallest change that satisfies the requirement. Avoid refactoring beyond the task scope.\\n- Standard tooling assumptions: Node.js, TypeScript, npm workspaces, vitest, ESLint/Biome.\\n- When multiple approaches are equivalent, choose the one already present elsewhere in the repo.\\n\",\n\t\"devops\": \"**Profile: infrastructure / DevOps**\\n\\n- **Never run `terraform apply`, `kubectl delete`, or equivalent destructive commands** without showing the plan/diff and receiving explicit confirmation.\\n- **Plan before apply**: always run `terraform plan` or `kubectl diff` first and surface the output.\\n- **Prefer declarative config** — Terraform HCL, Kubernetes manifests, Helm values — over imperative CLI sequences.\\n- **Secrets**: reference vault paths or secret manager keys; never hardcode or echo credentials.\\n- **Every change must include a rollback strategy** — previous state, revert command, or rollback manifest.\\n\",\n};\n"]}
|
package/dist/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAqBA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBhD","sourcesContent":["import { mkdir, stat, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { getHooCodeDir } from \"./config.js\";\nimport { EMBEDDED_DEFAULT_CONFIG, EMBEDDED_MODES, EMBEDDED_PROFILES } from \"./init-templates.generated.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\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 writeSeedFile(dest: string, contents: string): Promise<void> {\n\tawait mkdir(dirname(dest), { recursive: true });\n\tawait writeFile(dest, contents);\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 writeSeedFile(configPath, EMBEDDED_DEFAULT_CONFIG);\n\n\tfor (const [modeName, content] of Object.entries(EMBEDDED_MODES)) {\n\t\tawait writeSeedFile(join(HOOCODE_DIR, \"modes\", modeName, \"system.md\"), content);\n\t}\n\n\tfor (const [profileName, content] of Object.entries(EMBEDDED_PROFILES)) {\n\t\tawait writeSeedFile(join(HOOCODE_DIR, \"profiles\", profileName, \"context.md\"), content);\n\t}\n}\n"]}
|
package/dist/init.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdir, stat, writeFile } from "fs/promises";
|
|
2
2
|
import { dirname, join } from "path";
|
|
3
|
-
import { getHooCodeDir
|
|
3
|
+
import { getHooCodeDir } from "./config.js";
|
|
4
|
+
import { EMBEDDED_DEFAULT_CONFIG, EMBEDDED_MODES, EMBEDDED_PROFILES } from "./init-templates.generated.js";
|
|
4
5
|
const HOOCODE_DIR = getHooCodeDir();
|
|
5
|
-
const TEMPLATES_DIR = getTemplatesDir();
|
|
6
6
|
async function exists(p) {
|
|
7
7
|
try {
|
|
8
8
|
await stat(p);
|
|
@@ -12,36 +12,9 @@ async function exists(p) {
|
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
async function
|
|
16
|
-
await mkdir(
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
entries = await readdir(srcDir);
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
for (const entry of entries) {
|
|
25
|
-
const srcPath = join(srcDir, entry);
|
|
26
|
-
const destPath = join(destDir, entry);
|
|
27
|
-
const entryStat = await stat(srcPath);
|
|
28
|
-
if (entryStat.isDirectory()) {
|
|
29
|
-
await _copyDir(srcPath, destPath);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
await copyFile(srcPath, destPath);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
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
|
-
}
|
|
15
|
+
async function writeSeedFile(dest, contents) {
|
|
16
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
17
|
+
await writeFile(dest, contents);
|
|
45
18
|
}
|
|
46
19
|
export async function initConfig() {
|
|
47
20
|
const configPath = join(HOOCODE_DIR, "agent", "hoo-config.json");
|
|
@@ -53,26 +26,12 @@ export async function initConfig() {
|
|
|
53
26
|
await mkdir(join(HOOCODE_DIR, "mcp-servers"), { recursive: true });
|
|
54
27
|
await mkdir(join(HOOCODE_DIR, "extensions"), { recursive: true });
|
|
55
28
|
await mkdir(join(HOOCODE_DIR, "agent"), { recursive: true });
|
|
56
|
-
await
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
for (const modeName of modeNames) {
|
|
60
|
-
const src = join(modesDir, modeName, "system.md");
|
|
61
|
-
const dest = join(HOOCODE_DIR, "modes", modeName, "system.md");
|
|
62
|
-
if (await exists(src)) {
|
|
63
|
-
await mkdir(dirname(dest), { recursive: true });
|
|
64
|
-
await copyFile(src, dest);
|
|
65
|
-
}
|
|
29
|
+
await writeSeedFile(configPath, EMBEDDED_DEFAULT_CONFIG);
|
|
30
|
+
for (const [modeName, content] of Object.entries(EMBEDDED_MODES)) {
|
|
31
|
+
await writeSeedFile(join(HOOCODE_DIR, "modes", modeName, "system.md"), content);
|
|
66
32
|
}
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
for (const profileName of profileNames) {
|
|
70
|
-
const src = join(profilesDir, profileName, "context.md");
|
|
71
|
-
const dest = join(HOOCODE_DIR, "profiles", profileName, "context.md");
|
|
72
|
-
if (await exists(src)) {
|
|
73
|
-
await mkdir(dirname(dest), { recursive: true });
|
|
74
|
-
await copyFile(src, dest);
|
|
75
|
-
}
|
|
33
|
+
for (const [profileName, content] of Object.entries(EMBEDDED_PROFILES)) {
|
|
34
|
+
await writeSeedFile(join(HOOCODE_DIR, "profiles", profileName, "context.md"), content);
|
|
76
35
|
}
|
|
77
36
|
}
|
|
78
37
|
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAE3G,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC;AAEpC,KAAK,UAAU,MAAM,CAAC,CAAS,EAAoB;IAClD,IAAI,CAAC;QACJ,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AAAA,CACD;AAED,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,QAAgB,EAAiB;IAC3E,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAAA,CAChC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,GAAkB;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAEjE,IAAI,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO;IACR,CAAC;IAED,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7D,MAAM,aAAa,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAEzD,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAClE,MAAM,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;IACjF,CAAC;IAED,KAAK,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACxE,MAAM,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;IACxF,CAAC;AAAA,CACD","sourcesContent":["import { mkdir, stat, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { getHooCodeDir } from \"./config.js\";\nimport { EMBEDDED_DEFAULT_CONFIG, EMBEDDED_MODES, EMBEDDED_PROFILES } from \"./init-templates.generated.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\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 writeSeedFile(dest: string, contents: string): Promise<void> {\n\tawait mkdir(dirname(dest), { recursive: true });\n\tawait writeFile(dest, contents);\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 writeSeedFile(configPath, EMBEDDED_DEFAULT_CONFIG);\n\n\tfor (const [modeName, content] of Object.entries(EMBEDDED_MODES)) {\n\t\tawait writeSeedFile(join(HOOCODE_DIR, \"modes\", modeName, \"system.md\"), content);\n\t}\n\n\tfor (const [profileName, content] of Object.entries(EMBEDDED_PROFILES)) {\n\t\tawait writeSeedFile(join(HOOCODE_DIR, \"profiles\", profileName, \"context.md\"), content);\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolisachint/hoocode-agent",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"hoocodeConfig": {
|
|
@@ -33,8 +33,9 @@
|
|
|
33
33
|
],
|
|
34
34
|
"scripts": {
|
|
35
35
|
"clean": "shx rm -rf dist",
|
|
36
|
-
"dev": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
37
|
-
"
|
|
36
|
+
"dev": "node scripts/embed-templates.mjs && tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
37
|
+
"embed-templates": "node scripts/embed-templates.mjs",
|
|
38
|
+
"build": "npm run embed-templates && tsgo -p tsconfig.build.json && shx chmod +x dist/cli.js && shx chmod +x bin/hoocode.js && npm run copy-assets",
|
|
38
39
|
"build:binary": "npm --prefix ../tui run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm run build && npm run copy-binary-assets && pkg . --entry bin/hoocode.js",
|
|
39
40
|
"copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/",
|
|
40
41
|
"copy-binary-assets": "shx cp package.json dist/ && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html dist/export-html/ && shx cp src/core/export-html/vendor/*.js dist/export-html/vendor/ && shx cp -r docs dist/ && shx cp -r examples dist/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/",
|
|
@@ -42,9 +43,9 @@
|
|
|
42
43
|
"prepublishOnly": "npm run clean && npm run build"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"@kolisachint/hoocode-agent-core": "^0.2.
|
|
46
|
-
"@kolisachint/hoocode-ai": "^0.2.
|
|
47
|
-
"@kolisachint/hoocode-tui": "^0.2.
|
|
46
|
+
"@kolisachint/hoocode-agent-core": "^0.2.4",
|
|
47
|
+
"@kolisachint/hoocode-ai": "^0.2.4",
|
|
48
|
+
"@kolisachint/hoocode-tui": "^0.2.4",
|
|
48
49
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
49
50
|
"chalk": "^5.5.0",
|
|
50
51
|
"cli-highlight": "^2.1.11",
|