hanoman 0.6.0 → 0.8.0

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.
Files changed (36) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/cli.js +85 -22
  3. package/dist/server.js +4047 -1505
  4. package/docs/agent-integration.md +5 -0
  5. package/package.json +1 -1
  6. package/web/assets/ChangelogScreen-_gDN94cU.js +1 -0
  7. package/web/assets/DalangHanomanScreen-DYgYsjHL.js +1 -0
  8. package/web/assets/{DocPreviewModal-BTwj2rmX.js → DocPreviewModal-BmiV6G97.js} +1 -1
  9. package/web/assets/DocsWorkspace-B235YOee.js +3 -0
  10. package/web/assets/IdeScreen-CKtV6kQg.js +2 -0
  11. package/web/assets/LeadScreen-CCbmOwDK.js +1 -0
  12. package/web/assets/ReviewScreen-Cjn2UblA.js +1 -0
  13. package/web/assets/SchedulerScreen-CgWbTZRW.js +1 -0
  14. package/web/assets/{SettingsScreen-D1Fop_V6.js → SettingsScreen-CgKsiBYb.js} +8 -8
  15. package/web/assets/TeamScreen-BQaDdG1N.js +1 -0
  16. package/web/assets/TerminalScreen-XuGax_Pi.js +2 -0
  17. package/web/assets/TriageScreen-Dwb-RSdX.js +1 -0
  18. package/web/assets/VpsScreen-B98EElUN.js +2 -0
  19. package/web/assets/index-B5A1QnO4.js +1005 -0
  20. package/web/assets/{index-NgKosv8R.css → index-ezlZRsLF.css} +32 -1
  21. package/web/assets/{live-BlNZnTbo.js → live-DanRrGMa.js} +1 -1
  22. package/web/index.html +3 -2
  23. package/web/assets/ChangelogScreen-DVMpzy2Y.js +0 -1
  24. package/web/assets/DalangHanomanScreen-aY89PmaJ.js +0 -1
  25. package/web/assets/DocsWorkspace-CgM5rgcr.js +0 -3
  26. package/web/assets/IdeScreen-B7oDlNQ0.js +0 -2
  27. package/web/assets/LeadScreen-BzNU_kBC.js +0 -1
  28. package/web/assets/ReviewScreen-Dk0Zy4jJ.js +0 -1
  29. package/web/assets/SchedulerScreen-CxYqEqnw.js +0 -1
  30. package/web/assets/TeamScreen-DwtrDuZG.js +0 -1
  31. package/web/assets/TerminalScreen-6GBZ9nXN.css +0 -32
  32. package/web/assets/TerminalScreen-CViC7rot.js +0 -9
  33. package/web/assets/TriageScreen-DjCXx0F4.js +0 -1
  34. package/web/assets/VpsScreen-C2WoJQ_j.js +0 -2
  35. package/web/assets/diff-view-Bep86yt6.js +0 -2
  36. package/web/assets/index-Bd9gXx1g.js +0 -923
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.0",
3
- "sha": "61bc006c",
4
- "builtAt": "2026-09-17T03:44:44.300Z"
2
+ "version": "0.8.0",
3
+ "sha": "e207f1bf",
4
+ "builtAt": "2026-09-20T02:51:11.990Z"
5
5
  }
package/dist/cli.js CHANGED
@@ -4506,7 +4506,7 @@ var init_relay = __esm({
4506
4506
  });
4507
4507
 
4508
4508
  // ../shared/src/logs.ts
