harness-bujang 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +59 -0
  2. package/dist/index.js +222 -41
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,8 +18,24 @@ npx harness-bujang init --lang=en
18
18
 
19
19
  # Different folder, skip the chat-room UI
20
20
  npx harness-bujang init --target=./my-app --no-template
21
+
22
+ # Upgrade an existing install — adds NEW team files only, never touches existing ones
23
+ npx harness-bujang update
21
24
  ```
22
25
 
26
+ > ## ⚠️ First-time vs upgrade — read this before re-running
27
+ >
28
+ > | Situation | Command | What it does |
29
+ > |-----------|---------|-------------|
30
+ > | **First install** (empty project) | `npx harness-bujang init` | Full install — director + 16 teams + cofounder |
31
+ > | **Pulling new version** (already installed) | `npx harness-bujang update` | **Adds only NEW files.** Existing agent files are never touched |
32
+ > | **Clean reset** (drop customizations) | `npx harness-bujang init --yes` | **Overwrites every agent file** ⚠️ |
33
+ >
34
+ > **If you've already been using harness-bujang, use `update`.** Running
35
+ > `init --yes` to upgrade will destroy any domain rules / learned customizations
36
+ > you've added to existing agent files. `CLAUDE.md` and
37
+ > `docs/AGENT_LEARNING_LOG.md` are never touched by any of the three commands.
38
+
23
39
  ### See the chat-room — any stack
24
40
 
25
41
  ```bash
@@ -72,6 +88,49 @@ npx harness-bujang status [path]
72
88
 
73
89
  Verifies the install: agent files, `CLAUDE.md` section, learning log, chat-room UI. Counts unfilled `{{...}}` placeholders.
74
90
 
91
+ ### `update`
92
+
93
+ ```
94
+ npx harness-bujang update [options]
95
+
96
+ Options:
97
+ --target=<path> Project root (default: cwd)
98
+ --lang=<ko|en> Language for newly-added agents (default: ko)
99
+ ```
100
+
101
+ **Safe additive update.** Adds NEW agent files only. Existing files are NEVER touched.
102
+
103
+ Use this when you upgrade `harness-bujang` and want to pull in newly-introduced
104
+ team members (e.g. the cofounder persona in 0.5.1, or the content-production
105
+ teams in 0.5.0) without disturbing any local customizations.
106
+
107
+ ```
108
+ $ npx harness-bujang update
109
+
110
+ 🔄 Harness-Bujang update
111
+ 📂 Checking .claude/agents/
112
+ = consultant.md (exists, kept as-is)
113
+ = dev-team.md (exists, kept as-is)
114
+ + cofounder.md
115
+ + image-team.md
116
+ ...
117
+
118
+ 📋 Summary
119
+ Added: 4 (new files only)
120
+ Kept: 14 (existing files untouched)
121
+ ```
122
+
123
+ > ⚠️ **`update` vs `init --yes`** — pick the right one:
124
+ >
125
+ > | Command | What happens |
126
+ > |---------|-------------|
127
+ > | `npx harness-bujang update` | **Safe.** Adds only new files. Custom edits preserved. |
128
+ > | `npx harness-bujang init --yes` | **Destructive.** Overwrites every agent file. Customizations lost. |
129
+ >
130
+ > Default to `update` for upgrades. Use `init --yes` only for a clean reset.
131
+
132
+ `CLAUDE.md` and `docs/AGENT_LEARNING_LOG.md` are **never** touched by either command.
133
+
75
134
  ### `chat`
76
135
 
77
136
  ```
package/dist/index.js CHANGED
@@ -862,11 +862,11 @@ async function upsertEnvVar(envFile, key, value) {
862
862
  }
863
863
  async function confirm2(message) {
864
864
  process.stdout.write(`${message} [y/N] `);
865
- return new Promise((resolve6) => {
865
+ return new Promise((resolve7) => {
866
866
  process.stdin.setEncoding("utf8");
867
867
  process.stdin.once("data", (chunk) => {
868
868
  const ans = chunk.toString().trim().toLowerCase();
869
- resolve6(ans === "y" || ans === "yes");
869
+ resolve7(ans === "y" || ans === "yes");
870
870
  process.stdin.pause();
871
871
  });
872
872
  });
@@ -1009,7 +1009,7 @@ async function runChat(args) {
1009
1009
  res.writeHead(404);
1010
1010
  res.end("not found");
1011
1011
  });
1012
- await new Promise((resolve6) => server.listen(port, "127.0.0.1", resolve6));
1012
+ await new Promise((resolve7) => server.listen(port, "127.0.0.1", resolve7));
1013
1013
  const url = `http://localhost:${port}`;
