harness-bujang 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/index.js +86 -6
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -7,13 +7,16 @@ Install the [Harness-Bujang](https://github.com/bjcho4141/harness-bujang) multi-
|
|
|
7
7
|
## Quick start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
#
|
|
10
|
+
# Interactive setup — prompts for language, backend, etc.
|
|
11
11
|
npx harness-bujang init
|
|
12
12
|
|
|
13
|
+
# Non-interactive (CI / scripts) — accept all defaults
|
|
14
|
+
npx harness-bujang init --yes
|
|
15
|
+
|
|
13
16
|
# Korean agents (full 부장 persona)
|
|
14
17
|
npx harness-bujang init --lang=ko
|
|
15
18
|
|
|
16
|
-
#
|
|
19
|
+
# Different folder, skip the chat-room UI
|
|
17
20
|
npx harness-bujang init --target=./my-app --no-template
|
|
18
21
|
```
|
|
19
22
|
|
|
@@ -40,9 +43,11 @@ Options:
|
|
|
40
43
|
--no-template Skip chat-room UI install
|
|
41
44
|
--no-claude-md Skip CLAUDE.md edit
|
|
42
45
|
--no-learning-log Skip learning log seed
|
|
43
|
-
--yes, -y
|
|
46
|
+
--yes, -y Skip prompts and overwrite (non-interactive — for CI / scripts)
|
|
44
47
|
```
|
|
45
48
|
|
|
49
|
+
When `--yes` is omitted and stdin is a TTY, the CLI prompts for language, chat backend, and (for Next.js projects) whether to install the chat-room UI.
|
|
50
|
+
|
|
46
51
|
### `status`
|
|
47
52
|
|
|
48
53
|
```
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import * as fs2 from "fs/promises";
|
|
5
5
|
import * as path2 from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
+
import { select, confirm } from "@inquirer/prompts";
|
|
7
8
|
|
|
8
9
|
// src/scan.ts
|
|
9
10
|
import * as fs from "fs/promises";
|
|
@@ -180,13 +181,11 @@ If installed via npm, try reinstalling. If running from source, run "npm run bui
|
|
|
180
181
|
);
|
|
181
182
|
}
|
|
182
183
|
async function runInit(args) {
|
|
183
|
-
|
|
184
|
+
let opts = parseArgs(args);
|
|
184
185
|
const assets = await resolveAssetPaths();
|
|
185
186
|
console.log();
|
|
186
187
|
console.log(c.bold("\u{1F4E6} Harness-Bujang init"));
|
|
187
188
|
console.log(c.dim(` Target: ${opts.target}`));
|
|
188
|
-
console.log(c.dim(` Language: ${opts.lang}`));
|
|
189
|
-
console.log(c.dim(` Chat backend: ${opts.chatBackend}${opts.chatBackend === "sqlite" ? c.dim(" (default \u2014 local file)") : c.dim(" (cloud Postgres)")}`));
|
|
190
189
|
console.log(c.dim(` Assets: ${assets.mode}`));
|
|
191
190
|
console.log();
|
|
192
191
|
if (!await exists2(opts.target)) {
|
|
@@ -201,6 +200,49 @@ async function runInit(args) {
|
|
|
201
200
|
console.log(` Payment: ${scan.payment}`);
|
|
202
201
|
console.log(` GitHub: ${scan.ghUser}`);
|
|
203
202
|
console.log();
|
|
203
|
+
const interactive = !opts.yes && Boolean(process.stdin.isTTY);
|
|
204
|
+
if (interactive) {
|
|
205
|
+
try {
|
|
206
|
+
opts = await promptInteractive(opts, scan);
|
|
207
|
+
if (await isExistingInstall(opts.target)) {
|
|
208
|
+
const overwrite = await confirm({
|
|
209
|
+
message: "Existing harness install detected. Overwrite all files to apply your selections?",
|
|
210
|
+
default: false
|
|
211
|
+
});
|
|
212
|
+
if (overwrite) opts.yes = true;
|
|
213
|
+
}
|
|
214
|
+
} catch (err) {
|
|
215
|
+
if (err && typeof err === "object" && "name" in err && err.name === "ExitPromptError") {
|
|
216
|
+
console.log(c.dim(" (aborted)"));
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
console.log(c.bold("\u{1F4CB} Configuration"));
|
|
223
|
+
console.log(c.dim(` Language: ${opts.lang}`));
|
|
224
|
+
console.log(c.dim(` Chat backend: ${opts.chatBackend}${opts.chatBackend === "sqlite" ? " (local file)" : " (cloud Postgres)"}`));
|
|
225
|
+
if (scan.framework.startsWith("Next.js")) {
|
|
226
|
+
console.log(c.dim(` Chat-room UI: ${opts.installTemplate ? "install" : "skip"}`));
|
|
227
|
+
}
|
|
228
|
+
console.log(c.dim(` On conflict: ${opts.yes ? "overwrite" : "skip existing files"}`));
|
|
229
|
+
console.log();
|
|
230
|
+
if (interactive) {
|
|
231
|
+
try {
|
|
232
|
+
const proceed = await confirm({ message: "Proceed with these settings?", default: true });
|
|
233
|
+
if (!proceed) {
|
|
234
|
+
console.log(c.dim(" (aborted)"));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
console.log();
|
|
238
|
+
} catch (err) {
|
|
239
|
+
if (err && typeof err === "object" && "name" in err && err.name === "ExitPromptError") {
|
|
240
|
+
console.log(c.dim(" (aborted)"));
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
throw err;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
204
246
|
const context = {
|
|
205
247
|
PROJECT_PATH: opts.target,
|
|
206
248
|
PROJECT_NAME: path2.basename(opts.target),
|
|
@@ -355,6 +397,32 @@ async function runInit(args) {
|
|
|
355
397
|
console.log(` ${c.cyan("3.")} Watch ${c.bold(context.ADMIN_HARNESS_ROUTE)} for live updates (after env setup)`);
|
|
356
398
|
console.log();
|
|
357
399
|
}
|
|
400
|
+
async function promptInteractive(opts, scan) {
|
|
401
|
+
const lang = await select({
|
|
402
|
+
message: "Agent language",
|
|
403
|
+
choices: [
|
|
404
|
+
{ name: "English", value: "en" },
|
|
405
|
+
{ name: "Korean \u2014 full \uBD80\uC7A5 persona (\uD55C\uAD6D\uC5B4)", value: "ko" }
|
|
406
|
+
],
|
|
407
|
+
default: opts.lang
|
|
408
|
+
});
|
|
409
|
+
const chatBackend = await select({
|
|
410
|
+
message: "Chat backend",
|
|
411
|
+
choices: [
|
|
412
|
+
{ name: "SQLite \u2014 local file, zero setup (recommended)", value: "sqlite" },
|
|
413
|
+
{ name: "Supabase \u2014 cloud Postgres for team sharing", value: "supabase" }
|
|
414
|
+
],
|
|
415
|
+
default: opts.chatBackend
|
|
416
|
+
});
|
|
417
|
+
let installTemplate = opts.installTemplate;
|
|
418
|
+
if (scan.framework.startsWith("Next.js") && opts.installTemplate) {
|
|
419
|
+
installTemplate = await confirm({
|
|
420
|
+
message: "Install chat-room UI (Next.js admin route at /admin/harness)?",
|
|
421
|
+
default: true
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
return { ...opts, lang, chatBackend, installTemplate };
|
|
425
|
+
}
|
|
358
426
|
function parseArgs(args) {
|
|
359
427
|
const lang = getFlag(args, "--lang") ?? "en";
|
|
360
428
|
if (!["ko", "en"].includes(lang)) {
|
|
@@ -388,6 +456,16 @@ function getFlag(args, name) {
|
|
|
388
456
|
}
|
|
389
457
|
return void 0;
|
|
390
458
|
}
|
|
459
|
+
async function isExistingInstall(target) {
|
|
460
|
+
const probes = [
|
|
461
|
+
path2.join(target, ".claude/agents/director.md"),
|
|
462
|
+
path2.join(target, ".claude/agents/dev-team.md")
|
|
463
|
+
];
|
|
464
|
+
for (const p of probes) {
|
|
465
|
+
if (await exists2(p)) return true;
|
|
466
|
+
}
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
391
469
|
async function exists2(p) {
|
|
392
470
|
try {
|
|
393
471
|
await fs2.access(p);
|
|
@@ -663,7 +741,7 @@ Run "npx harness-bujang init" first.`
|
|
|
663
741
|
}
|
|
664
742
|
console.log();
|
|
665
743
|
console.log(c3.dim("Pass --yes to skip this confirmation."));
|
|
666
|
-
if (!await
|
|
744
|
+
if (!await confirm2("Continue?")) {
|
|
667
745
|
console.log(c3.dim("Aborted."));
|
|
668
746
|
return;
|
|
669
747
|
}
|
|
@@ -775,7 +853,7 @@ async function upsertEnvVar(envFile, key, value) {
|
|
|
775
853
|
}
|
|
776
854
|
await fs4.writeFile(envFile, content);
|
|
777
855
|
}
|
|
778
|
-
async function
|
|
856
|
+
async function confirm2(message) {
|
|
779
857
|
process.stdout.write(`${message} [y/N] `);
|
|
780
858
|
return new Promise((resolve4) => {
|
|
781
859
|
process.stdin.setEncoding("utf8");
|
|
@@ -843,7 +921,9 @@ ${c4.bold("Options for init:")}
|
|
|
843
921
|
--no-template Skip chat-room UI install
|
|
844
922
|
--no-claude-md Skip CLAUDE.md edit
|
|
845
923
|
--no-learning-log Skip learning log seed
|
|
846
|
-
--yes, -y
|
|
924
|
+
--yes, -y Skip prompts and overwrite (non-interactive \u2014 for CI / scripts)
|
|
925
|
+
|
|
926
|
+
${c4.dim("Run without --yes for an interactive setup (prompts for language, backend, etc.).")}
|
|
847
927
|
|
|
848
928
|
${c4.bold("Options for migrate:")}
|
|
849
929
|
--to=<sqlite|supabase> Required \u2014 target backend
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harness-bujang",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|
|
@@ -53,5 +53,8 @@
|
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
55
|
"node": ">=20"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@inquirer/prompts": "^8.4.2"
|
|
56
59
|
}
|
|
57
60
|
}
|