harness-bujang 0.5.6 → 0.5.8
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/dist/index.js +38 -49
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -925,9 +925,8 @@ console.log(' \u2713 Transferred ' + total + ' messages');
|
|
|
925
925
|
import * as http from "http";
|
|
926
926
|
import * as path5 from "path";
|
|
927
927
|
import * as fs5 from "fs";
|
|
928
|
-
import {
|
|
929
|
-
import
|
|
930
|
-
var execFileP = promisify(execFile);
|
|
928
|
+
import { spawn } from "child_process";
|
|
929
|
+
import Database from "better-sqlite3";
|
|
931
930
|
var c4 = {
|
|
932
931
|
bold: (s) => `\x1B[1m${s}\x1B[22m`,
|
|
933
932
|
dim: (s) => `\x1B[2m${s}\x1B[22m`,
|
|
@@ -938,34 +937,37 @@ var c4 = {
|
|
|
938
937
|
};
|
|
939
938
|
async function runChat(args) {
|
|
940
939
|
const opts = parseArgs3(args);
|
|
940
|
+
const dbPath = resolveDbPath(opts.target);
|
|
941
|
+
const dbIsNew = !fs5.existsSync(dbPath);
|
|
942
|
+
if (dbIsNew) fs5.mkdirSync(path5.dirname(dbPath), { recursive: true });
|
|
943
|
+
let db;
|
|
941
944
|
try {
|
|
942
|
-
|
|
943
|
-
} catch {
|
|
945
|
+
db = new Database(dbPath);
|
|
946
|
+
} catch (err) {
|
|
944
947
|
console.log();
|
|
945
|
-
console.log(c4.red("\u2716
|
|
948
|
+
console.log(c4.red("\u2716 Failed to open chat DB at " + dbPath));
|
|
949
|
+
console.log(" " + c4.dim(String(err)));
|
|
946
950
|
console.log();
|
|
947
|
-
console.log("
|
|
948
|
-
console.log("
|
|
949
|
-
console.log(" Fedora: " + c4.bold("sudo dnf install sqlite"));
|
|
950
|
-
console.log(" Windows: https://www.sqlite.org/download.html (sqlite-tools-win-x64)");
|
|
951
|
+
console.log(" This usually means better-sqlite3 could not load its native binding.");
|
|
952
|
+
console.log(" Try " + c4.bold("npm i -g harness-bujang@latest") + " to fetch a fresh prebuild.");
|
|
951
953
|
console.log();
|
|
952
954
|
process.exitCode = 1;
|
|
953
955
|
return;
|
|
954
956
|
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
await runSql(dbPath, SCHEMA_SQL);
|
|
957
|
+
db.pragma("journal_mode = WAL");
|
|
958
|
+
db.exec(SCHEMA_SQL);
|
|
959
|
+
if (dbIsNew) {
|
|
959
960
|
const seedId = `seed-${Date.now()}`;
|
|
960
|
-
|
|
961
|
-
dbPath,
|
|
961
|
+
db.prepare(
|
|
962
962
|
`INSERT INTO harness_messages (id, "from", "to", type, message, severity)
|
|
963
|
-
VALUES (
|
|
964
|
-
);
|
|
963
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
964
|
+
).run(seedId, "\uBD80\uC7A5", "\uB300\uD45C\uB2D8", "info", "\uD1A1\uBC29\uC774 \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uCCAB \uBA85\uB839\uC744 \uB0B4\uB824\uC8FC\uC138\uC694.", "info");
|
|
965
965
|
console.log(c4.dim(` created empty chat DB at ${dbPath}`));
|
|
966
|
-
} else {
|
|
967
|
-
await runSql(dbPath, SCHEMA_SQL);
|
|
968
966
|
}
|
|
967
|
+
const insertStmt = db.prepare(
|
|
968
|
+
`INSERT INTO harness_messages (id, "from", "to", type, message, severity)
|
|
969
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
970
|
+
);
|
|
969
971
|
const port = await findOpenPort(opts.port);
|
|
970
972
|
const server = http.createServer(async (req, res) => {
|
|
971
973
|
const url2 = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
@@ -977,7 +979,7 @@ async function runChat(args) {
|
|
|
977
979
|
if (req.method === "GET" && url2.pathname === "/api/messages") {
|
|
978
980
|
const days = parseInt(url2.searchParams.get("days") ?? "7", 10);
|
|
979
981
|
try {
|
|
980
|
-
const rows =
|
|
982
|
+
const rows = readMessages(db, days);
|
|
981
983
|
res.writeHead(200, { "content-type": "application/json" });
|
|
982
984
|
res.end(JSON.stringify({ data: rows }));
|
|
983
985
|
} catch (err) {
|
|
@@ -1001,11 +1003,7 @@ async function runChat(args) {
|
|
|
1001
1003
|
res.end(JSON.stringify({ error: "message is required" }));
|
|
1002
1004
|
return;
|
|
1003
1005
|
}
|
|
1004
|
-
|
|
1005
|
-
dbPath,
|
|
1006
|
-
`INSERT INTO harness_messages (id, "from", "to", type, message, severity)
|
|
1007
|
-
VALUES (${q(id)}, ${q(from)}, ${q(to)}, ${q(type)}, ${q(message)}, ${q(severity)});`
|
|
1008
|
-
);
|
|
1006
|
+
insertStmt.run(id, from, to, type, message, severity);
|
|
1009
1007
|
res.writeHead(200, { "content-type": "application/json" });
|
|
1010
1008
|
res.end(JSON.stringify({ data: { id } }));
|
|
1011
1009
|
} catch (err) {
|
|
@@ -1031,6 +1029,7 @@ async function runChat(args) {
|
|
|
1031
1029
|
console.log();
|
|
1032
1030
|
console.log(c4.dim(" bye \u{1F44B}"));
|
|
1033
1031
|
server.close();
|
|
1032
|
+
db.close();
|
|
1034
1033
|
process.exit(0);
|
|
1035
1034
|
});
|
|
1036
1035
|
}
|
|
@@ -1081,11 +1080,10 @@ function portIsFree(port) {
|
|
|
1081
1080
|
}
|
|
1082
1081
|
function openBrowser(url) {
|
|
1083
1082
|
const platform = process.platform;
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
}
|
|
1083
|
+
const child = platform === "darwin" ? spawn("open", [url], { detached: true, stdio: "ignore" }) : platform === "win32" ? spawn("cmd", ["/c", "start", '""', url], { detached: true, stdio: "ignore" }) : spawn("xdg-open", [url], { detached: true, stdio: "ignore" });
|
|
1084
|
+
child.on("error", () => {
|
|
1085
|
+
});
|
|
1086
|
+
child.unref();
|
|
1089
1087
|
}
|
|
1090
1088
|
function readBody(req) {
|
|
1091
1089
|
return new Promise((resolve7, reject) => {
|
|
@@ -1095,18 +1093,15 @@ function readBody(req) {
|
|
|
1095
1093
|
req.on("error", reject);
|
|
1096
1094
|
});
|
|
1097
1095
|
}
|
|
1098
|
-
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
});
|
|
1108
|
-
if (!stdout.trim()) return [];
|
|
1109
|
-
const raw = JSON.parse(stdout);
|
|
1096
|
+
function readMessages(db, days) {
|
|
1097
|
+
const safeDays = Math.max(1, days | 0);
|
|
1098
|
+
const stmt = db.prepare(
|
|
1099
|
+
`SELECT id, timestamp, "from" AS sender, "to" AS recipient, type, message, severity
|
|
1100
|
+
FROM harness_messages
|
|
1101
|
+
WHERE timestamp >= datetime('now', '-' || ? || ' day')
|
|
1102
|
+
ORDER BY timestamp ASC`
|
|
1103
|
+
);
|
|
1104
|
+
const raw = stmt.all(safeDays);
|
|
1110
1105
|
return raw.map((r) => ({
|
|
1111
1106
|
id: r.id,
|
|
1112
1107
|
timestamp: r.timestamp,
|
|
@@ -1117,12 +1112,6 @@ async function readMessages(dbPath, days) {
|
|
|
1117
1112
|
severity: r.severity
|
|
1118
1113
|
}));
|
|
1119
1114
|
}
|
|
1120
|
-
async function runSql(dbPath, sql) {
|
|
1121
|
-
await execFileP("sqlite3", [dbPath, sql], { maxBuffer: 1024 * 1024 });
|
|
1122
|
-
}
|
|
1123
|
-
function q(value) {
|
|
1124
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
1125
|
-
}
|
|
1126
1115
|
var SCHEMA_SQL = `
|
|
1127
1116
|
CREATE TABLE IF NOT EXISTS harness_messages (
|
|
1128
1117
|
id TEXT PRIMARY KEY,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harness-bujang",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
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",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"prepublishOnly": "npm run build"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
+
"@types/better-sqlite3": "^7.6.10",
|
|
50
51
|
"@types/node": "^20.11.0",
|
|
51
52
|
"tsup": "^8.3.0",
|
|
52
53
|
"tsx": "^4.19.0",
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"node": ">=20"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"@inquirer/prompts": "^8.4.2"
|
|
60
|
+
"@inquirer/prompts": "^8.4.2",
|
|
61
|
+
"better-sqlite3": "^11.7.0"
|
|
60
62
|
}
|
|
61
63
|
}
|