4509
- var LOG_LANES, zLogLane, LOG_LEVELS, zLogLevel, LOG_MSG_MAX_BYTES, LOG_DATA_MAX_BYTES, LOG_SHIPPING_DEFAULTS, zLogShipping, LOG_RETENTION_DEFAULTS, days, zLogRetention;
4509
+ var LOG_LANES, zLogLane, LOG_LEVELS, zLogLevel, LOG_MSG_MAX_BYTES, LOG_DATA_MAX_BYTES, LOG_SHIPPING_DEFAULTS, zLogShipping, LOG_RETENTION_DEFAULTS, days, zLogRetention, LOG_BATCH_MAX_ENTRIES, LOG_BODY_MAX_BYTES, LOG_DECODED_MAX_BYTES, LOG_TRANSCRIPT_MAX_BYTES, LOG_SPOOL_MAX_BYTES, LOG_SPOOL_SEGMENT_BYTES, LOG_SEARCH_MAX_RANGE_DAYS, LOG_SEARCH_MAX_LIMIT, LOG_UNSUPPORTED_RETRY_MS, zLogWireEntry, zLogBatch, zLogSearchQuery;
4510
4510
  var init_logs = __esm({
4511
4511
  "../shared/src/logs.ts"() {
4512
4512
  "use strict";
@@ -4531,6 +4531,47 @@ var init_logs = __esm({
4531
4531
  transcriptDays: days(30),
4532
4532
  maxBytes: external_exports.number().int().min(16 * 1024 ** 2).max(4 * 1024 ** 3).default(256 * 1024 ** 2)
4533
4533
  });
4534
+ LOG_BATCH_MAX_ENTRIES = 500;
4535
+ LOG_BODY_MAX_BYTES = 1 * 1024 * 1024;
4536
+ LOG_DECODED_MAX_BYTES = 2 * 1024 * 1024;
4537
+ LOG_TRANSCRIPT_MAX_BYTES = 1 * 1024 * 1024;
4538
+ LOG_SPOOL_MAX_BYTES = 64 * 1024 * 1024;
4539
+ LOG_SPOOL_SEGMENT_BYTES = 1 * 1024 * 1024;
4540
+ LOG_SEARCH_MAX_RANGE_DAYS = 31;
4541
+ LOG_SEARCH_MAX_LIMIT = 200;
4542
+ LOG_UNSUPPORTED_RETRY_MS = 30 * 6e4;
4543
+ zLogWireEntry = external_exports.object({
4544
+ seq: external_exports.string().regex(/^\d+$/),
4545
+ ts: external_exports.string().datetime(),
4546
+ level: zLogLevel,
4547
+ kind: external_exports.string().min(1).max(64),
4548
+ projectId: external_exports.string().nullish(),
4549
+ specId: external_exports.string().nullish(),
4550
+ sessionId: external_exports.string().nullish(),
4551
+ msg: external_exports.string().max(LOG_MSG_MAX_BYTES),
4552
+ data: external_exports.record(external_exports.unknown()).nullish(),
4553
+ transcript: external_exports.string().max(LOG_TRANSCRIPT_MAX_BYTES).nullish()
4554
+ }).strict();
4555
+ zLogBatch = external_exports.object({
4556
+ lane: zLogLane,
4557
+ entries: external_exports.array(zLogWireEntry).min(1).max(LOG_BATCH_MAX_ENTRIES)
4558
+ }).strict();
4559
+ zLogSearchQuery = external_exports.object({
4560
+ from: external_exports.string().datetime(),
4561
+ to: external_exports.string().datetime(),
4562
+ deviceId: external_exports.string().optional(),
4563
+ projectId: external_exports.string().optional(),
4564
+ specId: external_exports.string().optional(),
4565
+ lane: external_exports.string().optional(),
4566
+ level: zLogLevel.optional(),
4567
+ kind: external_exports.string().optional(),
4568
+ q: external_exports.string().max(200).optional(),
4569
+ cursor: external_exports.string().optional(),
4570
+ limit: external_exports.coerce.number().int().min(1).max(LOG_SEARCH_MAX_LIMIT).default(LOG_SEARCH_MAX_LIMIT)
4571
+ }).strict().refine((v) => Date.parse(v.to) >= Date.parse(v.from), { message: "to < from" }).refine(
4572
+ (v) => Date.parse(v.to) - Date.parse(v.from) <= LOG_SEARCH_MAX_RANGE_DAYS * 864e5,
4573
+ { message: `rentang > ${LOG_SEARCH_MAX_RANGE_DAYS} hari` }
4574
+ );
4534
4575
  }
4535
4576
  });
4536
4577
 
