vibecodeagent 0.1.64 → 0.1.65
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 +9 -0
- package/dist/agen.js +208 -183
- package/dist/bin.js +1 -1
- package/dist/daemon.js +42 -5
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -13,6 +13,15 @@ npm install -g vibecodeagent
|
|
|
13
13
|
|
|
14
14
|
The terminal UI ships as a separate package for your operating system and processor, installed automatically.
|
|
15
15
|
|
|
16
|
+
If npm stops with `EACCES` on a Mac, its global folder belongs to the system. Move it to your home folder once, then run the install again:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
mkdir -p ~/.npm-global
|
|
20
|
+
npm config set prefix ~/.npm-global
|
|
21
|
+
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
|
|
22
|
+
source ~/.zshrc
|
|
23
|
+
```
|
|
24
|
+
|
|
16
25
|
## Use
|
|
17
26
|
|
|
18
27
|
```sh
|
package/dist/agen.js
CHANGED
|
@@ -131628,6 +131628,194 @@ var ToolCallAccumulator = class {
|
|
|
131628
131628
|
}
|
|
131629
131629
|
};
|
|
131630
131630
|
|
|
131631
|
+
// packages/core/src/mcp/tool-mcp.ts
|
|
131632
|
+
var import_node_crypto14 = require("node:crypto");
|
|
131633
|
+
var MAKS_NAMA_TOOL = 64;
|
|
131634
|
+
var MAKS_DESKRIPSI = 2048;
|
|
131635
|
+
function bersihkanSegmen(s) {
|
|
131636
|
+
return s.replace(/[^A-Za-z0-9_-]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "") || "x";
|
|
131637
|
+
}
|
|
131638
|
+
function hash6(s) {
|
|
131639
|
+
return (0, import_node_crypto14.createHash)("sha256").update(s).digest("hex").slice(0, 6);
|
|
131640
|
+
}
|
|
131641
|
+
function namaAgenTool(idServer, namaTool, terpakai) {
|
|
131642
|
+
const awal = `${AWALAN_TOOL_MCP}${bersihkanSegmen(idServer)}__`;
|
|
131643
|
+
const bersih2 = bersihkanSegmen(namaTool);
|
|
131644
|
+
const polos = awal + bersih2;
|
|
131645
|
+
if (polos.length <= MAKS_NAMA_TOOL && !terpakai.has(polos) && bersih2 === namaTool) return polos;
|
|
131646
|
+
const sufiks = `_${hash6(namaTool)}`;
|
|
131647
|
+
const ruang = MAKS_NAMA_TOOL - awal.length - sufiks.length;
|
|
131648
|
+
return awal + bersih2.slice(0, Math.max(1, ruang)) + sufiks;
|
|
131649
|
+
}
|
|
131650
|
+
function headerParamDari(skema) {
|
|
131651
|
+
const daftar2 = [];
|
|
131652
|
+
const dilihat = /* @__PURE__ */ new Set();
|
|
131653
|
+
let sebab = null;
|
|
131654
|
+
const jelajah = (node, jalur, lewatProperti) => {
|
|
131655
|
+
if (sebab !== null || typeof node !== "object" || node === null) return;
|
|
131656
|
+
if (Array.isArray(node)) {
|
|
131657
|
+
for (const x of node) jelajah(x, jalur, false);
|
|
131658
|
+
return;
|
|
131659
|
+
}
|
|
131660
|
+
const o = node;
|
|
131661
|
+
const h = o["x-mcp-header"];
|
|
131662
|
+
if (h !== void 0) {
|
|
131663
|
+
if (!lewatProperti || jalur.length === 0) {
|
|
131664
|
+
sebab = "x-mcp-header di luar rantai properties";
|
|
131665
|
+
return;
|
|
131666
|
+
}
|
|
131667
|
+
if (typeof h !== "string" || !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(h)) {
|
|
131668
|
+
sebab = `x-mcp-header tidak sah: ${String(h)}`;
|
|
131669
|
+
return;
|
|
131670
|
+
}
|
|
131671
|
+
const tipe = o["type"];
|
|
131672
|
+
if (tipe !== "string" && tipe !== "integer" && tipe !== "boolean") {
|
|
131673
|
+
sebab = `x-mcp-header pada parameter bertipe ${String(tipe)}`;
|
|
131674
|
+
return;
|
|
131675
|
+
}
|
|
131676
|
+
const kecil = h.toLowerCase();
|
|
131677
|
+
if (dilihat.has(kecil)) {
|
|
131678
|
+
sebab = `x-mcp-header ganda: ${h}`;
|
|
131679
|
+
return;
|
|
131680
|
+
}
|
|
131681
|
+
dilihat.add(kecil);
|
|
131682
|
+
daftar2.push({ jalur, header: h });
|
|
131683
|
+
}
|
|
131684
|
+
for (const [k, v] of Object.entries(o)) {
|
|
131685
|
+
if (k === "properties" && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
131686
|
+
for (const [nama, anak] of Object.entries(v)) {
|
|
131687
|
+
jelajah(anak, [...jalur, nama], lewatProperti);
|
|
131688
|
+
}
|
|
131689
|
+
} else if (k !== "x-mcp-header") {
|
|
131690
|
+
jelajah(v, jalur, false);
|
|
131691
|
+
}
|
|
131692
|
+
}
|
|
131693
|
+
};
|
|
131694
|
+
jelajah(skema, [], true);
|
|
131695
|
+
return sebab !== null ? { ok: false, sebab } : { ok: true, daftar: daftar2 };
|
|
131696
|
+
}
|
|
131697
|
+
function parameterDari(skema) {
|
|
131698
|
+
if (typeof skema !== "object" || skema === null || Array.isArray(skema)) return { type: "object", properties: {} };
|
|
131699
|
+
const s = { ...skema };
|
|
131700
|
+
delete s["$schema"];
|
|
131701
|
+
const properties = s["properties"];
|
|
131702
|
+
return {
|
|
131703
|
+
...s,
|
|
131704
|
+
type: "object",
|
|
131705
|
+
properties: typeof properties === "object" && properties !== null && !Array.isArray(properties) ? properties : {}
|
|
131706
|
+
};
|
|
131707
|
+
}
|
|
131708
|
+
function siapkanTools(idServer, namaServer, mentah) {
|
|
131709
|
+
const tools = [];
|
|
131710
|
+
const ditolak = [];
|
|
131711
|
+
const terpakai = /* @__PURE__ */ new Set();
|
|
131712
|
+
for (const x of mentah) {
|
|
131713
|
+
if (typeof x !== "object" || x === null) continue;
|
|
131714
|
+
const t = x;
|
|
131715
|
+
if (typeof t.name !== "string" || t.name.trim() === "") {
|
|
131716
|
+
ditolak.push({ nama: "(tanpa nama)", sebab: "nama tool kosong" });
|
|
131717
|
+
continue;
|
|
131718
|
+
}
|
|
131719
|
+
const header = headerParamDari(t.inputSchema);
|
|
131720
|
+
if (!header.ok) {
|
|
131721
|
+
ditolak.push({ nama: t.name, sebab: header.sebab });
|
|
131722
|
+
continue;
|
|
131723
|
+
}
|
|
131724
|
+
const namaAgen = namaAgenTool(idServer, t.name, terpakai);
|
|
131725
|
+
terpakai.add(namaAgen);
|
|
131726
|
+
const asli = typeof t.description === "string" ? t.description.trim() : "";
|
|
131727
|
+
const deskripsi = `[MCP server "${namaServer}", tool "${t.name}"] ${asli}`.trim();
|
|
131728
|
+
tools.push({
|
|
131729
|
+
nama: t.name,
|
|
131730
|
+
namaAgen,
|
|
131731
|
+
deskripsi: deskripsi.length > MAKS_DESKRIPSI ? `${deskripsi.slice(0, MAKS_DESKRIPSI - 1)}\u2026` : deskripsi,
|
|
131732
|
+
parameters: parameterDari(t.inputSchema),
|
|
131733
|
+
bacaSaja: t.annotations?.readOnlyHint === true,
|
|
131734
|
+
headerParam: header.daftar
|
|
131735
|
+
});
|
|
131736
|
+
}
|
|
131737
|
+
return { tools, ditolak };
|
|
131738
|
+
}
|
|
131739
|
+
function efekToolMcp(bacaSaja2) {
|
|
131740
|
+
return bacaSaja2 ? "network" : "exec";
|
|
131741
|
+
}
|
|
131742
|
+
function headerDariArgumen(headerParam, args, kodekan) {
|
|
131743
|
+
const h = {};
|
|
131744
|
+
for (const { jalur, header } of headerParam) {
|
|
131745
|
+
let v = args;
|
|
131746
|
+
for (const k of jalur) v = typeof v === "object" && v !== null ? v[k] : void 0;
|
|
131747
|
+
if (v === void 0 || v === null) continue;
|
|
131748
|
+
const teks4 = typeof v === "boolean" ? String(v) : typeof v === "number" ? String(Math.trunc(v)) : typeof v === "string" ? v : null;
|
|
131749
|
+
if (teks4 !== null) h[`mcp-param-${header.toLowerCase()}`] = kodekan(teks4);
|
|
131750
|
+
}
|
|
131751
|
+
return h;
|
|
131752
|
+
}
|
|
131753
|
+
function teksHasil(hasil2) {
|
|
131754
|
+
const bagian = [];
|
|
131755
|
+
const isi = Array.isArray(hasil2["content"]) ? hasil2["content"] : [];
|
|
131756
|
+
for (const c of isi) {
|
|
131757
|
+
if (typeof c !== "object" || c === null) continue;
|
|
131758
|
+
const o = c;
|
|
131759
|
+
switch (o["type"]) {
|
|
131760
|
+
case "text":
|
|
131761
|
+
if (typeof o["text"] === "string") bagian.push(o["text"]);
|
|
131762
|
+
break;
|
|
131763
|
+
case "image":
|
|
131764
|
+
case "audio": {
|
|
131765
|
+
const data = typeof o["data"] === "string" ? o["data"] : "";
|
|
131766
|
+
bagian.push(`[${String(o["type"])} ${String(o["mimeType"] ?? "")}, ${String(Math.floor(data.length * 3 / 4))} bytes \u2014 not shown]`);
|
|
131767
|
+
break;
|
|
131768
|
+
}
|
|
131769
|
+
case "resource": {
|
|
131770
|
+
const r = o["resource"] ?? {};
|
|
131771
|
+
const uri = String(r["uri"] ?? "");
|
|
131772
|
+
if (typeof r["text"] === "string") bagian.push(`[resource ${uri}]
|
|
131773
|
+
${r["text"]}`);
|
|
131774
|
+
else bagian.push(`[binary resource ${uri} ${String(r["mimeType"] ?? "")}]`);
|
|
131775
|
+
break;
|
|
131776
|
+
}
|
|
131777
|
+
case "resource_link":
|
|
131778
|
+
bagian.push(`[resource link: ${String(o["name"] ?? "")} ${String(o["uri"] ?? "")}]`);
|
|
131779
|
+
break;
|
|
131780
|
+
default:
|
|
131781
|
+
break;
|
|
131782
|
+
}
|
|
131783
|
+
}
|
|
131784
|
+
if (bagian.length === 0 && hasil2["structuredContent"] !== void 0) {
|
|
131785
|
+
bagian.push(JSON.stringify(hasil2["structuredContent"], null, 2));
|
|
131786
|
+
}
|
|
131787
|
+
const galat11 = hasil2["isError"] === true;
|
|
131788
|
+
const teks4 = bagian.join("\n").trim();
|
|
131789
|
+
return { teks: teks4 === "" ? galat11 ? "The MCP tool reported an error without details." : "(empty result)" : teks4, galat: galat11 };
|
|
131790
|
+
}
|
|
131791
|
+
|
|
131792
|
+
// packages/core/src/provider/nama-tool-riwayat.ts
|
|
131793
|
+
var POLA_NAMA_SAH = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
131794
|
+
function namaToolKirim(nama) {
|
|
131795
|
+
return POLA_NAMA_SAH.test(nama) ? nama : bersihkanSegmen(nama).slice(0, MAKS_NAMA_TOOL);
|
|
131796
|
+
}
|
|
131797
|
+
function pesanNamaSah(m) {
|
|
131798
|
+
if (m.role === "tool") {
|
|
131799
|
+
if (m.name === void 0) return m;
|
|
131800
|
+
const nama = namaToolKirim(m.name);
|
|
131801
|
+
return nama === m.name ? m : { ...m, name: nama };
|
|
131802
|
+
}
|
|
131803
|
+
if (m.role !== "assistant" || m.tool_calls === void 0) return m;
|
|
131804
|
+
if (m.tool_calls.every((t) => namaToolKirim(t.function.name) === t.function.name)) return m;
|
|
131805
|
+
return { ...m, tool_calls: m.tool_calls.map((t) => ({ ...t, function: { ...t.function, name: namaToolKirim(t.function.name) } })) };
|
|
131806
|
+
}
|
|
131807
|
+
function riwayatNamaToolSah(pesan) {
|
|
131808
|
+
let keluar = null;
|
|
131809
|
+
for (let i = 0; i < pesan.length; i += 1) {
|
|
131810
|
+
const m = pesan[i];
|
|
131811
|
+
const baru = pesanNamaSah(m);
|
|
131812
|
+
if (baru === m) continue;
|
|
131813
|
+
keluar ??= pesan.slice();
|
|
131814
|
+
keluar[i] = baru;
|
|
131815
|
+
}
|
|
131816
|
+
return keluar ?? pesan;
|
|
131817
|
+
}
|
|
131818
|
+
|
|
131631
131819
|
// packages/core/src/provider/delta.ts
|
|
131632
131820
|
function* petakanDelta(delta, akumulator) {
|
|
131633
131821
|
const konten = delta["content"];
|
|
@@ -133213,7 +133401,7 @@ var OpenRouterProvider = class {
|
|
|
133213
133401
|
bangunBody(req, effortDiapit, saklarSaja, cadangan) {
|
|
133214
133402
|
const body = {
|
|
133215
133403
|
model: req.model,
|
|
133216
|
-
messages: req.messages
|
|
133404
|
+
messages: riwayatNamaToolSah(req.messages)
|
|
133217
133405
|
};
|
|
133218
133406
|
if (req.tools.length > 0) body["tools"] = req.tools;
|
|
133219
133407
|
body["stream"] = true;
|
|
@@ -133633,7 +133821,7 @@ function pesanUntukLokal(pesan, opsi = {}) {
|
|
|
133633
133821
|
const terimaGambar = opsi.terimaGambar === true;
|
|
133634
133822
|
const dicabut = [];
|
|
133635
133823
|
const keluar = gabungPenggunaBeruntun(
|
|
133636
|
-
lintasanUtama(pasangkanTool(pesan), dicabut, terimaGambar)
|
|
133824
|
+
lintasanUtama(pasangkanTool(riwayatNamaToolSah(pesan)), dicabut, terimaGambar)
|
|
133637
133825
|
);
|
|
133638
133826
|
if (dicabut.length === 0) return keluar;
|
|
133639
133827
|
const teks4 = dicabut.join("\n\n");
|
|
@@ -134434,7 +134622,7 @@ function normalkanFinishLokal(mentah) {
|
|
|
134434
134622
|
}
|
|
134435
134623
|
|
|
134436
134624
|
// packages/core/src/host/jembatan-potret.ts
|
|
134437
|
-
var
|
|
134625
|
+
var import_node_crypto15 = require("node:crypto");
|
|
134438
134626
|
var KELONGGARAN_MS = 15e3;
|
|
134439
134627
|
var JembatanPotret = class {
|
|
134440
134628
|
constructor(emit, batasMs) {
|
|
@@ -134445,7 +134633,7 @@ var JembatanPotret = class {
|
|
|
134445
134633
|
batasMs;
|
|
134446
134634
|
tertunda = /* @__PURE__ */ new Map();
|
|
134447
134635
|
minta(p) {
|
|
134448
|
-
const id = (0,
|
|
134636
|
+
const id = (0, import_node_crypto15.randomUUID)();
|
|
134449
134637
|
const batasMs = (this.batasMs ?? batasPotretMs(p)) + KELONGGARAN_MS;
|
|
134450
134638
|
return new Promise((selesai) => {
|
|
134451
134639
|
const batas = setTimeout(() => {
|
|
@@ -134562,7 +134750,7 @@ function rakitLangkahGagal(mentah) {
|
|
|
134562
134750
|
}
|
|
134563
134751
|
|
|
134564
134752
|
// packages/core/src/host/jembatan-sesi-lain.ts
|
|
134565
|
-
var
|
|
134753
|
+
var import_node_crypto16 = require("node:crypto");
|
|
134566
134754
|
var BATAS_SESI_LAIN_MS = 1e4;
|
|
134567
134755
|
var JembatanSesiLain = class {
|
|
134568
134756
|
constructor(emit, batasMs = BATAS_SESI_LAIN_MS) {
|
|
@@ -134590,7 +134778,7 @@ var JembatanSesiLain = class {
|
|
|
134590
134778
|
return true;
|
|
134591
134779
|
}
|
|
134592
134780
|
kirim(p) {
|
|
134593
|
-
const id = (0,
|
|
134781
|
+
const id = (0, import_node_crypto16.randomUUID)();
|
|
134594
134782
|
return new Promise((selesai) => {
|
|
134595
134783
|
const batas = setTimeout(() => {
|
|
134596
134784
|
this.tertunda.delete(id);
|
|
@@ -134613,7 +134801,7 @@ var JembatanSesiLain = class {
|
|
|
134613
134801
|
};
|
|
134614
134802
|
|
|
134615
134803
|
// packages/core/src/host/jembatan-dokumen.ts
|
|
134616
|
-
var
|
|
134804
|
+
var import_node_crypto17 = require("node:crypto");
|
|
134617
134805
|
var KELONGGARAN_MS2 = 1e4;
|
|
134618
134806
|
var JembatanDokumen = class {
|
|
134619
134807
|
constructor(emit, batasMs = 6e4) {
|
|
@@ -134624,7 +134812,7 @@ var JembatanDokumen = class {
|
|
|
134624
134812
|
batasMs;
|
|
134625
134813
|
tertunda = /* @__PURE__ */ new Map();
|
|
134626
134814
|
minta(p) {
|
|
134627
|
-
const id = (0,
|
|
134815
|
+
const id = (0, import_node_crypto17.randomUUID)();
|
|
134628
134816
|
return new Promise((selesai) => {
|
|
134629
134817
|
const batas = setTimeout(() => {
|
|
134630
134818
|
this.tertunda.delete(id);
|
|
@@ -134712,8 +134900,8 @@ function gabungSkillAktif(dariPrompt, terdeteksi) {
|
|
|
134712
134900
|
}
|
|
134713
134901
|
|
|
134714
134902
|
// packages/core/src/skills/index-prompt.ts
|
|
134715
|
-
var
|
|
134716
|
-
function potongDeskripsi(teks4, maks =
|
|
134903
|
+
var MAKS_DESKRIPSI2 = LIMITS.SKILL_INDEX_DESC_CHARS;
|
|
134904
|
+
function potongDeskripsi(teks4, maks = MAKS_DESKRIPSI2) {
|
|
134717
134905
|
const aman2 = teks4.replace(/<(\/?)(available_skills|system|available_tools)>/gi, "<\u200B$1$2>");
|
|
134718
134906
|
const satuBaris5 = aman2.replace(/\s+/g, " ").trim();
|
|
134719
134907
|
if (satuBaris5.length <= maks) return satuBaris5;
|
|
@@ -134774,7 +134962,7 @@ function terlihatUntukModel(s) {
|
|
|
134774
134962
|
function bangunIndeksPrompt(indeks, opsi = {}) {
|
|
134775
134963
|
const aktif = opsi.aktif ?? null;
|
|
134776
134964
|
if (!ada(aktif, "Skill")) return "";
|
|
134777
|
-
const maks = opsi.maksDeskripsi ??
|
|
134965
|
+
const maks = opsi.maksDeskripsi ?? MAKS_DESKRIPSI2;
|
|
134778
134966
|
const deskripsiKategori = opsi.categoryDescriptions ?? {};
|
|
134779
134967
|
const perKategori = /* @__PURE__ */ new Map();
|
|
134780
134968
|
for (const s of indeks.skills) {
|
|
@@ -135159,7 +135347,7 @@ function buatPengawasMacet(o) {
|
|
|
135159
135347
|
}
|
|
135160
135348
|
|
|
135161
135349
|
// packages/core/src/agent/subagent.ts
|
|
135162
|
-
var
|
|
135350
|
+
var import_node_crypto18 = require("node:crypto");
|
|
135163
135351
|
var JEDA_DENYUT_MS = 5e3;
|
|
135164
135352
|
var MAKS_GAMBAR_KEMBALI = 3;
|
|
135165
135353
|
function catatanTool(nama, argUtama2) {
|
|
@@ -135181,7 +135369,7 @@ function buatPembuatSesiAnak(o) {
|
|
|
135181
135369
|
const m = opsi.ctxInduk.mode;
|
|
135182
135370
|
return m === "plan" || m === "chat" ? toolsetSempit : toolsetDasar;
|
|
135183
135371
|
};
|
|
135184
|
-
const turnId = (0,
|
|
135372
|
+
const turnId = (0, import_node_crypto18.randomUUID)();
|
|
135185
135373
|
const pengawas = buatPengawasMacet({
|
|
135186
135374
|
induk: opsi.signal,
|
|
135187
135375
|
...opsi.batasMacetMs !== void 0 ? { batasMs: opsi.batasMacetMs } : {}
|
|
@@ -135444,7 +135632,7 @@ function modeFolderSesi(wadah, cwd, kreasi, resume) {
|
|
|
135444
135632
|
var import_node_fs51 = require("node:fs");
|
|
135445
135633
|
|
|
135446
135634
|
// packages/core/src/agent/pesan-folder-sesi.ts
|
|
135447
|
-
var
|
|
135635
|
+
var import_node_crypto19 = require("node:crypto");
|
|
135448
135636
|
var import_node_fs50 = require("node:fs");
|
|
135449
135637
|
var import_node_path62 = require("node:path");
|
|
135450
135638
|
var MAKS_PANJANG_NAMA = 40;
|
|
@@ -135534,7 +135722,7 @@ function dirReservasiFolderSesi() {
|
|
|
135534
135722
|
return (0, import_node_path62.join)(vibecodeHome(), "folder-sesi");
|
|
135535
135723
|
}
|
|
135536
135724
|
function berkasReservasi(dir, path2) {
|
|
135537
|
-
return (0, import_node_path62.join)(dir, `${(0,
|
|
135725
|
+
return (0, import_node_path62.join)(dir, `${(0, import_node_crypto19.createHash)("sha256").update((0, import_node_path62.resolve)(path2).toLowerCase()).digest("hex").slice(0, 24)}.json`);
|
|
135538
135726
|
}
|
|
135539
135727
|
function bacaReservasi(berkas) {
|
|
135540
135728
|
try {
|
|
@@ -135720,7 +135908,7 @@ function modeOrkestrasi(prefWorkflowAktif, ultracode) {
|
|
|
135720
135908
|
}
|
|
135721
135909
|
|
|
135722
135910
|
// packages/core/src/host/human-bridge.ts
|
|
135723
|
-
var
|
|
135911
|
+
var import_node_crypto20 = require("node:crypto");
|
|
135724
135912
|
var ID_HOST2 = "p1";
|
|
135725
135913
|
var HumanBridge = class {
|
|
135726
135914
|
constructor(emit) {
|
|
@@ -135748,7 +135936,7 @@ var HumanBridge = class {
|
|
|
135748
135936
|
return { choices: ["once", "session", "always", "deny"], scopes: ["session", "project", "global"] };
|
|
135749
135937
|
}
|
|
135750
135938
|
mintaIzin(p) {
|
|
135751
|
-
const requestId = (0,
|
|
135939
|
+
const requestId = (0, import_node_crypto20.randomUUID)();
|
|
135752
135940
|
const { choices, scopes } = this.pilihanUntuk(p.origin);
|
|
135753
135941
|
const event = {
|
|
135754
135942
|
type: "approval.request",
|
|
@@ -135804,7 +135992,7 @@ var HumanBridge = class {
|
|
|
135804
135992
|
return { status: adaYangCocok ? "ok" : "expired" };
|
|
135805
135993
|
}
|
|
135806
135994
|
tanyaPengguna(pertanyaan) {
|
|
135807
|
-
const requestId = (0,
|
|
135995
|
+
const requestId = (0, import_node_crypto20.randomUUID)();
|
|
135808
135996
|
const event = {
|
|
135809
135997
|
type: "clarify.request",
|
|
135810
135998
|
request_id: requestId,
|
|
@@ -135831,7 +136019,7 @@ var HumanBridge = class {
|
|
|
135831
136019
|
* dipulangkan, juga saat habis waktu dan ditutup. `penerima` sudah divalidasi pemanggil terhadap roster.
|
|
135832
136020
|
*/
|
|
135833
136021
|
tanyaPeserta(pertanyaan, penerima, audience) {
|
|
135834
|
-
const requestId = (0,
|
|
136022
|
+
const requestId = (0, import_node_crypto20.randomUUID)();
|
|
135835
136023
|
const event = {
|
|
135836
136024
|
type: "clarify.request",
|
|
135837
136025
|
request_id: requestId,
|
|
@@ -135919,7 +136107,7 @@ var HumanBridge = class {
|
|
|
135919
136107
|
* `plan.expire` dan `timeout_ms` di kartunya — sebagaimana `approval.expire`.
|
|
135920
136108
|
*/
|
|
135921
136109
|
mintaKeluarRencana(planPath, planMarkdown) {
|
|
135922
|
-
const requestId = (0,
|
|
136110
|
+
const requestId = (0, import_node_crypto20.randomUUID)();
|
|
135923
136111
|
const event = {
|
|
135924
136112
|
type: "plan.exit_request",
|
|
135925
136113
|
request_id: requestId,
|
|
@@ -136150,169 +136338,6 @@ var import_node_path64 = require("node:path");
|
|
|
136150
136338
|
|
|
136151
136339
|
// packages/core/src/mcp/konfig.ts
|
|
136152
136340
|
var import_node_path63 = require("node:path");
|
|
136153
|
-
|
|
136154
|
-
// packages/core/src/mcp/tool-mcp.ts
|
|
136155
|
-
var import_node_crypto20 = require("node:crypto");
|
|
136156
|
-
var MAKS_NAMA_TOOL = 64;
|
|
136157
|
-
var MAKS_DESKRIPSI2 = 2048;
|
|
136158
|
-
function bersihkanSegmen(s) {
|
|
136159
|
-
return s.replace(/[^A-Za-z0-9_-]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "") || "x";
|
|
136160
|
-
}
|
|
136161
|
-
function hash6(s) {
|
|
136162
|
-
return (0, import_node_crypto20.createHash)("sha256").update(s).digest("hex").slice(0, 6);
|
|
136163
|
-
}
|
|
136164
|
-
function namaAgenTool(idServer, namaTool, terpakai) {
|
|
136165
|
-
const awal = `${AWALAN_TOOL_MCP}${bersihkanSegmen(idServer)}__`;
|
|
136166
|
-
const bersih2 = bersihkanSegmen(namaTool);
|
|
136167
|
-
const polos = awal + bersih2;
|
|
136168
|
-
if (polos.length <= MAKS_NAMA_TOOL && !terpakai.has(polos) && bersih2 === namaTool) return polos;
|
|
136169
|
-
const sufiks = `_${hash6(namaTool)}`;
|
|
136170
|
-
const ruang = MAKS_NAMA_TOOL - awal.length - sufiks.length;
|
|
136171
|
-
return awal + bersih2.slice(0, Math.max(1, ruang)) + sufiks;
|
|
136172
|
-
}
|
|
136173
|
-
function headerParamDari(skema) {
|
|
136174
|
-
const daftar2 = [];
|
|
136175
|
-
const dilihat = /* @__PURE__ */ new Set();
|
|
136176
|
-
let sebab = null;
|
|
136177
|
-
const jelajah = (node, jalur, lewatProperti) => {
|
|
136178
|
-
if (sebab !== null || typeof node !== "object" || node === null) return;
|
|
136179
|
-
if (Array.isArray(node)) {
|
|
136180
|
-
for (const x of node) jelajah(x, jalur, false);
|
|
136181
|
-
return;
|
|
136182
|
-
}
|
|
136183
|
-
const o = node;
|
|
136184
|
-
const h = o["x-mcp-header"];
|
|
136185
|
-
if (h !== void 0) {
|
|
136186
|
-
if (!lewatProperti || jalur.length === 0) {
|
|
136187
|
-
sebab = "x-mcp-header di luar rantai properties";
|
|
136188
|
-
return;
|
|
136189
|
-
}
|
|
136190
|
-
if (typeof h !== "string" || !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(h)) {
|
|
136191
|
-
sebab = `x-mcp-header tidak sah: ${String(h)}`;
|
|
136192
|
-
return;
|
|
136193
|
-
}
|
|
136194
|
-
const tipe = o["type"];
|
|
136195
|
-
if (tipe !== "string" && tipe !== "integer" && tipe !== "boolean") {
|
|
136196
|
-
sebab = `x-mcp-header pada parameter bertipe ${String(tipe)}`;
|
|
136197
|
-
return;
|
|
136198
|
-
}
|
|
136199
|
-
const kecil = h.toLowerCase();
|
|
136200
|
-
if (dilihat.has(kecil)) {
|
|
136201
|
-
sebab = `x-mcp-header ganda: ${h}`;
|
|
136202
|
-
return;
|
|
136203
|
-
}
|
|
136204
|
-
dilihat.add(kecil);
|
|
136205
|
-
daftar2.push({ jalur, header: h });
|
|
136206
|
-
}
|
|
136207
|
-
for (const [k, v] of Object.entries(o)) {
|
|
136208
|
-
if (k === "properties" && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
136209
|
-
for (const [nama, anak] of Object.entries(v)) {
|
|
136210
|
-
jelajah(anak, [...jalur, nama], lewatProperti);
|
|
136211
|
-
}
|
|
136212
|
-
} else if (k !== "x-mcp-header") {
|
|
136213
|
-
jelajah(v, jalur, false);
|
|
136214
|
-
}
|
|
136215
|
-
}
|
|
136216
|
-
};
|
|
136217
|
-
jelajah(skema, [], true);
|
|
136218
|
-
return sebab !== null ? { ok: false, sebab } : { ok: true, daftar: daftar2 };
|
|
136219
|
-
}
|
|
136220
|
-
function parameterDari(skema) {
|
|
136221
|
-
if (typeof skema !== "object" || skema === null || Array.isArray(skema)) return { type: "object", properties: {} };
|
|
136222
|
-
const s = { ...skema };
|
|
136223
|
-
delete s["$schema"];
|
|
136224
|
-
const properties = s["properties"];
|
|
136225
|
-
return {
|
|
136226
|
-
...s,
|
|
136227
|
-
type: "object",
|
|
136228
|
-
properties: typeof properties === "object" && properties !== null && !Array.isArray(properties) ? properties : {}
|
|
136229
|
-
};
|
|
136230
|
-
}
|
|
136231
|
-
function siapkanTools(idServer, namaServer, mentah) {
|
|
136232
|
-
const tools = [];
|
|
136233
|
-
const ditolak = [];
|
|
136234
|
-
const terpakai = /* @__PURE__ */ new Set();
|
|
136235
|
-
for (const x of mentah) {
|
|
136236
|
-
if (typeof x !== "object" || x === null) continue;
|
|
136237
|
-
const t = x;
|
|
136238
|
-
if (typeof t.name !== "string" || t.name.trim() === "") {
|
|
136239
|
-
ditolak.push({ nama: "(tanpa nama)", sebab: "nama tool kosong" });
|
|
136240
|
-
continue;
|
|
136241
|
-
}
|
|
136242
|
-
const header = headerParamDari(t.inputSchema);
|
|
136243
|
-
if (!header.ok) {
|
|
136244
|
-
ditolak.push({ nama: t.name, sebab: header.sebab });
|
|
136245
|
-
continue;
|
|
136246
|
-
}
|
|
136247
|
-
const namaAgen = namaAgenTool(idServer, t.name, terpakai);
|
|
136248
|
-
terpakai.add(namaAgen);
|
|
136249
|
-
const asli = typeof t.description === "string" ? t.description.trim() : "";
|
|
136250
|
-
const deskripsi = `[MCP server "${namaServer}", tool "${t.name}"] ${asli}`.trim();
|
|
136251
|
-
tools.push({
|
|
136252
|
-
nama: t.name,
|
|
136253
|
-
namaAgen,
|
|
136254
|
-
deskripsi: deskripsi.length > MAKS_DESKRIPSI2 ? `${deskripsi.slice(0, MAKS_DESKRIPSI2 - 1)}\u2026` : deskripsi,
|
|
136255
|
-
parameters: parameterDari(t.inputSchema),
|
|
136256
|
-
bacaSaja: t.annotations?.readOnlyHint === true,
|
|
136257
|
-
headerParam: header.daftar
|
|
136258
|
-
});
|
|
136259
|
-
}
|
|
136260
|
-
return { tools, ditolak };
|
|
136261
|
-
}
|
|
136262
|
-
function efekToolMcp(bacaSaja2) {
|
|
136263
|
-
return bacaSaja2 ? "network" : "exec";
|
|
136264
|
-
}
|
|
136265
|
-
function headerDariArgumen(headerParam, args, kodekan) {
|
|
136266
|
-
const h = {};
|
|
136267
|
-
for (const { jalur, header } of headerParam) {
|
|
136268
|
-
let v = args;
|
|
136269
|
-
for (const k of jalur) v = typeof v === "object" && v !== null ? v[k] : void 0;
|
|
136270
|
-
if (v === void 0 || v === null) continue;
|
|
136271
|
-
const teks4 = typeof v === "boolean" ? String(v) : typeof v === "number" ? String(Math.trunc(v)) : typeof v === "string" ? v : null;
|
|
136272
|
-
if (teks4 !== null) h[`mcp-param-${header.toLowerCase()}`] = kodekan(teks4);
|
|
136273
|
-
}
|
|
136274
|
-
return h;
|
|
136275
|
-
}
|
|
136276
|
-
function teksHasil(hasil2) {
|
|
136277
|
-
const bagian = [];
|
|
136278
|
-
const isi = Array.isArray(hasil2["content"]) ? hasil2["content"] : [];
|
|
136279
|
-
for (const c of isi) {
|
|
136280
|
-
if (typeof c !== "object" || c === null) continue;
|
|
136281
|
-
const o = c;
|
|
136282
|
-
switch (o["type"]) {
|
|
136283
|
-
case "text":
|
|
136284
|
-
if (typeof o["text"] === "string") bagian.push(o["text"]);
|
|
136285
|
-
break;
|
|
136286
|
-
case "image":
|
|
136287
|
-
case "audio": {
|
|
136288
|
-
const data = typeof o["data"] === "string" ? o["data"] : "";
|
|
136289
|
-
bagian.push(`[${String(o["type"])} ${String(o["mimeType"] ?? "")}, ${String(Math.floor(data.length * 3 / 4))} bytes \u2014 not shown]`);
|
|
136290
|
-
break;
|
|
136291
|
-
}
|
|
136292
|
-
case "resource": {
|
|
136293
|
-
const r = o["resource"] ?? {};
|
|
136294
|
-
const uri = String(r["uri"] ?? "");
|
|
136295
|
-
if (typeof r["text"] === "string") bagian.push(`[resource ${uri}]
|
|
136296
|
-
${r["text"]}`);
|
|
136297
|
-
else bagian.push(`[binary resource ${uri} ${String(r["mimeType"] ?? "")}]`);
|
|
136298
|
-
break;
|
|
136299
|
-
}
|
|
136300
|
-
case "resource_link":
|
|
136301
|
-
bagian.push(`[resource link: ${String(o["name"] ?? "")} ${String(o["uri"] ?? "")}]`);
|
|
136302
|
-
break;
|
|
136303
|
-
default:
|
|
136304
|
-
break;
|
|
136305
|
-
}
|
|
136306
|
-
}
|
|
136307
|
-
if (bagian.length === 0 && hasil2["structuredContent"] !== void 0) {
|
|
136308
|
-
bagian.push(JSON.stringify(hasil2["structuredContent"], null, 2));
|
|
136309
|
-
}
|
|
136310
|
-
const galat11 = hasil2["isError"] === true;
|
|
136311
|
-
const teks4 = bagian.join("\n").trim();
|
|
136312
|
-
return { teks: teks4 === "" ? galat11 ? "The MCP tool reported an error without details." : "(empty result)" : teks4, galat: galat11 };
|
|
136313
|
-
}
|
|
136314
|
-
|
|
136315
|
-
// packages/core/src/mcp/konfig.ts
|
|
136316
136341
|
var MAKS_RAHASIA = 30;
|
|
136317
136342
|
var MAKS_NILAI2 = 8192;
|
|
136318
136343
|
var HEADER_TERLARANG = /* @__PURE__ */ new Set(["content-type", "accept", "content-length", "host", "connection", "transfer-encoding"]);
|
package/dist/bin.js
CHANGED
|
@@ -1118,7 +1118,7 @@ function perintahTui(env, ada, paket) {
|
|
|
1118
1118
|
}
|
|
1119
1119
|
|
|
1120
1120
|
// apps/cli/src/peluncur/bin.ts
|
|
1121
|
-
var VERSI = true ? "0.1.
|
|
1121
|
+
var VERSI = true ? "0.1.65" : "0.0.0-dev";
|
|
1122
1122
|
var NAMA_CLI = true ? "vibecodeagent" : "vibecodeagent";
|
|
1123
1123
|
var AWALAN_TUI = true ? "@vibecodeagent/cli" : "@vibecodeagent/cli";
|
|
1124
1124
|
var BINER_TUI = true ? "vibecode-tui" : "vibecode-tui";
|
package/dist/daemon.js
CHANGED
|
@@ -99140,20 +99140,29 @@ function kodeKeluar(code, signal) {
|
|
|
99140
99140
|
if (signal !== null) return 128 + (NOMOR_SINYAL[signal] ?? 1);
|
|
99141
99141
|
return 1;
|
|
99142
99142
|
}
|
|
99143
|
+
function stdioAgen(stdio, platform) {
|
|
99144
|
+
const keluaran = stdio === "inherit" && platform === "win32" ? "pipe" : stdio;
|
|
99145
|
+
return ["ignore", keluaran, keluaran, "ipc"];
|
|
99146
|
+
}
|
|
99143
99147
|
var UtilityProcess = class extends import_node_events6.EventEmitter {
|
|
99144
99148
|
anak;
|
|
99145
99149
|
constructor(modul3, args, opsi2) {
|
|
99146
99150
|
super();
|
|
99147
99151
|
const stdio = typeof opsi2.stdio === "string" ? opsi2.stdio : "inherit";
|
|
99148
|
-
|
|
99152
|
+
const opsiFork = {
|
|
99149
99153
|
env: { ...opsi2.env ?? process.env, ELECTRON_RUN_AS_NODE: "1" },
|
|
99150
99154
|
execPath: process.execPath,
|
|
99151
99155
|
execArgv: opsi2.execArgv ?? [],
|
|
99152
99156
|
serialization: "advanced",
|
|
99153
|
-
|
|
99154
|
-
|
|
99157
|
+
stdio: stdioAgen(stdio, process.platform),
|
|
99158
|
+
windowsHide: true,
|
|
99155
99159
|
...opsi2.cwd !== void 0 ? { cwd: opsi2.cwd } : {}
|
|
99156
|
-
}
|
|
99160
|
+
};
|
|
99161
|
+
this.anak = (0, import_node_child_process5.fork)(petakanEntri(modul3), args, opsiFork);
|
|
99162
|
+
if (stdio === "inherit") {
|
|
99163
|
+
this.anak.stdout?.pipe(process.stdout);
|
|
99164
|
+
this.anak.stderr?.pipe(process.stderr);
|
|
99165
|
+
}
|
|
99157
99166
|
const pid = this.anak.pid;
|
|
99158
99167
|
if (pid !== void 0) {
|
|
99159
99168
|
catatProsesAnak({ pid, jenis: "Utility", ...opsi2.serviceName !== void 0 ? { serviceName: opsi2.serviceName } : {}, lahir: Date.now() });
|
|
@@ -159492,6 +159501,14 @@ var PenerjemahSesi = class {
|
|
|
159492
159501
|
if (this.langkah !== null && this.langkah.finish === null) this.langkah.finish = finish;
|
|
159493
159502
|
this.akhiriLangkah(this.angkaGiliran());
|
|
159494
159503
|
}
|
|
159504
|
+
/**
|
|
159505
|
+
* Proses agen sesi ini sudah tiada (CATATAN 526): `prompt.selesai` tak akan pernah tiba, karena hanya agen yang memancarkannya. Tanpa ini TUI berputar selamanya atas giliran yang sudah
|
|
159506
|
+
* mati, di semua OS. Giliran ditutup gagal; pesan berikutnya melahirkan agen baru. `turnAktif`: giliran yang prompt-nya sudah diterima agen tetapi belum sempat mulai.
|
|
159507
|
+
*/
|
|
159508
|
+
agenHilang(turnAktif) {
|
|
159509
|
+
if (this.eksekusi !== null) this.akhiriEksekusi("proses_mati");
|
|
159510
|
+
else if (turnAktif !== null) this.eksekusiSelesai(turnAktif, "proses_mati");
|
|
159511
|
+
}
|
|
159495
159512
|
eksekusiSelesai(turn, hasil2) {
|
|
159496
159513
|
if (this.eksekusi === null) {
|
|
159497
159514
|
if (this.pemula === null) return;
|
|
@@ -159716,7 +159733,7 @@ var PenerjemahSesi = class {
|
|
|
159716
159733
|
}
|
|
159717
159734
|
};
|
|
159718
159735
|
function galatHasil(hasil2) {
|
|
159719
|
-
if (hasil2 === "proses_mati") return { type: "process", message: "
|
|
159736
|
+
if (hasil2 === "proses_mati") return { type: "process", message: teksEn("galat.agen_mati") };
|
|
159720
159737
|
if (hasil2 === "terpotong") return { type: "truncated", message: "The response was cut off." };
|
|
159721
159738
|
return { type: "error", message: "The request failed." };
|
|
159722
159739
|
}
|
|
@@ -160892,6 +160909,13 @@ var PercakapanV2 = class {
|
|
|
160892
160909
|
this.d.log(`[daemon] sadapan ${frame.event.type} gagal: ${e instanceof Error ? e.message : String(e)}`);
|
|
160893
160910
|
}
|
|
160894
160911
|
}
|
|
160912
|
+
/** Relay melupakan sesi ini: proses agennya mati atau ditutup (`penerjemah.agenHilang`). Sesi yang belum pernah hidup di daemon ini tak perlu dibuat hanya untuk itu. */
|
|
160913
|
+
agenHilang(uuid3) {
|
|
160914
|
+
const s = this.sesi.get(uuid3);
|
|
160915
|
+
if (s === void 0) return;
|
|
160916
|
+
s.penerjemah.agenHilang(s.turnAktif);
|
|
160917
|
+
s.turnAktif = null;
|
|
160918
|
+
}
|
|
160895
160919
|
setelahEksekusi(s, turn, hasil2) {
|
|
160896
160920
|
s.turnSelesai.push(turn);
|
|
160897
160921
|
if (s.turnSelesai.length > MAKS_TURN_DIINGAT) s.turnSelesai.shift();
|
|
@@ -163032,9 +163056,21 @@ var Relay = class {
|
|
|
163032
163056
|
// apps/cli/src/daemon/relay-cli.ts
|
|
163033
163057
|
var RelayCli = class extends Relay {
|
|
163034
163058
|
sadap = null;
|
|
163059
|
+
saatLupa = null;
|
|
163035
163060
|
pasangSadapanPersist(f) {
|
|
163036
163061
|
this.sadap = f;
|
|
163037
163062
|
}
|
|
163063
|
+
pasangSaatLupa(f) {
|
|
163064
|
+
this.saatLupa = f;
|
|
163065
|
+
}
|
|
163066
|
+
lupakan(sesi2) {
|
|
163067
|
+
super.lupakan(sesi2);
|
|
163068
|
+
try {
|
|
163069
|
+
this.saatLupa?.(sesi2);
|
|
163070
|
+
} catch (e) {
|
|
163071
|
+
console.error("[daemon] sadapan lupakan gagal:", e instanceof Error ? e.message : e);
|
|
163072
|
+
}
|
|
163073
|
+
}
|
|
163038
163074
|
terimaFrame(frame) {
|
|
163039
163075
|
if (this.sadap !== null && frame.kind === "event" && adalahEventPersist(frame.event)) {
|
|
163040
163076
|
this.flush(frame.session_id);
|
|
@@ -163550,6 +163586,7 @@ async function utama() {
|
|
|
163550
163586
|
jurnal?.("persist", frame);
|
|
163551
163587
|
adaptor.percakapan.terimaPersist(frame);
|
|
163552
163588
|
});
|
|
163589
|
+
relay.pasangSaatLupa((sesi2) => adaptor.percakapan.agenHilang(sesi2));
|
|
163553
163590
|
const kataSandi = (0, import_node_crypto27.randomBytes)(32).toString("hex");
|
|
163554
163591
|
let server = null;
|
|
163555
163592
|
let menganggurSejak = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibecodeagent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.65",
|
|
4
4
|
"description": "VibeCode, the AI coding agent, in your terminal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -21,17 +21,17 @@
|
|
|
21
21
|
"THIRD-PARTY-NOTICES.txt"
|
|
22
22
|
],
|
|
23
23
|
"optionalDependencies": {
|
|
24
|
-
"@vibecodeagent/cli-darwin-arm64": "0.1.
|
|
25
|
-
"@vibecodeagent/cli-darwin-x64": "0.1.
|
|
26
|
-
"@vibecodeagent/cli-darwin-x64-baseline": "0.1.
|
|
27
|
-
"@vibecodeagent/cli-linux-arm64": "0.1.
|
|
28
|
-
"@vibecodeagent/cli-linux-arm64-musl": "0.1.
|
|
29
|
-
"@vibecodeagent/cli-linux-x64": "0.1.
|
|
30
|
-
"@vibecodeagent/cli-linux-x64-baseline": "0.1.
|
|
31
|
-
"@vibecodeagent/cli-linux-x64-baseline-musl": "0.1.
|
|
32
|
-
"@vibecodeagent/cli-linux-x64-musl": "0.1.
|
|
33
|
-
"@vibecodeagent/cli-windows-arm64": "0.1.
|
|
34
|
-
"@vibecodeagent/cli-windows-x64": "0.1.
|
|
35
|
-
"@vibecodeagent/cli-windows-x64-baseline": "0.1.
|
|
24
|
+
"@vibecodeagent/cli-darwin-arm64": "0.1.65",
|
|
25
|
+
"@vibecodeagent/cli-darwin-x64": "0.1.65",
|
|
26
|
+
"@vibecodeagent/cli-darwin-x64-baseline": "0.1.65",
|
|
27
|
+
"@vibecodeagent/cli-linux-arm64": "0.1.65",
|
|
28
|
+
"@vibecodeagent/cli-linux-arm64-musl": "0.1.65",
|
|
29
|
+
"@vibecodeagent/cli-linux-x64": "0.1.65",
|
|
30
|
+
"@vibecodeagent/cli-linux-x64-baseline": "0.1.65",
|
|
31
|
+
"@vibecodeagent/cli-linux-x64-baseline-musl": "0.1.65",
|
|
32
|
+
"@vibecodeagent/cli-linux-x64-musl": "0.1.65",
|
|
33
|
+
"@vibecodeagent/cli-windows-arm64": "0.1.65",
|
|
34
|
+
"@vibecodeagent/cli-windows-x64": "0.1.65",
|
|
35
|
+
"@vibecodeagent/cli-windows-x64-baseline": "0.1.65"
|
|
36
36
|
}
|
|
37
37
|
}
|