hanoman 0.1.47 → 0.1.50
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 +43 -1
- package/dist/build-info.json +3 -3
- package/dist/cli.js +85 -37
- package/dist/server.js +208 -44
- package/package.json +1 -1
- package/prisma/migrations/20260819130000_session_history_ended_reason/migration.sql +27 -0
- package/prisma/schema.prisma +7 -0
- package/web/assets/{index-Cnd5rKXp.js → index-Ddz2nble.js} +1543 -1552
- package/web/index.html +1 -1
package/README.md
CHANGED
|
@@ -84,13 +84,55 @@ Sesudah `hanoman update`, instance yang berjalan perlu di-restart (mis. `systemc
|
|
|
84
84
|
|
|
85
85
|
| Env | Default | Untuk apa |
|
|
86
86
|
|---|---|---|
|
|
87
|
-
| `HANOMAN_HOME` | `~/.hanoman` |
|
|
87
|
+
| `HANOMAN_HOME` | `~/.hanoman` | akar seluruh state hanoman — lihat [Isi `$HANOMAN_HOME`](#isi-hanoman_home) |
|
|
88
88
|
| `HANOMAN_DATABASE_URL` | — | berkas DB khusus hanoman; hanya URL `file:` (nilai lain **melempar**) |
|
|
89
89
|
| `DATABASE_URL` | `file:$HANOMAN_HOME/hanoman.db` | dipakai bila ber-`file:`; nilai lain **diabaikan** dengan peringatan |
|
|
90
|
+
| `HANOMAN_TRANSCRIPT_DIR` | `$HANOMAN_HOME/transcripts` | transkrip sesi yang sudah ditutup |
|
|
91
|
+
| `HANOMAN_UPLOAD_DIR` | `$HANOMAN_HOME/uploads` | lampiran tiket & lampiran gambar sesi terminal |
|
|
92
|
+
| `HANOMAN_SSH_KEY_DIR` | `$HANOMAN_HOME` | keypair identitas hanoman untuk VPS |
|
|
90
93
|
| `PORT` / `HOST` | `8787` / `127.0.0.1` | alamat bind |
|
|
91
94
|
| `HANOMAN_CLAUDE_BIN` / `HANOMAN_CODEX_BIN` | `claude` / `codex` | biner agen |
|
|
92
95
|
| `HANOMAN_TMUX_SOCKET` | `hanoman` | socket tmux terpisah dari milikmu |
|
|
93
96
|
|
|
97
|
+
<a id="isi-hanoman_home"></a>
|
|
98
|
+
|
|
99
|
+
## Isi `$HANOMAN_HOME` — satu batas backup/restore
|
|
100
|
+
|
|
101
|
+
Tanpa override, **seluruh** state hanoman hidup di bawah satu direktori. Itulah batas yang harus
|
|
102
|
+
disalin: memindahkan DB saja meninggalkan metadata yang menunjuk byte yang tak ada (SPEC-846).
|
|
103
|
+
|
|
104
|
+
| Path | Isi | Hilang berarti |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `hanoman.db` (+ `-wal`/`-shm`) | seluruh state aplikasi | semuanya |
|
|
107
|
+
| `secret.key` | kunci AES untuk RuntimeConfig & webhook secret | credential terenkripsi tak bisa dibuka |
|
|
108
|
+
| `id_ed25519` + `.pub` | identitas SSH hanoman ke VPS | akses VPS mati; `authorized_keys` tak lagi cocok |
|
|
109
|
+
| `transcripts/` | transkrip sesi yang ditutup | `hasTranscript` benar, isinya tak terbaca |
|
|
110
|
+
| `uploads/` | lampiran tiket, byte source-map lama | lampiran 404 walau metadata utuh |
|
|
111
|
+
| `uploads/terminal/<sessionId>/` | lampiran gambar sesi terminal | path di prompt agen menunjuk berkas hilang |
|
|
112
|
+
| `setup.token` | token bootstrap admin pertama (one-time, 15 menit) | hanya relevan sebelum admin pertama |
|
|
113
|
+
| `agent-token` | agent token yang dibaca `hanoman mcp` | klien MCP lokal kehilangan autentikasi |
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Backup — SQLite disalin konsisten, sisanya berkas biasa.
|
|
117
|
+
sqlite3 "$HANOMAN_HOME/hanoman.db" ".backup '/backup/hanoman.db'"
|
|
118
|
+
tar -C "$HANOMAN_HOME" -czf /backup/hanoman-files.tgz \
|
|
119
|
+
secret.key id_ed25519 id_ed25519.pub transcripts uploads
|
|
120
|
+
|
|
121
|
+
# Restore di host lain — umask dulu, isinya memuat kunci privat.
|
|
122
|
+
umask 077
|
|
123
|
+
install -d -m 0700 "$HANOMAN_HOME"
|
|
124
|
+
cp /backup/hanoman.db "$HANOMAN_HOME/hanoman.db"
|
|
125
|
+
tar -C "$HANOMAN_HOME" -xzf /backup/hanoman-files.tgz
|
|
126
|
+
hanoman doctor # memverifikasi tiap path data efektif + izin tulisnya
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`setup.token` dan `agent-token` sengaja **tidak** ikut: yang pertama one-time dan lahir ulang
|
|
130
|
+
sendiri bila DB belum punya user, yang kedua sebaiknya diterbitkan ulang di host baru.
|
|
131
|
+
|
|
132
|
+
Mengeset `HANOMAN_TRANSCRIPT_DIR`, `HANOMAN_UPLOAD_DIR`, atau `HANOMAN_SSH_KEY_DIR` memindahkan
|
|
133
|
+
bagian itu ke luar batas ini — sah, tapi backup-nya menjadi tanggung jawabmu. `hanoman doctor`
|
|
134
|
+
mencetak path efektifnya supaya tak perlu ditebak.
|
|
135
|
+
|
|
94
136
|
## Bind & TLS
|
|
95
137
|
|
|
96
138
|
Default `127.0.0.1:8787`. hanoman punya auth, tapi cookie sesinya `Secure` — set
|
package/dist/build-info.json
CHANGED
package/dist/cli.js
CHANGED
|
@@ -5064,6 +5064,10 @@ var init_dto = __esm({
|
|
|
5064
5064
|
cwd: external_exports.string(),
|
|
5065
5065
|
startedAt: external_exports.string(),
|
|
5066
5066
|
endedAt: external_exports.string().nullable(),
|
|
5067
|
+
// SPEC-844 · ADR-0125 · `string` longgar, bukan enum: baris lama null dan nilai asing dari
|
|
5068
|
+
// instance lebih baru tak boleh melempar di boundary — `sessionOutcome()` yang menafsirkannya.
|
|
5069
|
+
endedReason: external_exports.string().nullable(),
|
|
5070
|
+
reconciledAt: external_exports.string().nullable(),
|
|
5067
5071
|
exitCode: external_exports.number().nullable(),
|
|
5068
5072
|
transcriptBytes: external_exports.number().nullable()
|
|
5069
5073
|
});
|
|
@@ -5918,6 +5922,13 @@ var init_session_kind = __esm({
|
|
|
5918
5922
|
}
|
|
5919
5923
|
});
|
|
5920
5924
|
|
|
5925
|
+
// ../shared/src/session-end.ts
|
|
5926
|
+
var init_session_end = __esm({
|
|
5927
|
+
"../shared/src/session-end.ts"() {
|
|
5928
|
+
"use strict";
|
|
5929
|
+
}
|
|
5930
|
+
});
|
|
5931
|
+
|
|
5921
5932
|
// ../shared/src/config.ts
|
|
5922
5933
|
var zHanomanConfig;
|
|
5923
5934
|
var init_config = __esm({
|
|
@@ -6291,6 +6302,8 @@ var init_webhook = __esm({
|
|
|
6291
6302
|
"branch",
|
|
6292
6303
|
"startedAt",
|
|
6293
6304
|
"endedAt",
|
|
6305
|
+
"endedReason",
|
|
6306
|
+
"reconciledAt",
|
|
6294
6307
|
"exitCode"
|
|
6295
6308
|
],
|
|
6296
6309
|
projectIdField: "projectId",
|
|
@@ -6299,9 +6312,9 @@ var init_webhook = __esm({
|
|
|
6299
6312
|
},
|
|
6300
6313
|
derived: [{
|
|
6301
6314
|
type: "session.ended",
|
|
6302
|
-
label: "Sesi selesai atau
|
|
6315
|
+
label: "Sesi selesai, gagal, atau terputus",
|
|
6303
6316
|
changed: ["endedAt"],
|
|
6304
|
-
when:
|
|
6317
|
+
when: 'Sesi berakhir dan endedAt terisi. endedReason memberi tahu CARANYA: "closed" = hanoman menutupnya, jadi exitCode berlaku (null = agen masih hidup saat ditutup, 0 = keluar bersih, selain itu gagal); "reconciled" = panenya sudah lenyap saat hanoman menyala lagi (reboot, kill-server, host mati) sehingga hasilnya TAK DIKETAHUI, exitCode selalu null, dan reconciledAt menyebut kapan hanoman menemukannya \u2014 endedAt di kasus itu batas BAWAH, bukan waktu berakhir sebenarnya. null = baris lahir sebelum SPEC-844.'
|
|
6305
6318
|
}],
|
|
6306
6319
|
sample: {
|
|
6307
6320
|
id: "6f0c1c1e-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
|
|
@@ -6317,6 +6330,8 @@ var init_webhook = __esm({
|
|
|
6317
6330
|
branch: "hanoman/spec-481",
|
|
6318
6331
|
startedAt: "2026-08-01T02:12:31.000Z",
|
|
6319
6332
|
endedAt: "2026-08-01T09:44:02.000Z",
|
|
6333
|
+
endedReason: "closed",
|
|
6334
|
+
reconciledAt: null,
|
|
6320
6335
|
exitCode: 0
|
|
6321
6336
|
}
|
|
6322
6337
|
},
|
|
@@ -7251,6 +7266,7 @@ var init_src = __esm({
|
|
|
7251
7266
|
init_portal();
|
|
7252
7267
|
init_prd_status();
|
|
7253
7268
|
init_session_kind();
|
|
7269
|
+
init_session_end();
|
|
7254
7270
|
init_config();
|
|
7255
7271
|
init_config_registry();
|
|
7256
7272
|
init_semver();
|
|
@@ -7443,6 +7459,16 @@ function resolveHome(env = process.env, home = homedir()) {
|
|
|
7443
7459
|
const v = env.HANOMAN_HOME?.trim();
|
|
7444
7460
|
return v ? v : join(home, ".hanoman");
|
|
7445
7461
|
}
|
|
7462
|
+
function resolveDataDirs(env = process.env, home = homedir()) {
|
|
7463
|
+
const root = resolveHome(env, home);
|
|
7464
|
+
const dir = (key, name) => env[key]?.trim() || join(root, name);
|
|
7465
|
+
return {
|
|
7466
|
+
home: root,
|
|
7467
|
+
transcripts: dir("HANOMAN_TRANSCRIPT_DIR", "transcripts"),
|
|
7468
|
+
uploads: dir("HANOMAN_UPLOAD_DIR", "uploads"),
|
|
7469
|
+
sshKeys: env.HANOMAN_SSH_KEY_DIR?.trim() || root
|
|
7470
|
+
};
|
|
7471
|
+
}
|
|
7446
7472
|
function schemeOf(raw) {
|
|
7447
7473
|
return raw.split("://")[0] ?? "?";
|
|
7448
7474
|
}
|
|
@@ -7701,10 +7727,10 @@ function ensureSpawnHelpersExecutable(paths2, ops) {
|
|
|
7701
7727
|
}
|
|
7702
7728
|
return fixed;
|
|
7703
7729
|
}
|
|
7704
|
-
function repairSpawnHelper(
|
|
7730
|
+
function repairSpawnHelper(resolve5, notify) {
|
|
7705
7731
|
let ptyDir;
|
|
7706
7732
|
try {
|
|
7707
|
-
ptyDir = dirname3(
|
|
7733
|
+
ptyDir = dirname3(resolve5("node-pty/package.json"));
|
|
7708
7734
|
} catch {
|
|
7709
7735
|
return [];
|
|
7710
7736
|
}
|
|
@@ -8106,7 +8132,7 @@ __export(doctor_exports, {
|
|
|
8106
8132
|
});
|
|
8107
8133
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
8108
8134
|
import { accessSync, constants, existsSync as existsSync4 } from "node:fs";
|
|
8109
|
-
import { dirname as dirname5 } from "node:path";
|
|
8135
|
+
import { dirname as dirname5, resolve as resolve4 } from "node:path";
|
|
8110
8136
|
function doctorReport(p) {
|
|
8111
8137
|
const major = Number(/^v?(\d+)/.exec(p.node)?.[1] ?? 0);
|
|
8112
8138
|
const rows = [
|
|
@@ -8121,7 +8147,13 @@ function doctorReport(p) {
|
|
|
8121
8147
|
text: p.gh ? `gh ${p.gh}` : "gh \u2014 tak ada (tarik issue akan lewat HTTP + GITHUB_TOKEN)",
|
|
8122
8148
|
fatal: false
|
|
8123
8149
|
},
|
|
8124
|
-
|
|
8150
|
+
// Direktori turunan lahir saat dipakai, jadi izin tulis yang belum ada di situ adalah
|
|
8151
|
+
// peringatan — bukan alasan menyatakan hanoman tak bisa menjalankan sesi. Home tetap fatal.
|
|
8152
|
+
...p.dirs.map((d) => ({
|
|
8153
|
+
mark: d.writable ? "\u2713" : d.fatal ? "\u2717" : "!",
|
|
8154
|
+
text: `${d.label} ${d.path}${d.writable ? "" : " \u2014 TAK bisa ditulis"}`,
|
|
8155
|
+
fatal: d.fatal && !d.writable
|
|
8156
|
+
})),
|
|
8125
8157
|
{ mark: p.web ? "\u2713" : "!", text: p.web ? "aset dashboard ada" : "aset dashboard tak ada \u2014 API jalan, dashboard tidak", fatal: false },
|
|
8126
8158
|
{ mark: "\xB7", text: `db ${p.db}`, fatal: false },
|
|
8127
8159
|
{
|
|
@@ -8144,6 +8176,21 @@ function doctorReport(p) {
|
|
|
8144
8176
|
}
|
|
8145
8177
|
return { lines: rows.map((r) => ` ${r.mark} ${r.text}`), ok: !rows.some((r) => r.fatal) };
|
|
8146
8178
|
}
|
|
8179
|
+
function writable(path) {
|
|
8180
|
+
for (let p = resolve4(path); ; ) {
|
|
8181
|
+
if (existsSync4(p)) {
|
|
8182
|
+
try {
|
|
8183
|
+
accessSync(p, constants.W_OK);
|
|
8184
|
+
return true;
|
|
8185
|
+
} catch {
|
|
8186
|
+
return false;
|
|
8187
|
+
}
|
|
8188
|
+
}
|
|
8189
|
+
const up = dirname5(p);
|
|
8190
|
+
if (up === p) return false;
|
|
8191
|
+
p = up;
|
|
8192
|
+
}
|
|
8193
|
+
}
|
|
8147
8194
|
function version(bin, args) {
|
|
8148
8195
|
try {
|
|
8149
8196
|
return execFileSync3(bin, args, { encoding: "utf8", timeout: 1e4, stdio: ["ignore", "pipe", "ignore"] }).trim().split("\n")[0] ?? null;
|
|
@@ -8162,13 +8209,13 @@ async function doctor(_argv, ctx) {
|
|
|
8162
8209
|
`);
|
|
8163
8210
|
return 1;
|
|
8164
8211
|
}
|
|
8165
|
-
const
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8212
|
+
const d = resolveDataDirs(ctx.env);
|
|
8213
|
+
const dirs = [
|
|
8214
|
+
{ label: "data dir", path: d.home, writable: writable(d.home), fatal: true },
|
|
8215
|
+
{ label: "transkrip", path: d.transcripts, writable: writable(d.transcripts), fatal: false },
|
|
8216
|
+
{ label: "upload", path: d.uploads, writable: writable(d.uploads), fatal: false },
|
|
8217
|
+
{ label: "key SSH", path: d.sshKeys, writable: writable(d.sshKeys), fatal: false }
|
|
8218
|
+
];
|
|
8172
8219
|
const claude = version(ctx.env.HANOMAN_CLAUDE_BIN ?? "claude", ["--version"]);
|
|
8173
8220
|
const codex = version(ctx.env.HANOMAN_CODEX_BIN ?? "codex", ["--version"]);
|
|
8174
8221
|
const method = METHODS[DEFAULT_METHOD];
|
|
@@ -8198,7 +8245,7 @@ async function doctor(_argv, ctx) {
|
|
|
8198
8245
|
claude,
|
|
8199
8246
|
codex,
|
|
8200
8247
|
gh: version(ctx.env.HANOMAN_GH_BIN ?? "gh", ["--version"]),
|
|
8201
|
-
|
|
8248
|
+
dirs,
|
|
8202
8249
|
web: layout.web !== null,
|
|
8203
8250
|
db,
|
|
8204
8251
|
methods,
|
|
@@ -17588,14 +17635,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
17588
17635
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
17589
17636
|
}
|
|
17590
17637
|
function sleep(ms, signal) {
|
|
17591
|
-
return new Promise((
|
|
17638
|
+
return new Promise((resolve5, reject) => {
|
|
17592
17639
|
if (signal?.aborted) {
|
|
17593
17640
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
17594
17641
|
return;
|
|
17595
17642
|
}
|
|
17596
17643
|
const timer = setTimeout(() => {
|
|
17597
17644
|
signal?.removeEventListener("abort", onAbort);
|
|
17598
|
-
|
|
17645
|
+
resolve5();
|
|
17599
17646
|
}, ms);
|
|
17600
17647
|
const onAbort = () => {
|
|
17601
17648
|
clearTimeout(timer);
|
|
@@ -19406,7 +19453,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
19406
19453
|
const flowStartedAt = Date.now();
|
|
19407
19454
|
let onAbort;
|
|
19408
19455
|
let cleanupMessageId;
|
|
19409
|
-
return new Promise((
|
|
19456
|
+
return new Promise((resolve5, reject) => {
|
|
19410
19457
|
const earlyReject = (error2) => {
|
|
19411
19458
|
reject(error2);
|
|
19412
19459
|
};
|
|
@@ -19474,7 +19521,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
19474
19521
|
}
|
|
19475
19522
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
19476
19523
|
if (decoded.kind === "input_required") {
|
|
19477
|
-
if (options?.allowInputRequired === true) return
|
|
19524
|
+
if (options?.allowInputRequired === true) return resolve5(manualInputRequiredValue(decoded));
|
|
19478
19525
|
const flow = {
|
|
19479
19526
|
codec,
|
|
19480
19527
|
request,
|
|
@@ -19486,11 +19533,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
19486
19533
|
params
|
|
19487
19534
|
}, resultSchema, legOptions)
|
|
19488
19535
|
};
|
|
19489
|
-
return
|
|
19536
|
+
return resolve5(this._resolveNonCompleteResult(decoded, flow));
|
|
19490
19537
|
}
|
|
19491
19538
|
const result = decoded.result;
|
|
19492
19539
|
validateStandardSchema(resultSchema, result).then((parseResult) => {
|
|
19493
|
-
if (parseResult.success)
|
|
19540
|
+
if (parseResult.success) resolve5(parseResult.data);
|
|
19494
19541
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
19495
19542
|
}, reject);
|
|
19496
19543
|
});
|
|
@@ -22306,7 +22353,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
22306
22353
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
22307
22354
|
const schOrFunc = root.refs[ref];
|
|
22308
22355
|
if (schOrFunc) return schOrFunc;
|
|
22309
|
-
let _sch =
|
|
22356
|
+
let _sch = resolve5.call(this, root, ref);
|
|
22310
22357
|
if (_sch === void 0) {
|
|
22311
22358
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
22312
22359
|
const { schemaId } = this.opts;
|
|
@@ -22332,7 +22379,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
22332
22379
|
function sameSchemaEnv(s1, s2) {
|
|
22333
22380
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
22334
22381
|
}
|
|
22335
|
-
function
|
|
22382
|
+
function resolve5(root, ref) {
|
|
22336
22383
|
let sch;
|
|
22337
22384
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
22338
22385
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -22782,7 +22829,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
22782
22829
|
else if (typeof uri === "object") uri = parse4(serialize(uri, options), options);
|
|
22783
22830
|
return uri;
|
|
22784
22831
|
}
|
|
22785
|
-
function
|
|
22832
|
+
function resolve5(baseURI, relativeURI, options) {
|
|
22786
22833
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
22787
22834
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
22788
22835
|
schemelessOptions.skipEscape = true;
|
|
@@ -22956,7 +23003,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
22956
23003
|
const fastUri = {
|
|
22957
23004
|
SCHEMES,
|
|
22958
23005
|
normalize,
|
|
22959
|
-
resolve:
|
|
23006
|
+
resolve: resolve5,
|
|
22960
23007
|
resolveComponent,
|
|
22961
23008
|
equal,
|
|
22962
23009
|
serialize,
|
|
@@ -28648,7 +28695,7 @@ var init_stdio = __esm({
|
|
|
28648
28695
|
}
|
|
28649
28696
|
send(message) {
|
|
28650
28697
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
28651
|
-
return new Promise((
|
|
28698
|
+
return new Promise((resolve5, reject) => {
|
|
28652
28699
|
const json = serializeMessage(message);
|
|
28653
28700
|
let settled = false;
|
|
28654
28701
|
const onError = (error2) => {
|
|
@@ -28663,14 +28710,14 @@ var init_stdio = __esm({
|
|
|
28663
28710
|
settled = true;
|
|
28664
28711
|
this._stdout.off("error", onError);
|
|
28665
28712
|
this._stdout.off("drain", onDrain);
|
|
28666
|
-
|
|
28713
|
+
resolve5();
|
|
28667
28714
|
};
|
|
28668
28715
|
this._stdout.once("error", onError);
|
|
28669
28716
|
if (this._stdout.write(json)) {
|
|
28670
28717
|
if (settled) return;
|
|
28671
28718
|
settled = true;
|
|
28672
28719
|
this._stdout.off("error", onError);
|
|
28673
|
-
|
|
28720
|
+
resolve5();
|
|
28674
28721
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
28675
28722
|
});
|
|
28676
28723
|
}
|
|
@@ -28724,14 +28771,14 @@ var init_stdio = __esm({
|
|
|
28724
28771
|
*/
|
|
28725
28772
|
async whenRequestsAnswered(timeoutMs) {
|
|
28726
28773
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
28727
|
-
return await new Promise((
|
|
28774
|
+
return await new Promise((resolve5) => {
|
|
28728
28775
|
const waiter = () => {
|
|
28729
28776
|
clearTimeout(timer);
|
|
28730
|
-
|
|
28777
|
+
resolve5(true);
|
|
28731
28778
|
};
|
|
28732
28779
|
const timer = setTimeout(() => {
|
|
28733
28780
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
28734
|
-
|
|
28781
|
+
resolve5(false);
|
|
28735
28782
|
}, timeoutMs);
|
|
28736
28783
|
this._drainWaiters.push(waiter);
|
|
28737
28784
|
});
|
|
@@ -29008,10 +29055,10 @@ var init_server = __esm({
|
|
|
29008
29055
|
// src/commands/mcp.ts
|
|
29009
29056
|
var mcp_exports = {};
|
|
29010
29057
|
__export(mcp_exports, {
|
|
29058
|
+
agentTokenPath: () => agentTokenPath,
|
|
29011
29059
|
default: () => mcp
|
|
29012
29060
|
});
|
|
29013
29061
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
29014
|
-
import { homedir as homedir3 } from "node:os";
|
|
29015
29062
|
import { join as join6 } from "node:path";
|
|
29016
29063
|
async function mcp(argv, ctx) {
|
|
29017
29064
|
const cfg = resolveMcpConfig(argv, ctx.env, () => tokenFile(ctx.env));
|
|
@@ -29026,26 +29073,27 @@ async function mcp(argv, ctx) {
|
|
|
29026
29073
|
await handle.close();
|
|
29027
29074
|
return 0;
|
|
29028
29075
|
}
|
|
29029
|
-
await new Promise((
|
|
29030
|
-
process.stdin.once("close",
|
|
29031
|
-
process.stdin.once("end",
|
|
29076
|
+
await new Promise((resolve5) => {
|
|
29077
|
+
process.stdin.once("close", resolve5);
|
|
29078
|
+
process.stdin.once("end", resolve5);
|
|
29032
29079
|
});
|
|
29033
29080
|
return 0;
|
|
29034
29081
|
}
|
|
29035
|
-
var tokenFile;
|
|
29082
|
+
var agentTokenPath, tokenFile;
|
|
29036
29083
|
var init_mcp2 = __esm({
|
|
29037
29084
|
"src/commands/mcp.ts"() {
|
|
29038
29085
|
"use strict";
|
|
29086
|
+
init_src2();
|
|
29039
29087
|
init_stdio();
|
|
29040
29088
|
init_router();
|
|
29041
29089
|
init_config2();
|
|
29042
29090
|
init_client();
|
|
29043
29091
|
init_server();
|
|
29044
29092
|
init_redact();
|
|
29093
|
+
agentTokenPath = (env) => join6(resolveHome(env), "agent-token");
|
|
29045
29094
|
tokenFile = (env) => {
|
|
29046
|
-
const home = env.HANOMAN_HOME ?? join6(homedir3(), ".hanoman");
|
|
29047
29095
|
try {
|
|
29048
|
-
return readFileSync2(
|
|
29096
|
+
return readFileSync2(agentTokenPath(env), "utf8");
|
|
29049
29097
|
} catch {
|
|
29050
29098
|
return null;
|
|
29051
29099
|
}
|