hanoman 0.2.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/dist/build-info.json +3 -3
- package/dist/cli.js +21 -4
- package/dist/server.js +86 -14
- package/package.json +1 -1
- package/web/assets/{index-BpV7m-Kb.js → index-CRbdeYxO.js} +1539 -1539
- package/web/index.html +1 -1
package/dist/build-info.json
CHANGED
package/dist/cli.js
CHANGED
|
@@ -6060,7 +6060,15 @@ var init_api = __esm({
|
|
|
6060
6060
|
breakdown: (id, prd) => `${API}/projects/${id}/breakdown?prd=${encodeURIComponent(prd)}`,
|
|
6061
6061
|
specsBatch: `${API}/specs/batch`,
|
|
6062
6062
|
// SPEC-182 · IDE Visual
|
|
6063
|
-
|
|
6063
|
+
// `hidden` menyertakan entri .gitignore; `under` membuka satu tingkat isi sebuah direktori.
|
|
6064
|
+
ideTree: (id, ref = "", opts) => {
|
|
6065
|
+
const q = new URLSearchParams();
|
|
6066
|
+
if (ref) q.set("ref", ref);
|
|
6067
|
+
if (opts?.hidden) q.set("hidden", "1");
|
|
6068
|
+
if (opts?.under) q.set("under", opts.under);
|
|
6069
|
+
const s2 = q.toString();
|
|
6070
|
+
return `${API}/projects/${id}/tree${s2 ? `?${s2}` : ""}`;
|
|
6071
|
+
},
|
|
6064
6072
|
ideFile: (id, path, ref = "") => `${API}/projects/${id}/file${path ? `?path=${encodeURIComponent(path)}${ref ? `&ref=${encodeURIComponent(ref)}` : ""}` : ""}`,
|
|
6065
6073
|
ideGraph: (id, limit = 200, opts) => {
|
|
6066
6074
|
const p3 = new URLSearchParams({ limit: String(limit) });
|
|
@@ -8205,16 +8213,25 @@ var init_ide = __esm({
|
|
|
8205
8213
|
{
|
|
8206
8214
|
name: "hanoman_ide_tree",
|
|
8207
8215
|
title: "Pohon berkas repo project",
|
|
8208
|
-
description: "Daftar berkas repo project pada sebuah ref. Tanpa `ref` ia membaca working tree apa adanya, termasuk perubahan yang belum di-commit.",
|
|
8216
|
+
description: "Daftar berkas repo project pada sebuah ref. Tanpa `ref` ia membaca working tree apa adanya, termasuk perubahan yang belum di-commit. `hidden` ikut menyertakan yang .gitignore sembunyikan \u2014 direktori yang seluruhnya diabaikan (mis. `node_modules`) diruntuhkan jadi satu entri di `dirs`; buka isinya dengan `under`, satu tingkat per panggilan.",
|
|
8209
8217
|
inputSchema: obj({
|
|
8210
|
-
properties: {
|
|
8218
|
+
properties: {
|
|
8219
|
+
project: PROJECT2,
|
|
8220
|
+
ref: str("Ref git (branch/tag/sha). Kosongkan untuk working tree."),
|
|
8221
|
+
hidden: bool("Sertakan berkas & direktori yang diabaikan .gitignore. Tak berlaku bersama `ref`."),
|
|
8222
|
+
under: str("Jalur direktori; balasannya berisi SATU tingkat isinya. Dipakai untuk membuka direktori terabaikan yang diruntuhkan.")
|
|
8223
|
+
},
|
|
8211
8224
|
required: ["project"]
|
|
8212
8225
|
}),
|
|
8213
8226
|
mode: "read",
|
|
8214
8227
|
capability: "ide:read",
|
|
8215
8228
|
samplePath: "/projects/hanoman/tree",
|
|
8216
8229
|
sampleMethod: "GET",
|
|
8217
|
-
build: (a) => ({
|
|
8230
|
+
build: (a) => ({
|
|
8231
|
+
method: "GET",
|
|
8232
|
+
path: `${p(a.project)}/tree`,
|
|
8233
|
+
query: query({ ref: s(a.ref), hidden: a.hidden ? "1" : "", under: s(a.under) })
|
|
8234
|
+
}),
|
|
8218
8235
|
shape: (raw) => raw
|
|
8219
8236
|
},
|
|
8220
8237
|
{
|
package/dist/server.js
CHANGED
|
@@ -6520,7 +6520,15 @@ var init_api = __esm({
|
|
|
6520
6520
|
breakdown: (id, prd) => `${API}/projects/${id}/breakdown?prd=${encodeURIComponent(prd)}`,
|
|
6521
6521
|
specsBatch: `${API}/specs/batch`,
|
|
6522
6522
|
// SPEC-182 · IDE Visual
|
|
6523
|
-
|
|
6523
|
+
// `hidden` menyertakan entri .gitignore; `under` membuka satu tingkat isi sebuah direktori.
|
|
6524
|
+
ideTree: (id, ref = "", opts) => {
|
|
6525
|
+
const q = new URLSearchParams();
|
|
6526
|
+
if (ref) q.set("ref", ref);
|
|
6527
|
+
if (opts?.hidden) q.set("hidden", "1");
|
|
6528
|
+
if (opts?.under) q.set("under", opts.under);
|
|
6529
|
+
const s2 = q.toString();
|
|
6530
|
+
return `${API}/projects/${id}/tree${s2 ? `?${s2}` : ""}`;
|
|
6531
|
+
},
|
|
6524
6532
|
ideFile: (id, path, ref = "") => `${API}/projects/${id}/file${path ? `?path=${encodeURIComponent(path)}${ref ? `&ref=${encodeURIComponent(ref)}` : ""}` : ""}`,
|
|
6525
6533
|
ideGraph: (id, limit = 200, opts) => {
|
|
6526
6534
|
const p3 = new URLSearchParams({ limit: String(limit) });
|
|
@@ -8815,16 +8823,25 @@ var init_ide = __esm({
|
|
|
8815
8823
|
{
|
|
8816
8824
|
name: "hanoman_ide_tree",
|
|
8817
8825
|
title: "Pohon berkas repo project",
|
|
8818
|
-
description: "Daftar berkas repo project pada sebuah ref. Tanpa `ref` ia membaca working tree apa adanya, termasuk perubahan yang belum di-commit.",
|
|
8826
|
+
description: "Daftar berkas repo project pada sebuah ref. Tanpa `ref` ia membaca working tree apa adanya, termasuk perubahan yang belum di-commit. `hidden` ikut menyertakan yang .gitignore sembunyikan \u2014 direktori yang seluruhnya diabaikan (mis. `node_modules`) diruntuhkan jadi satu entri di `dirs`; buka isinya dengan `under`, satu tingkat per panggilan.",
|
|
8819
8827
|
inputSchema: obj({
|
|
8820
|
-
properties: {
|
|
8828
|
+
properties: {
|
|
8829
|
+
project: PROJECT2,
|
|
8830
|
+
ref: str("Ref git (branch/tag/sha). Kosongkan untuk working tree."),
|
|
8831
|
+
hidden: bool("Sertakan berkas & direktori yang diabaikan .gitignore. Tak berlaku bersama `ref`."),
|
|
8832
|
+
under: str("Jalur direktori; balasannya berisi SATU tingkat isinya. Dipakai untuk membuka direktori terabaikan yang diruntuhkan.")
|
|
8833
|
+
},
|
|
8821
8834
|
required: ["project"]
|
|
8822
8835
|
}),
|
|
8823
8836
|
mode: "read",
|
|
8824
8837
|
capability: "ide:read",
|
|
8825
8838
|
samplePath: "/projects/hanoman/tree",
|
|
8826
8839
|
sampleMethod: "GET",
|
|
8827
|
-
build: (a) => ({
|
|
8840
|
+
build: (a) => ({
|
|
8841
|
+
method: "GET",
|
|
8842
|
+
path: `${p(a.project)}/tree`,
|
|
8843
|
+
query: query({ ref: s(a.ref), hidden: a.hidden ? "1" : "", under: s(a.under) })
|
|
8844
|
+
}),
|
|
8828
8845
|
shape: (raw) => raw
|
|
8829
8846
|
},
|
|
8830
8847
|
{
|
|
@@ -26508,6 +26525,7 @@ function ownsWorktree(repoDir, cwd) {
|
|
|
26508
26525
|
import { execFile as execFile7 } from "node:child_process";
|
|
26509
26526
|
import { promisify as promisify6 } from "node:util";
|
|
26510
26527
|
import { existsSync as existsSync7 } from "node:fs";
|
|
26528
|
+
import { readdir as readdir2 } from "node:fs/promises";
|
|
26511
26529
|
import { resolve as resolve14 } from "node:path";
|
|
26512
26530
|
var exec6 = promisify6(execFile7);
|
|
26513
26531
|
var GIT4 = { maxBuffer: 1 << 24 };
|
|
@@ -26527,6 +26545,43 @@ async function listRepoTree(repoDir, ref = "") {
|
|
|
26527
26545
|
return [];
|
|
26528
26546
|
}
|
|
26529
26547
|
}
|
|
26548
|
+
async function listIgnoredEntries(repoDir) {
|
|
26549
|
+
const empty = { files: [], dirs: [] };
|
|
26550
|
+
if (!repoDir || !existsSync7(repoDir)) return empty;
|
|
26551
|
+
try {
|
|
26552
|
+
const { stdout } = await exec6(
|
|
26553
|
+
"git",
|
|
26554
|
+
["ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "--no-empty-directory", "-z"],
|
|
26555
|
+
{ cwd: repoDir, ...GIT4 }
|
|
26556
|
+
);
|
|
26557
|
+
const files = [], dirs = [];
|
|
26558
|
+
for (const e of new Set(splitZ2(stdout))) {
|
|
26559
|
+
if (e.endsWith("/")) dirs.push(e.slice(0, -1));
|
|
26560
|
+
else files.push(e);
|
|
26561
|
+
}
|
|
26562
|
+
return { files: files.sort(), dirs: dirs.sort() };
|
|
26563
|
+
} catch {
|
|
26564
|
+
return empty;
|
|
26565
|
+
}
|
|
26566
|
+
}
|
|
26567
|
+
var DIR_ENTRY_MAX = 5e3;
|
|
26568
|
+
async function listDirEntries(repoDir, rel) {
|
|
26569
|
+
const empty = { files: [], dirs: [], truncated: false };
|
|
26570
|
+
if (!repoDir) return empty;
|
|
26571
|
+
const abs = repoAbsPath(repoDir, rel);
|
|
26572
|
+
let raw;
|
|
26573
|
+
try {
|
|
26574
|
+
raw = await readdir2(abs, { withFileTypes: true });
|
|
26575
|
+
} catch {
|
|
26576
|
+
return empty;
|
|
26577
|
+
}
|
|
26578
|
+
const files = [], dirs = [];
|
|
26579
|
+
for (const d of raw.slice(0, DIR_ENTRY_MAX)) {
|
|
26580
|
+
if (d.name === ".git") continue;
|
|
26581
|
+
(d.isDirectory() ? dirs : files).push(`${rel}/${d.name}`);
|
|
26582
|
+
}
|
|
26583
|
+
return { files: files.sort(), dirs: dirs.sort(), truncated: raw.length > DIR_ENTRY_MAX };
|
|
26584
|
+
}
|
|
26530
26585
|
async function readRepoFile2(repoDir, rel, ref = "") {
|
|
26531
26586
|
if (!repoDir) return null;
|
|
26532
26587
|
repoAbsPath(repoDir, rel, !!ref);
|
|
@@ -31222,7 +31277,7 @@ async function dropSpecAttachments(specId) {
|
|
|
31222
31277
|
|
|
31223
31278
|
// src/services/spec-attachment-dir.ts
|
|
31224
31279
|
init_db();
|
|
31225
|
-
import { mkdir as mkdir4, readdir as
|
|
31280
|
+
import { mkdir as mkdir4, readdir as readdir3, readFile as readFile3, rm as rm4, writeFile as writeFile3 } from "node:fs/promises";
|
|
31226
31281
|
import { join as join13 } from "node:path";
|
|
31227
31282
|
init_session_id();
|
|
31228
31283
|
init_uploads();
|
|
@@ -31287,7 +31342,7 @@ async function syncSpecAttachmentsDir(specId, projectId) {
|
|
|
31287
31342
|
}
|
|
31288
31343
|
await writeFile3(join13(dir2, INDEX), renderIndex(specId, items), { mode: 384 });
|
|
31289
31344
|
const keep = /* @__PURE__ */ new Set([INDEX, ...items.map((a) => a.filename)]);
|
|
31290
|
-
for (const name2 of await
|
|
31345
|
+
for (const name2 of await readdir3(dir2)) {
|
|
31291
31346
|
if (!keep.has(name2)) await rm4(join13(dir2, name2), { recursive: true, force: true }).catch(() => {
|
|
31292
31347
|
});
|
|
31293
31348
|
}
|
|
@@ -35153,8 +35208,25 @@ async function ide_default(app2) {
|
|
|
35153
35208
|
app2.get("/projects/:id/tree", async (req, reply) => {
|
|
35154
35209
|
const repoDir = await repoOf(req.params.id);
|
|
35155
35210
|
if (repoDir === void 0) return reply.code(404).send({ error: "not found" });
|
|
35156
|
-
const
|
|
35157
|
-
|
|
35211
|
+
const q = req.query;
|
|
35212
|
+
const ref = q.ref ?? "";
|
|
35213
|
+
const hidden = q.hidden === "1" || q.hidden === "true";
|
|
35214
|
+
if (q.under) {
|
|
35215
|
+
try {
|
|
35216
|
+
return { ref: "", ...await listDirEntries(repoDir, q.under), ignored: [] };
|
|
35217
|
+
} catch (e) {
|
|
35218
|
+
return entryError(reply, e);
|
|
35219
|
+
}
|
|
35220
|
+
}
|
|
35221
|
+
const files = await listRepoTree(repoDir, ref);
|
|
35222
|
+
if (!hidden || ref) return { ref, files, dirs: [], ignored: [] };
|
|
35223
|
+
const ign = await listIgnoredEntries(repoDir);
|
|
35224
|
+
return {
|
|
35225
|
+
ref,
|
|
35226
|
+
files: [...files, ...ign.files].sort(),
|
|
35227
|
+
dirs: ign.dirs,
|
|
35228
|
+
ignored: [...ign.files, ...ign.dirs]
|
|
35229
|
+
};
|
|
35158
35230
|
});
|
|
35159
35231
|
app2.get("/projects/:id/file", async (req, reply) => {
|
|
35160
35232
|
const id = req.params.id;
|
|
@@ -35597,7 +35669,7 @@ async function finishGraphOp(reply, id, repoDir, r, verb) {
|
|
|
35597
35669
|
}
|
|
35598
35670
|
|
|
35599
35671
|
// src/routes/fs.ts
|
|
35600
|
-
import { readdir as
|
|
35672
|
+
import { readdir as readdir4 } from "node:fs/promises";
|
|
35601
35673
|
import { homedir as homedir4 } from "node:os";
|
|
35602
35674
|
import { resolve as resolve17, dirname as dirname9, join as join16 } from "node:path";
|
|
35603
35675
|
async function fs_default(app2) {
|
|
@@ -35605,7 +35677,7 @@ async function fs_default(app2) {
|
|
|
35605
35677
|
const q = req.query.path;
|
|
35606
35678
|
const dir2 = q && q.trim() ? resolve17(q.trim()) : homedir4();
|
|
35607
35679
|
try {
|
|
35608
|
-
const ents = await
|
|
35680
|
+
const ents = await readdir4(dir2, { withFileTypes: true });
|
|
35609
35681
|
const entries3 = ents.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => ({ name: e.name, path: join16(dir2, e.name) })).sort((a, b) => a.name.localeCompare(b.name));
|
|
35610
35682
|
const parent = dirname9(dir2);
|
|
35611
35683
|
return { path: dir2, parent: parent === dir2 ? null : parent, entries: entries3 };
|
|
@@ -39011,7 +39083,7 @@ async function getLimits() {
|
|
|
39011
39083
|
}
|
|
39012
39084
|
|
|
39013
39085
|
// src/services/codex-limits.ts
|
|
39014
|
-
import { open as open3, readdir as
|
|
39086
|
+
import { open as open3, readdir as readdir5, stat as stat2 } from "node:fs/promises";
|
|
39015
39087
|
import { homedir as homedir8 } from "node:os";
|
|
39016
39088
|
import { join as join24 } from "node:path";
|
|
39017
39089
|
var TTL_MS3 = 3e4;
|
|
@@ -39048,7 +39120,7 @@ function toWindow(slot, raw, reached) {
|
|
|
39048
39120
|
async function recentRollouts(dir2) {
|
|
39049
39121
|
let entries3;
|
|
39050
39122
|
try {
|
|
39051
|
-
entries3 = (await
|
|
39123
|
+
entries3 = (await readdir5(dir2, { recursive: true })).filter((f) => f.endsWith(".jsonl"));
|
|
39052
39124
|
} catch {
|
|
39053
39125
|
return [];
|
|
39054
39126
|
}
|
|
@@ -40764,7 +40836,7 @@ import { randomUUID as randomUUID9 } from "node:crypto";
|
|
|
40764
40836
|
init_config2();
|
|
40765
40837
|
init_src2();
|
|
40766
40838
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
40767
|
-
import { mkdir as mkdir5, writeFile as writeFile4, readFile as readFile4, unlink as unlink4, readdir as
|
|
40839
|
+
import { mkdir as mkdir5, writeFile as writeFile4, readFile as readFile4, unlink as unlink4, readdir as readdir6, stat as stat3 } from "node:fs/promises";
|
|
40768
40840
|
import { join as join25, resolve as resolve19, basename as basename6 } from "node:path";
|
|
40769
40841
|
var MAX_TRANSCRIPT_BYTES = 1024 * 1024;
|
|
40770
40842
|
function transcriptDir() {
|
|
@@ -40809,7 +40881,7 @@ async function listTranscripts() {
|
|
|
40809
40881
|
const dir2 = transcriptDir();
|
|
40810
40882
|
let names;
|
|
40811
40883
|
try {
|
|
40812
|
-
names = await
|
|
40884
|
+
names = await readdir6(dir2);
|
|
40813
40885
|
} catch (e) {
|
|
40814
40886
|
if (e.code === "ENOENT") return [];
|
|
40815
40887
|
throw e;
|