@@ -4727,7 +4768,7 @@ function cmpVersion(a, b) {
4727
4768
  }
4728
4769
  return 0;
4729
4770
  }
4730
- var zProject, zBriefPayload, zQaPayload, zGoalPayload, zSpecBlocker, zSourceChange, zManualDone, zSpec, NOTIFY_SOUNDS, zCodex, CODEX_DEFAULTS, zSourceCommon, zScheduler, SCHEDULER_DEFAULTS, zGoal, GOAL_DEFAULTS, zConflict, CONFLICT_DEFAULTS, CHANGELOG_ENGINE_DEFAULTS, zLeadEngine, zLead, LEAD_DEFAULTS, zPortalChat, PORTAL_CHAT_DEFAULTS, zPhaseCell, zPhaseOverride, zPhaseOverrides, zFlowOrchestration, zOrchestration, ORCHESTRATION_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4771
+ var zProject, zBriefPayload, zQaPayload, zGoalPayload, zSpecBlocker, zSourceChange, zManualDone, zSpec, zSpecListItem, zSpecSlim, NOTIFY_SOUNDS, zCodex, CODEX_DEFAULTS, zSourceCommon, zScheduler, SCHEDULER_DEFAULTS, zGoal, GOAL_DEFAULTS, zConflict, CONFLICT_DEFAULTS, CHANGELOG_ENGINE_DEFAULTS, zLeadEngine, zLead, LEAD_DEFAULTS, zPortalChat, PORTAL_CHAT_DEFAULTS, zPhaseCell, zPhaseOverride, zPhaseOverrides, zFlowOrchestration, zOrchestration, ORCHESTRATION_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4731
4772
  var init_entities = __esm({
4732
4773
  "../shared/src/entities.ts"() {
4733
4774
  "use strict";
@@ -4833,6 +4874,11 @@ var init_entities = __esm({
4833
4874
  // sesi atau belum selesai. `.nullable().default(null)` menjaga respons/klien versi lama parse.
4834
4875
  manualDone: zManualDone.nullable().default(null)
4835
4876
  });
4877
+ zSpecListItem = zSpec.omit({ payload: true, sourceHistory: true }).extend({
4878
+ version: external_exports.number().optional(),
4879
+ updatedAt: external_exports.string().optional()
4880
+ });
4881
+ zSpecSlim = zSpecListItem.omit({ objective: true });
4836
4882
  NOTIFY_SOUNDS = [
4837
4883
  "off",
4838
4884
  "short",
@@ -5259,7 +5305,7 @@ var init_builtin_app_agents = __esm({
5259
5305
  "use strict";
5260
5306
  LEAF_HANDOFF = [
5261
5307
  "Kamu agen daun: jangan mendelegasikan atau memanggil agen lain; eskalasi hanya ke parent.",
5262
- "Awali laporan dengan Status: selesai | sebagian | terhalang. Sertakan simpulan, jangkar bukti,",
5308
+ "Awali laporan dengan Status: selesai | sebagian | terhalang | menunggu-keputusan. Sertakan simpulan, jangkar bukti,",
5263
5309
  "tingkat keyakinan, scope yang belum diperiksa dan langkah berikutnya. Maksimal 12 temuan utama",
5264
5310
  "dan 1200 kata; jangan mengklaim selesai bila acceptance penting belum terverifikasi."
5265
5311
  ];
@@ -6542,7 +6588,10 @@ var init_dto = __esm({
6542
6588
  method: external_exports.string().optional(),
6543
6589
  // SPEC-447 · ADR-0093 — lewati gerbang dependency. Hanya jalur manusia; UI hanya
6544
6590
  // mengirimkannya sesudah operator melihat daftar pemblokirnya.
6545
- force: external_exports.boolean().optional()
6591
+ force: external_exports.boolean().optional(),
6592
+ // SPEC-1216 · ADR-0165 §6 — lewati gerbang presence satu-sesi (confirm-required). Hanya
6593
+ // jalur manusia; UI hanya mengirimkannya sesudah operator melihat dialog konfirmasi.
6594
+ confirmRemote: external_exports.boolean().optional()
6546
6595
  })
6547
6596
  ]);
6548
6597
  zDocFileContent = external_exports.object({ content: external_exports.string() });
@@ -6967,6 +7016,10 @@ var init_api = __esm({
6967
7016
  deviceToken: (id) => `${API}/device-tokens/${id}`,
6968
7017
  // SPEC-1215 · ADR-0165 · grant kendali jarak jauh mesin ini (cookie-only)
6969
7018
  remoteControl: `${API}/remote-control`,
7019
+ // SPEC-1217 · ADR-0166 · log terpusat — pencarian, transkrip remote, retensi.
7020
+ logs: `${API}/logs`,
7021
+ logTranscript: (id) => `${API}/logs/${id}/transcript`,
7022
+ logRetention: `${API}/logs/retention`,
6970
7023
  sessionResults: (projectId) => `${API}/session-results${projectId ? `?projectId=${encodeURIComponent(projectId)}` : ""}`,
6971
7024
  // SPEC-215 · config runtime
6972
7025
  config: `${API}/config`,
@@ -8422,17 +8475,12 @@ var init_backlog = __esm({
8422
8475
  inputSchema: obj({ properties: { spec: str(ID_HINT) }, required: ["spec"] }),
8423
8476
  mode: "read",
8424
8477
  capability: "backlog:read",
8425
- samplePath: "/specs",
8478
+ samplePath: "/specs/SPEC-1",
8426
8479
  sampleMethod: "GET",
8427
- build: (a) => ({ method: "GET", path: "/specs", query: { q: String(a.spec), limit: "100" } }),
8428
- // REST tak punya `GET /specs/:id`; `q` adalah SUBSTRING, jadi `SPEC-48` mengembalikan
8429
- // SPEC-480…489. Pencocokan persis dilakukan di sini, bukan dipercayakan ke server.
8430
- shape: (raw, a) => {
8431
- const want = String(a.spec).trim().toLowerCase();
8432
- const items = raw?.items ?? [];
8433
- const hit = items.find((i) => String(i.id).toLowerCase() === want);
8434
- return hit ? shapeSpecDetail(hit) : { error: `backlog "${String(a.spec)}" tidak ada. Cek ejaannya (bentuknya SPEC-nnn) atau cari dengan hanoman_backlog_search.` };
8435
- }
8480
+ // SPEC-1267 · `GET /specs` tak lagi membawa `payload`/`sourceHistory`, jadi isi penuh HANYA ada di
8481
+ // `GET /specs/:id`. Pencocokan id persis kini urusan server (404 bila tak ada).
8482
+ build: (a) => ({ method: "GET", path: `/specs/${enc(String(a.spec).trim())}` }),
8483
+ shape: (raw) => shapeSpecDetail(raw)
8436
8484
  },
8437
8485
  {
8438
8486
  name: "hanoman_backlog_docs_list",
@@ -11760,6 +11808,13 @@ var init_presence = __esm({
11760
11808
  }
11761
11809
  });
11762
11810
 
11811
+ // ../shared/src/redact.ts
11812
+ var init_redact = __esm({
11813
+ "../shared/src/redact.ts"() {
11814
+ "use strict";
11815
+ }
11816
+ });
11817
+
11763
11818
  // ../shared/src/pending.ts
11764
11819
  var init_pending = __esm({
11765
11820
  "../shared/src/pending.ts"() {
@@ -11820,6 +11875,7 @@ var init_src = __esm({
11820
11875
  init_presence();
11821
11876
  init_relay();
11822
11877
  init_logs();
11878
+ init_redact();
11823
11879
  init_pending();
11824
11880
  init_team();
11825
11881
  init_model_catalog();
@@ -11901,7 +11957,7 @@ var init_goal_spec = __esm({
11901
11957
  });
11902
11958
 
11903
11959
  // ../runner/src/prompt.ts
11904
- var ESCALATION_CONTRACT, PROJECT_METHOD, REVERSE_PHASE_GUIDE, SCAFFOLD_PHASE_GUIDE;
11960
+ var DECIDER, ASK_ROUTE, AMBIGUOUS, AUTONOMY_CLAUSE, AUTONOMY_CLAUSE_FULL, ESCALATION_CONTRACT, PROJECT_METHOD, REVERSE_PHASE_GUIDE, SCAFFOLD_PHASE_GUIDE;
11905
11961
  var init_prompt = __esm({
11906
11962
  "../runner/src/prompt.ts"() {
11907
11963
  "use strict";
@@ -11910,6 +11966,11 @@ var init_prompt = __esm({
11910
11966
  init_verify_scope();
11911
11967
  init_code_style();
11912
11968
  init_goal_spec();
11969
+ DECIDER = "hanoman-lead bila aktif untuk project ini, selain itu manusia";
11970
+ ASK_ROUTE = `ajukan lewat AskUserQuestion bila agenmu punya tool itu (paling banyak 4 pertanyaan per panggilan \u2014 pecah sisanya ke panggilan berikutnya); bila tidak, tanyakan di terminal ini sekaligus, tiap pertanyaan bernomor dan diakhiri \`?\` beserta opsinya, lalu tunggu jawabannya. Tak ada batas jumlah pertanyaan: selama masih ambigu dan akan mempengaruhi hasil, tanyakan. Yang menjawab ditentukan hanoman \u2014 ${DECIDER}; jangan menjawabnya sendiri.`;
11971
+ AMBIGUOUS = "hal yang masih ambigu dan akan mempengaruhi hasil (data model, kontrak API, scope, perilaku yang terlihat pengguna, atau asumsi yang terpaksa kamu ambil agar bisa lanjut)";
11972
+ AUTONOMY_CLAUSE = `Jalankan seluruh pipeline sampai tuntas tanpa berhenti di batas antar-fase. Checkpoint "review"/"approval"/"need review" milik skill superpowers BUKAN titik berhenti di sini \u2014 lanjut saja ke fase berikutnya. Berhenti HANYA untuk ${AMBIGUOUS}: JANGAN memutuskannya sendiri, ${ASK_ROUTE} Selain itu, terus lanjut.`;
11973
+ AUTONOMY_CLAUSE_FULL = `Kamu diluncurkan scheduler \u2014 mungkin tak ada manusia yang sedang menonton terminal ini. Tembus seluruh pipeline sampai stage \`done\`, lalu commit & push: checkpoint "review"/"approval" milik skill BUKAN titik berhenti dan jangan menunggu persetujuan siapa pun. Tetapi JANGAN memutuskan sendiri ${AMBIGUOUS}: ${ASK_ROUTE} Catat keputusan penting di pesan commit. Merge ke branch utama tetap dilakukan manusia, bukan kamu.`;
11913
11974
  ESCALATION_CONTRACT = [
11914
11975
  "REKOMENDASI ESKALASI (wajib, terbaca mesin). Di bagian akhir dokumen audit, tulis bagian",
11915
11976
  "`## Rekomendasi eskalasi` berisi penjelasan singkat untuk manusia, LALU tepat SATU blok ```json",
@@ -12016,6 +12077,7 @@ var init_custom_agents = __esm({
12016
12077
  "use strict";
12017
12078
  init_src();
12018
12079
  init_code_style();
12080
+ init_prompt();
12019
12081
  }
12020
12082
  });
12021
12083
 
@@ -12082,13 +12144,14 @@ var init_agent_definition = __esm({
12082
12144
  });
12083
12145
 
12084
12146
  // ../runner/src/phase-agents.ts
12085
- var PHASE_AGENT_RULES, PHASE_AGENT_REPORT;
12147
+ var PHASE_AGENT_AUTONOMY, PHASE_AGENT_RULES, PHASE_AGENT_REPORT;
12086
12148
  var init_phase_agents = __esm({
12087
12149
  "../runner/src/phase-agents.ts"() {
12088
12150
  "use strict";
12089
12151
  init_src();
12090
12152
  init_prompt();
12091
12153
  init_reverse_standard();
12154
+ PHASE_AGENT_AUTONOMY = `Kamu dipanggil orchestrator sesi hanoman, bukan manusia. Checkpoint "review"/"approval" milik skill BUKAN titik berhenti. Tetapi kamu TIDAK BOLEH memutuskan sendiri hal yang masih ambigu dan akan mempengaruhi hasil \u2014 percabangan data model, kontrak API, scope, perilaku yang terlihat pengguna, atau asumsi yang terpaksa kamu ambil agar bisa lanjut \u2014 dan kamu tak bisa bertanya langsung. Daftarkan SEMUANYA di bagian \`Keputusan terbuka:\` laporanmu (tanpa batas jumlah; tiap butir berupa pertanyaan bernomor diakhiri \`?\` beserta opsi dan rekomendasimu), begitu juga bila panduan fase menyuruhmu bertanya ke manusia, lalu tulis \`Status: menunggu-keputusan\` dan berhenti. Jawabannya datang sebagai pesan susulan ke agen yang sama \u2014 lanjutkan dari sana; bila jawaban itu memunculkan ambiguitas baru, laporkan lagi dengan cara yang sama. Yang menjawab ditentukan hanoman \u2014 ${DECIDER}.`;
12092
12155
  PHASE_AGENT_RULES = [
12093
12156
  "Batas peran fase:",
12094
12157
  "- JANGAN menulis `$HANOMAN_PHASE_FILE` \u2014 orchestrator satu-satunya penulis marker fase.",
@@ -12098,10 +12161,10 @@ var init_phase_agents = __esm({
12098
12161
  ].join("\n");
12099
12162
  PHASE_AGENT_REPORT = [
12100
12163
  "Kontrak laporan (wajib, di akhir):",
12101
- "- Baris pertama: `Status: selesai | sebagian | terhalang`.",
12164
+ "- Baris pertama: `Status: selesai | sebagian | terhalang | menunggu-keputusan`.",
12102
12165
  "- `Artefak:` path berkas yang kamu tulis/ubah.",
12103
12166
  "- `Bukti:` perintah yang dijalankan beserta hasil yang benar-benar kamu baca.",
12104
- "- `Pertanyaan untuk manusia:` (opsional) SATU pertanyaan; bila ada, berhenti di situ.",
12167
+ "- `Keputusan terbuka:` (wajib) daftar pertanyaan, atau `-` bila tak ada. `selesai` hanya sah bila isinya `-`.",
12105
12168
  "- `Rekomendasi fase:` (opsional) mis. `jalur-cepat` sesudah Audit qa.",
12106
12169
  "Klaim tanpa bukti bukan bukti. Maksimal 1200 kata."
12107
12170
  ].join("\n");
@@ -33819,7 +33882,7 @@ function redactToken(text, token) {
33819
33882
  return out.replace(/hnm_agt_[A-Za-z0-9_-]+/g, MASK);
33820
33883
  }
33821
33884
  var MASK;
33822
- var init_redact = __esm({
33885
+ var init_redact2 = __esm({
33823
33886
  "src/mcp/redact.ts"() {
33824
33887
  "use strict";
33825
33888
  MASK = "\xABtoken disembunyikan\xBB";
@@ -33884,7 +33947,7 @@ var init_client = __esm({
33884
33947
  "src/mcp/client.ts"() {
33885
33948
  "use strict";
33886
33949
  init_errors4();
33887
- init_redact();
33950
+ init_redact2();
33888
33951
  }
33889
33952
  });
33890
33953
 
@@ -33956,7 +34019,7 @@ var init_server = __esm({
33956
34019
  "use strict";
33957
34020
  init_dist();
33958
34021
  init_src();
33959
- init_redact();
34022
+ init_redact2();
33960
34023
  }
33961
34024
  });
33962
34025
 
@@ -33997,7 +34060,7 @@ var init_mcp2 = __esm({
33997
34060
  init_config2();
33998
34061
  init_client();
33999
34062
  init_server();
34000
- init_redact();
34063
+ init_redact2();
34001
34064
  agentTokenPath = (env) => join7(resolveHome(env), "agent-token");
34002
34065
  tokenFile = (env) => {
34003
34066
  try {