1014
1014
  console.log();
1015
1015
  console.log(c4.bold(c4.green("\u{1F7E2} \uD558\uB124\uC2A4 \uD1A1\uBC29 viewer")) + c4.dim(" \u2014 " + url));
@@ -1061,12 +1061,12 @@ async function findOpenPort(preferred) {
1061
1061
  throw new Error(`Could not find a free port in range ${preferred}-${preferred + 19}`);
1062
1062
  }
1063
1063
  function portIsFree(port) {
1064
- return new Promise((resolve6) => {
1064
+ return new Promise((resolve7) => {
1065
1065
  const tester = http.createServer();
1066
- tester.once("error", () => resolve6(false));
1066
+ tester.once("error", () => resolve7(false));
1067
1067
  tester.once("listening", () => {
1068
1068
  tester.close();
1069
- resolve6(true);
1069
+ resolve7(true);
1070
1070
  });
1071
1071
  tester.listen(port, "127.0.0.1");
1072
1072
  });
@@ -1080,10 +1080,10 @@ function openBrowser(url) {
1080
1080
  }
1081
1081
  }
1082
1082
  function readBody(req) {
1083
- return new Promise((resolve6, reject) => {
1083
+ return new Promise((resolve7, reject) => {
1084
1084
  const chunks = [];
1085
1085
  req.on("data", (chunk) => chunks.push(chunk));
1086
- req.on("end", () => resolve6(Buffer.concat(chunks).toString("utf8")));
1086
+ req.on("end", () => resolve7(Buffer.concat(chunks).toString("utf8")));
1087
1087
  req.on("error", reject);
1088
1088
  });
1089
1089
  }
@@ -1883,7 +1883,12 @@ async function exists5(p) {
1883
1883
  }
1884
1884
  }
1885
1885
 
1886
- // src/index.ts
1886
+ // src/update.ts
1887
+ import * as fs7 from "fs/promises";
1888
+ import * as path7 from "path";
1889
+ import { fileURLToPath as fileURLToPath2 } from "url";
1890
+ var __filename3 = fileURLToPath2(import.meta.url);
1891
+ var __dirname3 = path7.dirname(__filename3);
1887
1892
  var c6 = {
1888
1893
  bold: (s) => `\x1B[1m${s}\x1B[22m`,
1889
1894
  dim: (s) => `\x1B[2m${s}\x1B[22m`,
@@ -1892,18 +1897,184 @@ var c6 = {
1892
1897
  yellow: (s) => `\x1B[33m${s}\x1B[39m`,
1893
1898
  cyan: (s) => `\x1B[36m${s}\x1B[39m`
1894
1899
  };
1895
- var HELP = `
1896
- ${c6.bold("harness-bujang")} \u2014 Korean-style multi-agent harness director for Claude Code
1897
- ${c6.dim("https://github.com/bjcho4141/harness-bujang")}
1898
-
1899
- ${c6.bold("Usage:")}
1900
- npx harness-bujang ${c6.cyan("init")} [options] Install the harness into a project
1901
- npx harness-bujang ${c6.cyan("status")} [options] Verify the harness install
1902
- npx harness-bujang ${c6.cyan("chat")} [options] Open the standalone chat-room viewer (any stack)
1903
- npx harness-bujang ${c6.cyan("adapt")} --to=<cursor|cline|aider|codex|gemini|all> Convert .claude/agents/ for other tools
1904
- npx harness-bujang ${c6.cyan("migrate")} --to=<sqlite|supabase> Move chat data between backends
1900
+ async function runUpdate(args) {
1901
+ const opts = parseArgs5(args);
1902
+ const assets = await resolveAssetPaths2();
1903
+ const agentsSrc = path7.join(assets.agents, opts.lang);
1904
+ const agentsDst = path7.join(opts.target, ".claude/agents");
1905
+ console.log();
1906
+ console.log(c6.bold("\u{1F504} Harness-Bujang update"));
1907
+ console.log(c6.dim(` Target: ${opts.target}`));
1908
+ console.log(c6.dim(` Language: ${opts.lang}`));
1909
+ console.log();
1910
+ if (!await exists6(agentsDst)) {
1911
+ console.log(c6.yellow("\u26A0 No .claude/agents/ directory found."));
1912
+ console.log();
1913
+ console.log(" This project has not been initialized yet. Run:");
1914
+ console.log(` ${c6.cyan("npx harness-bujang init")}`);
1915
+ console.log();
1916
+ return;
1917
+ }
1918
+ const scan = await scanProject(opts.target);
1919
+ const context = await buildContext(opts, scan);
1920
+ const agentFiles = (await fs7.readdir(agentsSrc)).filter((f) => f.endsWith(".md"));
1921
+ agentFiles.sort();
1922
+ const added = [];
1923
+ const kept = [];
1924
+ console.log(c6.bold("\u{1F4C2} Checking .claude/agents/"));
1925
+ for (const f of agentFiles) {
1926
+ const dst = path7.join(agentsDst, f);
1927
+ if (await exists6(dst)) {
1928
+ kept.push(f);
1929
+ console.log(` ${c6.dim("=")} ${f} ${c6.dim("(exists, kept as-is)")}`);
1930
+ continue;
1931
+ }
1932
+ const raw = await fs7.readFile(path7.join(agentsSrc, f), "utf8");
1933
+ await fs7.writeFile(dst, renderTemplate(raw, context));
1934
+ added.push(f);
1935
+ console.log(` ${c6.green("+")} ${f}`);
1936
+ }
1937
+ console.log();
1938
+ console.log(c6.bold("\u{1F4CB} Summary"));
1939
+ console.log(` ${c6.green("Added")}: ${added.length} ${added.length ? c6.dim("(new files only)") : ""}`);
1940
+ console.log(` ${c6.dim("Kept")}: ${kept.length} ${c6.dim("(existing files untouched)")}`);
1941
+ console.log();
1942
+ if (added.length === 0) {
1943
+ console.log(c6.dim(" Nothing new to install \u2014 your harness is already up to date."));
1944
+ console.log();
1945
+ return;
1946
+ }
1947
+ console.log(c6.bold(c6.green("\u2705 Update done.")));
1948
+ console.log();
1949
+ console.log(" Existing agent files were not modified. Your customizations are safe.");
1950
+ console.log(" To overwrite everything (e.g. for a clean reset), use instead:");
1951
+ console.log(` ${c6.cyan("npx harness-bujang init --yes")}`);
1952
+ console.log();
1953
+ }
1954
+ async function resolveAssetPaths2() {
1955
+ const packaged = path7.resolve(__dirname3, "..", "templates");
1956
+ if (await exists6(packaged)) {
1957
+ return {
1958
+ agents: path7.join(packaged, "agents"),
1959
+ templates: path7.join(packaged, "templates"),
1960
+ projectTemplate: path7.join(packaged, "project-template"),
1961
+ mode: "packaged"
1962
+ };
1963
+ }
1964
+ const monorepoRoot = path7.resolve(__dirname3, "../../..");
1965
+ const sharedDir = path7.join(monorepoRoot, "shared");
1966
+ if (await exists6(sharedDir)) {
1967
+ return {
1968
+ agents: path7.join(sharedDir, "agents"),
1969
+ templates: path7.join(sharedDir, "templates"),
1970
+ projectTemplate: path7.join(monorepoRoot, "packages/template"),
1971
+ mode: "monorepo"
1972
+ };
1973
+ }
1974
+ throw new Error(
1975
+ `Could not locate harness-bujang assets. Tried:
1976
+ - ${packaged}
1977
+ - ${sharedDir}
1978
+ `
1979
+ );
1980
+ }
1981
+ async function buildContext(opts, scan) {
1982
+ return {
1983
+ PROJECT_PATH: opts.target,
1984
+ PROJECT_NAME: path7.basename(opts.target),
1985
+ PROJECT_CATEGORY: scan.framework.startsWith("Next.js") ? "Web application" : "Software project",
1986
+ DIFFERENTIATION: "(define your project differentiation here if relevant)",
1987
+ STACK_FRAMEWORK: scan.framework,
1988
+ STACK_LANGUAGE: scan.language,
1989
+ STACK_DB: scan.db,
1990
+ STACK_UI: scan.ui,
1991
+ STACK_PAYMENT: scan.payment,
1992
+ STACK_EXTRA: "(none)",
1993
+ HARNESS_TABLE: "harness_messages",
1994
+ ADMIN_HARNESS_ROUTE: "/admin/harness",
1995
+ LEARNING_LOG_PATH: "docs/AGENT_LEARNING_LOG.md",
1996
+ TASKS_TRACKER_GLOB: "docs/TASKS_*.md",
1997
+ BENCHMARK_DOC_PATH: "docs/BENCHMARK.md",
1998
+ GH_USER: scan.ghUser,
1999
+ BUILD_CMD: scan.buildCmd || "(no build script)",
2000
+ TYPECHECK_CMD: scan.typecheckCmd || "(no type-check command)",
2001
+ TEST_CMD: scan.testCmd || "(no tests configured)",
2002
+ E2E_CMD: scan.e2eCmd || "(no E2E setup)",
2003
+ DEV_URL: "http://localhost:3000",
2004
+ DB_TYPES_PATH: scan.dbTypesPath,
2005
+ DB_CLIENT_PATTERN: `Use the project's existing DB client convention. See ${scan.dbTypesPath}.`,
2006
+ KNOWN_SCHEMA_DRIFT: "(none documented yet)",
2007
+ COMMON_FK_HINTS: "(extract from your schema as you go)",
2008
+ ACCESS_POLICY_NOTES: "(document RLS / middleware as encountered)",
2009
+ MIGRATION_NAMING: "supabase/migrations/XXXXX_name.sql (or per-stack)",
2010
+ MIGRATION_APPLY_CMD: "supabase db push (or stack-specific)",
2011
+ ROUTE_GROUPS: scan.routeGroups,
2012
+ MIDDLEWARE_PATH: scan.middlewarePath,
2013
+ KEY_RELATIONSHIPS: "(document key entity relations as you go)",
2014
+ AUTH_GUARD_PATTERN: "(stack-specific)",
2015
+ ADMIN_GUARD_PATTERN: "(stack-specific)",
2016
+ API_RESPONSE_SHAPE: "{ data, error, message }",
2017
+ PRIMARY_COLOR: "#6366F1",
2018
+ FRAMEWORK_REVIEW_RULES: "",
2019
+ TEST_ACCOUNTS: "(define your test accounts here)",
2020
+ LEGAL_CONTEXT: "(no special legal context)",
2021
+ LANG_CODE: opts.lang,
2022
+ TODAY: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
2023
+ COMPLETED_DOCS_PATTERN: "docs/\uC644\uB8CC_*.md"
2024
+ };
2025
+ }
2026
+ function parseArgs5(args) {
2027
+ const lang = getFlag5(args, "--lang") ?? "ko";
2028
+ if (!["ko", "en"].includes(lang)) {
2029
+ throw new Error(`--lang must be "ko" or "en", got "${lang}"`);
2030
+ }
2031
+ const targetRaw = getFlag5(args, "--target") ?? ".";
2032
+ return {
2033
+ target: path7.resolve(targetRaw),
2034
+ lang
2035
+ };
2036
+ }
2037
+ function getFlag5(args, name) {
2038
+ for (const a of args) {
2039
+ if (a.startsWith(`${name}=`)) return a.slice(name.length + 1);
2040
+ }
2041
+ const idx = args.indexOf(name);
2042
+ if (idx >= 0 && idx + 1 < args.length && !args[idx + 1].startsWith("--")) {
2043
+ return args[idx + 1];
2044
+ }
2045
+ return void 0;
2046
+ }
2047
+ async function exists6(p) {
2048
+ try {
2049
+ await fs7.access(p);
2050
+ return true;
2051
+ } catch {
2052
+ return false;
2053
+ }
2054
+ }
1905
2055
 
1906
- ${c6.bold("Options for init:")}
2056
+ // src/index.ts
2057
+ var c7 = {
2058
+ bold: (s) => `\x1B[1m${s}\x1B[22m`,
2059
+ dim: (s) => `\x1B[2m${s}\x1B[22m`,
2060
+ green: (s) => `\x1B[32m${s}\x1B[39m`,
2061
+ red: (s) => `\x1B[31m${s}\x1B[39m`,
2062
+ yellow: (s) => `\x1B[33m${s}\x1B[39m`,
2063
+ cyan: (s) => `\x1B[36m${s}\x1B[39m`
2064
+ };
2065
+ var HELP = `
2066
+ ${c7.bold("harness-bujang")} \u2014 Korean-style multi-agent harness director for Claude Code
2067
+ ${c7.dim("https://github.com/bjcho4141/harness-bujang")}
2068
+
2069
+ ${c7.bold("Usage:")}
2070
+ npx harness-bujang ${c7.cyan("init")} [options] Install the harness into a project
2071
+ npx harness-bujang ${c7.cyan("update")} [options] Pull NEW agents only \u2014 existing files untouched
2072
+ npx harness-bujang ${c7.cyan("status")} [options] Verify the harness install
2073
+ npx harness-bujang ${c7.cyan("chat")} [options] Open the standalone chat-room viewer (any stack)
2074
+ npx harness-bujang ${c7.cyan("adapt")} --to=<cursor|cline|aider|codex|gemini|all> Convert .claude/agents/ for other tools
2075
+ npx harness-bujang ${c7.cyan("migrate")} --to=<sqlite|supabase> Move chat data between backends
2076
+
2077
+ ${c7.bold("Options for init:")}
1907
2078
  --lang=<ko|en> Agent language (default: ko \u2014 full \uBD80\uC7A5 persona)
1908
2079
  --chat=<sqlite|supabase> Chat-room backend (default: sqlite \u2014 local file, no setup)
1909
2080
  --commit-chat Don't gitignore .harness/ (for solo cross-machine sync via git)
@@ -1915,49 +2086,56 @@ ${c6.bold("Options for init:")}
1915
2086
  --no-learning-log Skip learning log seed
1916
2087
  --yes, -y Skip prompts and overwrite (non-interactive \u2014 for CI / scripts)
1917
2088
 
1918
- ${c6.dim("Run without --yes for an interactive setup (prompts for language, backend, etc.).")}
2089
+ ${c7.dim("Run without --yes for an interactive setup (prompts for language, backend, etc.).")}
1919
2090
 
1920
- ${c6.bold("Options for chat:")}
2091
+ ${c7.bold("Options for chat:")}
1921
2092
  --target=<path> Project root (default: cwd)
1922
2093
  --port=<number> Preferred port (default: 7777, falls forward if busy)
1923
2094
  --no-open Don't auto-open the browser
1924
2095
  --create Create an empty chat DB + schema if none exists yet
1925
2096
 
1926
- ${c6.bold("Options for adapt:")}
2097
+ ${c7.bold("Options for adapt:")}
1927
2098
  --to=<cursor|cline|aider|codex|gemini|all> Required \u2014 comma-separated list also OK
1928
2099
  --target=<path> Project root (default: cwd)
1929
2100
  --yes, -y Overwrite existing adapter files
1930
2101
 
1931
- ${c6.dim("Adapter targets:")}
1932
- ${c6.dim(" cursor \u2192 .cursor/rules/bujang-*.mdc (Cursor IDE)")}
1933
- ${c6.dim(" cline \u2192 .clinerules/bujang-*.md (Cline)")}
1934
- ${c6.dim(" aider \u2192 CONVENTIONS.md + .aider.conf.yml (Aider)")}
1935
- ${c6.dim(" codex \u2192 AGENTS.md (Codex CLI / Copilot Coding Agent / Cody)")}
1936
- ${c6.dim(" gemini \u2192 GEMINI.md + .gemini/styleguide.md (Antigravity / Gemini CLI / Code Assist)")}
2102
+ ${c7.bold("Options for update:")}
2103
+ --target=<path> Project root (default: cwd)
2104
+ --lang=<ko|en> Language for newly-added agents (default: ko)
2105
+
2106
+ ${c7.dim(" update only adds NEW agent files. Existing files are NEVER touched.")}
2107
+ ${c7.dim(" For a clean overwrite (resets all agents), use: bujang init --yes")}
2108
+
2109
+ ${c7.dim("Adapter targets:")}
2110
+ ${c7.dim(" cursor \u2192 .cursor/rules/bujang-*.mdc (Cursor IDE)")}
2111
+ ${c7.dim(" cline \u2192 .clinerules/bujang-*.md (Cline)")}
2112
+ ${c7.dim(" aider \u2192 CONVENTIONS.md + .aider.conf.yml (Aider)")}
2113
+ ${c7.dim(" codex \u2192 AGENTS.md (Codex CLI / Copilot Coding Agent / Cody)")}
2114
+ ${c7.dim(" gemini \u2192 GEMINI.md + .gemini/styleguide.md (Antigravity / Gemini CLI / Code Assist)")}
1937
2115
 
1938
- ${c6.bold("Options for migrate:")}
2116
+ ${c7.bold("Options for migrate:")}
1939
2117
  --to=<sqlite|supabase> Required \u2014 target backend
1940
2118
  --target=<path> Project root (default: cwd)
1941
2119
  --yes, -y Skip confirmation
1942
2120
 
1943
- ${c6.bold("Examples:")}
1944
- ${c6.dim("# Install Korean Bujang persona, SQLite chat (default \u2014 zero setup)")}
2121
+ ${c7.bold("Examples:")}
2122
+ ${c7.dim("# Install Korean Bujang persona, SQLite chat (default \u2014 zero setup)")}
1945
2123
  npx harness-bujang init --lang=ko
1946
2124
 
1947
- ${c6.dim("# Open the standalone chat-room \u2014 works on ANY stack (Next.js, Rails, Django, \u2026)")}
2125
+ ${c7.dim("# Open the standalone chat-room \u2014 works on ANY stack (Next.js, Rails, Django, \u2026)")}
1948
2126
  npx harness-bujang chat
1949
- ${c6.dim("# \u2192 opens http://localhost:7777 in your browser")}
2127
+ ${c7.dim("# \u2192 opens http://localhost:7777 in your browser")}
1950
2128
 
1951
- ${c6.dim("# Solo, multiple machines \u2014 sync chat history via git")}
2129
+ ${c7.dim("# Solo, multiple machines \u2014 sync chat history via git")}
1952
2130
  npx harness-bujang init --commit-chat
1953
2131
 
1954
- ${c6.dim("# Production project with team sharing \u2014 Supabase backend")}
2132
+ ${c7.dim("# Production project with team sharing \u2014 Supabase backend")}
1955
2133
  npx harness-bujang init --chat=supabase
1956
2134
 
1957
- ${c6.dim("# Started solo, now scaling up \u2014 promote to cloud")}
2135
+ ${c7.dim("# Started solo, now scaling up \u2014 promote to cloud")}
1958
2136
  bujang migrate --to=supabase
1959
2137
 
1960
- ${c6.dim("# Going back to solo / archive \u2014 pull cloud data into local SQLite")}
2138
+ ${c7.dim("# Going back to solo / archive \u2014 pull cloud data into local SQLite")}
1961
2139
  bujang migrate --to=sqlite
1962
2140
  `;
1963
2141
  async function main() {
@@ -1976,12 +2154,15 @@ async function main() {
1976
2154
  case "adapt":
1977
2155
  await runAdapt(args.slice(1));
1978
2156
  break;
2157
+ case "update":
2158
+ await runUpdate(args.slice(1));
2159
+ break;
1979
2160
  case "migrate":
1980
2161
  await runMigrate(args.slice(1));
1981
2162
  break;
1982
2163
  case "--version":
1983
2164
  case "-v":
1984
- console.log("0.5.1");
2165
+ console.log("0.5.2");
1985
2166
  break;
1986
2167
  case "--help":
1987
2168
  case "-h":
@@ -1989,13 +2170,13 @@ async function main() {
1989
2170
  console.log(HELP);
1990
2171
  break;
1991
2172
  default:
1992
- console.error(c6.red(`Unknown command: ${command}`));
2173
+ console.error(c7.red(`Unknown command: ${command}`));
1993
2174
  console.log(HELP);
1994
2175
  process.exit(1);
1995
2176
  }
1996
2177
  }
1997
2178
  main().catch((err) => {
1998
- console.error(c6.red(`
2179
+ console.error(c7.red(`
1999
2180
  \u2716 ${err.message}`));
2000
2181
  if (process.env.DEBUG) console.error(err.stack);
2001
2182
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harness-bujang",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Install the Harness-Bujang multi-agent harness into any project — Director, 7 specialist teams, real-time chat-room UI. Korean and English personas. Works with Claude Code, Cursor, Cline, Aider, or any tool that reads .claude/agents/.",
5
5
  "keywords": [
6
6
  "claude-code",