hanoman 0.5.0 → 0.7.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.
Files changed (38) hide show
  1. package/README.md +2 -0
  2. package/dist/build-info.json +3 -3
  3. package/dist/cli.js +287 -38
  4. package/dist/server.js +3950 -1379
  5. package/docs/agent-integration.md +5 -0
  6. package/package.json +1 -1
  7. package/web/assets/ChangelogScreen-D6brfukI.js +1 -0
  8. package/web/assets/DalangHanomanScreen-C8GIJv8X.js +1 -0
  9. package/web/assets/{DocPreviewModal-Di28IHju.js → DocPreviewModal-4m5Afjx2.js} +1 -1
  10. package/web/assets/DocsWorkspace-8U-UYo4-.js +3 -0
  11. package/web/assets/IdeScreen-8QAVPotm.js +2 -0
  12. package/web/assets/LeadScreen-CRs2p9QY.js +1 -0
  13. package/web/assets/ReviewScreen-CBmaRAHG.js +1 -0
  14. package/web/assets/SchedulerScreen-C1dPfo1w.js +1 -0
  15. package/web/assets/SettingsScreen-rE_jbjMw.js +62 -0
  16. package/web/assets/TeamScreen-Dz0rA4Tk.js +1 -0
  17. package/web/assets/TerminalScreen-Ca7K60wq.js +2 -0
  18. package/web/assets/TriageScreen-BZQvccje.js +1 -0
  19. package/web/assets/VpsScreen-CPlPXExd.js +2 -0
  20. package/web/assets/index-C_btxEiC.js +931 -0
  21. package/web/assets/{index-NgKosv8R.css → index-ezlZRsLF.css} +32 -1
  22. package/web/assets/{live-DJzk8BTb.js → live-BWD2sDTC.js} +1 -1
  23. package/web/index.html +3 -2
  24. package/web/assets/ChangelogScreen-CqVppy70.js +0 -1
  25. package/web/assets/DalangHanomanScreen-DRFC8ZdR.js +0 -1
  26. package/web/assets/DocsWorkspace-DY0x50eq.js +0 -3
  27. package/web/assets/IdeScreen-BpSi7o5r.js +0 -2
  28. package/web/assets/LeadScreen-BRzdha5a.js +0 -1
  29. package/web/assets/ReviewScreen-D2SwZTqF.js +0 -1
  30. package/web/assets/SchedulerScreen-w6hID1yX.js +0 -1
  31. package/web/assets/SettingsScreen-DC4OFYQ-.js +0 -62
  32. package/web/assets/TeamScreen-D0W-oNAi.js +0 -1
  33. package/web/assets/TerminalScreen-6GBZ9nXN.css +0 -32
  34. package/web/assets/TerminalScreen-B2keWEDd.js +0 -9
  35. package/web/assets/TriageScreen-CmVGUNpA.js +0 -1
  36. package/web/assets/VpsScreen-BKoJ_dAB.js +0 -2
  37. package/web/assets/diff-view-B_pIZnWa.js +0 -2
  38. package/web/assets/index-C_-gADIr.js +0 -923
package/README.md CHANGED
@@ -107,6 +107,8 @@ hanoman update # npm i -g hanoman@latest --prefer-online
107
107
  ```
108
108
 
109
109
  Sesudah `hanoman update`, instance yang berjalan perlu di-restart (mis. `systemctl restart hanoman`).
110
+ Saat boot pertama sesudah install/update, Hanoman menyegarkan default model/effort bawaan dan
111
+ matriks subagent. Nilai yang pernah diedit user ditandai dan dipertahankan; tidak perlu migration SQL.
110
112
 
111
113
  ## Konfigurasi
112
114
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.5.0",
3
- "sha": "c507df84",
4
- "builtAt": "2026-09-14T23:17:43.632Z"
2
+ "version": "0.7.1",
3
+ "sha": "faa0ab35",
4
+ "builtAt": "2026-09-19T12:44:02.222Z"
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,230 @@ 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
+ );
4575
+ }
4576
+ });
4577
+
4578
+ // ../shared/src/orchestration.ts
4579
+ var ORCHESTRATION_FLOWS, FLOW_PHASES, PHASE_AGENT_PREFIX, isPhaseAgentName;
4580
+ var init_orchestration = __esm({
4581
+ "../shared/src/orchestration.ts"() {
4582
+ "use strict";
4583
+ ORCHESTRATION_FLOWS = [
4584
+ "feature",
4585
+ "qa",
4586
+ "scaffold",
4587
+ "reverse",
4588
+ "prd",
4589
+ "audit",
4590
+ "breakdown",
4591
+ "goal",
4592
+ "no_effort"
4593
+ ];
4594
+ FLOW_PHASES = {
4595
+ feature: ["Brainstorm", "Objective", "Spec", "Plan", "Execute"],
4596
+ qa: ["Audit", "Spec", "Plan", "Execute"],
4597
+ scaffold: ["Brainstorm", "Objective", "Doc index"],
4598
+ reverse: ["Scan", "Docs teknis", "Wawancara", "Konvensi & index", "Serah terima"],
4599
+ prd: ["Brainstorm", "PRD"],
4600
+ audit: ["Audit", "Laporan"],
4601
+ breakdown: ["Analisis", "Breakdown"],
4602
+ // SPEC-337 · ADR-0075 · audit lintas project: fase & stage-map identik audit-only, scope-nya
4603
+ // yang berbeda (project utama + tetangga ProjectLink).
4604
+ // SPEC-407 · ADR-0089 · backlog goal: tak ada fase perencanaan sama sekali. `Goal` = kerjakan,
4605
+ // `Verifikasi` = buktikan. Kedua nama unik lintas daftar ini — syarat peta REACHED di server,
4606
+ // yang berkunci nama fase saja.
4607
+ goal: ["Goal", "Verifikasi"],
4608
+ // SPEC-825 · ADR-0123 · task remeh: SATU fase. Nama `Kerjakan` unik lintas daftar ini — syarat
4609
+ // peta REACHED server, yang berkunci nama fase saja.
4610
+ no_effort: ["Kerjakan"]
4611
+ };
4612
+ PHASE_AGENT_PREFIX = "hanoman-fase-";
4613
+ isPhaseAgentName = (name) => name.startsWith(PHASE_AGENT_PREFIX);
4614
+ }
4615
+ });
4616
+
4617
+ // ../shared/src/runtime-defaults.ts
4618
+ var RUNTIME_DEFAULTS_VERSION, zRuntimeDefaultState, zBuiltinRuntimeDefaults, cell, flow, BUILTIN_ORCHESTRATION_DEFAULTS, seededFlows, BUILTIN_RUNTIME_DEFAULTS;
4619
+ var init_runtime_defaults = __esm({
4620
+ "../shared/src/runtime-defaults.ts"() {
4621
+ "use strict";
4622
+ init_orchestration();
4623
+ init_zod();
4624
+ RUNTIME_DEFAULTS_VERSION = "2026-09-17-v1";
4625
+ zRuntimeDefaultState = external_exports.enum(["seeded", "user"]);
4626
+ zBuiltinRuntimeDefaults = external_exports.object({
4627
+ version: external_exports.string().default(RUNTIME_DEFAULTS_VERSION),
4628
+ claude: external_exports.object({
4629
+ model: zRuntimeDefaultState.default("seeded"),
4630
+ effort: zRuntimeDefaultState.default("seeded")
4631
+ }).default({}),
4632
+ codex: external_exports.object({
4633
+ model: zRuntimeDefaultState.default("seeded"),
4634
+ effort: zRuntimeDefaultState.default("seeded")
4635
+ }).default({}),
4636
+ orchestration: external_exports.record(external_exports.string(), zRuntimeDefaultState).default({})
4637
+ });
4638
+ cell = (model, effort) => ({ model, effort });
4639
+ flow = (claude, codex, enabled = true) => ({ enabled, claude, codex });
4640
+ BUILTIN_ORCHESTRATION_DEFAULTS = {
4641
+ feature: flow(
4642
+ {
4643
+ Brainstorm: cell("claude-sonnet-5", "medium"),
4644
+ Objective: cell("claude-sonnet-5", "medium"),
4645
+ Spec: cell("claude-opus-5", "medium"),
4646
+ Plan: cell("claude-sonnet-5", "medium"),
4647
+ Execute: cell("claude-sonnet-5", "medium")
4648
+ },
4649
+ {
4650
+ Brainstorm: cell("gpt-5.6-terra", "medium"),
4651
+ Objective: cell("gpt-5.6-terra", "medium"),
4652
+ Spec: cell("gpt-5.6-sol", "medium"),
4653
+ Plan: cell("gpt-5.6-terra", "medium"),
4654
+ Execute: cell("gpt-5.6-terra", "medium")
4655
+ }
4656
+ ),
4657
+ qa: flow(
4658
+ {
4659
+ Audit: cell("claude-sonnet-5", "medium"),
4660
+ Spec: cell("claude-opus-5", "medium"),
4661
+ Plan: cell("claude-sonnet-5", "medium"),
4662
+ Execute: cell("claude-sonnet-5", "medium")
4663
+ },
4664
+ {
4665
+ Audit: cell("gpt-5.6-terra", "medium"),
4666
+ Spec: cell("gpt-5.6-sol", "medium"),
4667
+ Plan: cell("gpt-5.6-terra", "medium"),
4668
+ Execute: cell("gpt-5.6-terra", "medium")
4669
+ }
4670
+ ),
4671
+ scaffold: flow(
4672
+ {
4673
+ Brainstorm: cell("claude-sonnet-5", "medium"),
4674
+ Objective: cell("claude-sonnet-5", "medium"),
4675
+ "Doc index": cell("claude-opus-5", "medium")
4676
+ },
4677
+ {
4678
+ Brainstorm: cell("gpt-5.6-terra", "medium"),
4679
+ Objective: cell("gpt-5.6-terra", "medium"),
4680
+ "Doc index": cell("gpt-5.6-sol", "medium")
4681
+ }
4682
+ ),
4683
+ reverse: flow(
4684
+ {
4685
+ Scan: cell("claude-sonnet-5", "medium"),
4686
+ "Docs teknis": cell("claude-sonnet-5", "medium"),
4687
+ Wawancara: cell("claude-sonnet-5", "medium"),
4688
+ "Konvensi & index": cell("claude-sonnet-5", "medium"),
4689
+ "Serah terima": cell("claude-sonnet-5", "medium")
4690
+ },
4691
+ {
4692
+ Scan: cell("gpt-5.6-terra", "medium"),
4693
+ "Docs teknis": cell("gpt-5.6-terra", "medium"),
4694
+ Wawancara: cell("gpt-5.6-terra", "medium"),
4695
+ "Konvensi & index": cell("gpt-5.6-terra", "medium"),
4696
+ "Serah terima": cell("gpt-5.6-terra", "medium")
4697
+ }
4698
+ ),
4699
+ prd: flow(
4700
+ {
4701
+ Brainstorm: cell("claude-sonnet-5", "medium"),
4702
+ PRD: cell("claude-opus-5", "medium")
4703
+ },
4704
+ {
4705
+ Brainstorm: cell("gpt-5.6-terra", "medium"),
4706
+ PRD: cell("gpt-5.6-sol", "medium")
4707
+ }
4708
+ ),
4709
+ audit: flow(
4710
+ {
4711
+ Audit: cell("claude-sonnet-5", "medium"),
4712
+ Laporan: cell("claude-sonnet-5", "medium")
4713
+ },
4714
+ {
4715
+ Audit: cell("gpt-5.6-terra", "medium"),
4716
+ Laporan: cell("gpt-5.6-terra", "medium")
4717
+ }
4718
+ ),
4719
+ breakdown: flow(
4720
+ {
4721
+ Analisis: cell("claude-opus-5", "medium"),
4722
+ Breakdown: cell("claude-opus-5", "medium")
4723
+ },
4724
+ {
4725
+ Analisis: cell("gpt-5.6-sol", "medium"),
4726
+ Breakdown: cell("gpt-5.6-sol", "medium")
4727
+ }
4728
+ ),
4729
+ goal: flow(
4730
+ {
4731
+ Goal: cell("claude-sonnet-5", "medium"),
4732
+ Verifikasi: cell("claude-sonnet-5", "medium")
4733
+ },
4734
+ {
4735
+ Goal: cell("gpt-5.6-terra", "medium"),
4736
+ Verifikasi: cell("gpt-5.6-terra", "medium")
4737
+ }
4738
+ ),
4739
+ no_effort: flow(
4740
+ { Kerjakan: cell("claude-haiku-4-5", "low") },
4741
+ { Kerjakan: cell("gpt-5.6-terra", "low") },
4742
+ false
4743
+ )
4744
+ };
4745
+ seededFlows = Object.fromEntries(ORCHESTRATION_FLOWS.flatMap((flow2) => [
4746
+ [`${flow2}.enabled`, "seeded"],
4747
+ ...["claude", "codex"].flatMap((runtime) => FLOW_PHASES[flow2].flatMap((phase) => [
4748
+ [`${flow2}.${runtime}.${phase}.model`, "seeded"],
4749
+ [`${flow2}.${runtime}.${phase}.effort`, "seeded"]
4750
+ ]))
4751
+ ]));
4752
+ BUILTIN_RUNTIME_DEFAULTS = {
4753
+ version: RUNTIME_DEFAULTS_VERSION,
4754
+ claude: { model: "seeded", effort: "seeded" },
4755
+ codex: { model: "seeded", effort: "seeded" },
4756
+ orchestration: seededFlows
4757
+ };
4534
4758
  }
4535
4759
  });
4536
4760
 
@@ -4544,7 +4768,7 @@ function cmpVersion(a, b) {
4544
4768
  }
4545
4769
  return 0;
4546
4770
  }
4547
- 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, zFlowOrchestration, zOrchestration, ORCHESTRATION_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4771
+ 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;
4548
4772
  var init_entities = __esm({
4549
4773
  "../shared/src/entities.ts"() {
4550
4774
  "use strict";
@@ -4556,6 +4780,7 @@ var init_entities = __esm({
4556
4780
  init_method_catalog();
4557
4781
  init_relay();
4558
4782
  init_logs();
4783
+ init_runtime_defaults();
4559
4784
  zProject = external_exports.object({
4560
4785
  id: external_exports.string(),
4561
4786
  name: external_exports.string(),
@@ -4666,8 +4891,8 @@ var init_entities = __esm({
4666
4891
  "fanfare"
4667
4892
  ];
4668
4893
  zCodex = external_exports.object({
4669
- model: external_exports.string().default("gpt-5.6-sol"),
4670
- effort: external_exports.string().default("xhigh")
4894
+ model: external_exports.string().default("gpt-5.6-terra"),
4895
+ effort: external_exports.string().default("medium")
4671
4896
  });
4672
4897
  CODEX_DEFAULTS = zCodex.parse({});
4673
4898
  zSourceCommon = { enabled: external_exports.boolean().default(false) };
@@ -4758,6 +4983,11 @@ var init_entities = __esm({
4758
4983
  model: external_exports.string().nullable().default(null),
4759
4984
  effort: external_exports.string().nullable().default(null)
4760
4985
  });
4986
+ zPhaseOverride = external_exports.object({
4987
+ model: external_exports.string().optional(),
4988
+ effort: external_exports.string().optional()
4989
+ });
4990
+ zPhaseOverrides = external_exports.record(external_exports.string(), zPhaseOverride);
4761
4991
  zFlowOrchestration = external_exports.object({
4762
4992
  enabled: external_exports.boolean().default(true),
4763
4993
  claude: external_exports.record(external_exports.string(), zPhaseCell).default({}),
@@ -4774,10 +5004,10 @@ var init_entities = __esm({
4774
5004
  goal: zFlowOrchestration.default({}),
4775
5005
  no_effort: zFlowOrchestration.default({})
4776
5006
  });
4777
- ORCHESTRATION_DEFAULTS = zOrchestration.parse({});
5007
+ ORCHESTRATION_DEFAULTS = zOrchestration.parse(BUILTIN_ORCHESTRATION_DEFAULTS);
4778
5008
  zSetting = external_exports.object({
4779
- model: external_exports.string().default("claude-opus-5"),
4780
- effort: external_exports.string().default("xhigh"),
5009
+ model: external_exports.string().default("claude-sonnet-5"),
5010
+ effort: external_exports.string().default("medium"),
4781
5011
  autoDefault: external_exports.boolean(),
4782
5012
  autoScaffold: external_exports.boolean(),
4783
5013
  notifyFail: external_exports.boolean(),
@@ -4838,7 +5068,10 @@ var init_entities = __esm({
4838
5068
  builtinAgents: external_exports.record(external_exports.string(), external_exports.string()).default({}),
4839
5069
  // SPEC-950 · marker safety policy lokal. Terpisah dari fingerprint konten agar policy sekali
4840
5070
  // jalan tidak membuat seed memperlakukan konfigurasi operator sebagai bawaan.
4841
- builtinAgentPolicies: external_exports.record(external_exports.string(), external_exports.string()).default({})
5071
+ builtinAgentPolicies: external_exports.record(external_exports.string(), external_exports.string()).default({}),
5072
+ // Marker lokal per bagian: `seeded` boleh menerima rekomendasi baru saat update, `user` harus
5073
+ // dipertahankan. Setting tidak ikut sync, sehingga keputusan operator tetap milik mesin ini.
5074
+ builtinRuntimeDefaults: zBuiltinRuntimeDefaults.default(BUILTIN_RUNTIME_DEFAULTS)
4842
5075
  });
4843
5076
  zNotification = external_exports.object({
4844
5077
  id: external_exports.string(),
@@ -4872,16 +5105,6 @@ var init_entities = __esm({
4872
5105
  }
4873
5106
  });
4874
5107
 
4875
- // ../shared/src/orchestration.ts
4876
- var PHASE_AGENT_PREFIX, isPhaseAgentName;
4877
- var init_orchestration = __esm({
4878
- "../shared/src/orchestration.ts"() {
4879
- "use strict";
4880
- PHASE_AGENT_PREFIX = "hanoman-fase-";
4881
- isPhaseAgentName = (name) => name.startsWith(PHASE_AGENT_PREFIX);
4882
- }
4883
- });
4884
-
4885
5108
  // ../shared/src/orchestration-plan.ts
4886
5109
  function codexNativeAgentsSupported(version3) {
4887
5110
  const parsed = version3 ? /(\d+)\.(\d+)\.(\d+)/.exec(version3)?.[0] : null;
@@ -5077,7 +5300,7 @@ var init_builtin_app_agents = __esm({
5077
5300
  "use strict";
5078
5301
  LEAF_HANDOFF = [
5079
5302
  "Kamu agen daun: jangan mendelegasikan atau memanggil agen lain; eskalasi hanya ke parent.",
5080
- "Awali laporan dengan Status: selesai | sebagian | terhalang. Sertakan simpulan, jangkar bukti,",
5303
+ "Awali laporan dengan Status: selesai | sebagian | terhalang | menunggu-keputusan. Sertakan simpulan, jangkar bukti,",
5081
5304
  "tingkat keyakinan, scope yang belum diperiksa dan langkah berikutnya. Maksimal 12 temuan utama",
5082
5305
  "dan 1200 kata; jangan mengklaim selesai bila acceptance penting belum terverifikasi."
5083
5306
  ];
@@ -6347,6 +6570,9 @@ var init_dto = __esm({
6347
6570
  flow: zFlow,
6348
6571
  model: external_exports.string().optional(),
6349
6572
  effort: external_exports.string().optional(),
6573
+ // Override model/effort subagent hanya berlaku untuk sesi ini; kosong berarti memakai
6574
+ // rekomendasi bawaan atau matriks Settings pada fase tersebut.
6575
+ phaseOverrides: zPhaseOverrides.optional(),
6350
6576
  goal: external_exports.boolean().optional(),
6351
6577
  goalCondition: external_exports.string().max(4e3).optional(),
6352
6578
  agent: zAgent.optional(),
@@ -6357,7 +6583,10 @@ var init_dto = __esm({
6357
6583
  method: external_exports.string().optional(),
6358
6584
  // SPEC-447 · ADR-0093 — lewati gerbang dependency. Hanya jalur manusia; UI hanya
6359
6585
  // mengirimkannya sesudah operator melihat daftar pemblokirnya.
6360
- force: external_exports.boolean().optional()
6586
+ force: external_exports.boolean().optional(),
6587
+ // SPEC-1216 · ADR-0165 §6 — lewati gerbang presence satu-sesi (confirm-required). Hanya
6588
+ // jalur manusia; UI hanya mengirimkannya sesudah operator melihat dialog konfirmasi.
6589
+ confirmRemote: external_exports.boolean().optional()
6361
6590
  })
6362
6591
  ]);
6363
6592
  zDocFileContent = external_exports.object({ content: external_exports.string() });
@@ -6782,6 +7011,10 @@ var init_api = __esm({
6782
7011
  deviceToken: (id) => `${API}/device-tokens/${id}`,
6783
7012
  // SPEC-1215 · ADR-0165 · grant kendali jarak jauh mesin ini (cookie-only)
6784
7013
  remoteControl: `${API}/remote-control`,
7014
+ // SPEC-1217 · ADR-0166 · log terpusat — pencarian, transkrip remote, retensi.
7015
+ logs: `${API}/logs`,
7016
+ logTranscript: (id) => `${API}/logs/${id}/transcript`,
7017
+ logRetention: `${API}/logs/retention`,
6785
7018
  sessionResults: (projectId) => `${API}/session-results${projectId ? `?projectId=${encodeURIComponent(projectId)}` : ""}`,
6786
7019
  // SPEC-215 · config runtime
6787
7020
  config: `${API}/config`,
@@ -10414,9 +10647,9 @@ var init_sessions = __esm({
10414
10647
  }
10415
10648
  const project = String(a.project);
10416
10649
  if (a.shell === true) return { method: "POST", path: "/terminal/sessions", body: { project, shell: true } };
10417
- const flow = s(a.flow);
10418
- if (flow === "breakdown") return { method: "POST", path: "/terminal/sessions", body: { project, flow, prdPath: String(a.prdPath) } };
10419
- if (flow === "reverse" || flow === "scaffold") return { method: "POST", path: "/terminal/sessions", body: { project, flow } };
10650
+ const flow2 = s(a.flow);
10651
+ if (flow2 === "breakdown") return { method: "POST", path: "/terminal/sessions", body: { project, flow: flow2, prdPath: String(a.prdPath) } };
10652
+ if (flow2 === "reverse" || flow2 === "scaffold") return { method: "POST", path: "/terminal/sessions", body: { project, flow: flow2 } };
10420
10653
  const body = { project };
10421
10654
  for (const k of ["agent", "model", "effort"]) if (s(a[k]) !== void 0) body[k] = s(a[k]);
10422
10655
  return { method: "POST", path: "/terminal/sessions", body };
@@ -11575,6 +11808,13 @@ var init_presence = __esm({
11575
11808
  }
11576
11809
  });
11577
11810
 
11811
+ // ../shared/src/redact.ts
11812
+ var init_redact = __esm({
11813
+ "../shared/src/redact.ts"() {
11814
+ "use strict";
11815
+ }
11816
+ });
11817
+
11578
11818
  // ../shared/src/pending.ts
11579
11819
  var init_pending = __esm({
11580
11820
  "../shared/src/pending.ts"() {
@@ -11635,9 +11875,11 @@ var init_src = __esm({
11635
11875
  init_presence();
11636
11876
  init_relay();
11637
11877
  init_logs();
11878
+ init_redact();
11638
11879
  init_pending();
11639
11880
  init_team();
11640
11881
  init_model_catalog();
11882
+ init_runtime_defaults();
11641
11883
  }
11642
11884
  });
11643
11885
 
@@ -11715,7 +11957,7 @@ var init_goal_spec = __esm({
11715
11957
  });
11716
11958
 
11717
11959
  // ../runner/src/prompt.ts
11718
- 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;
11719
11961
  var init_prompt = __esm({
11720
11962
  "../runner/src/prompt.ts"() {
11721
11963
  "use strict";
@@ -11724,6 +11966,11 @@ var init_prompt = __esm({
11724
11966
  init_verify_scope();
11725
11967
  init_code_style();
11726
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.`;
11727
11974
  ESCALATION_CONTRACT = [
11728
11975
  "REKOMENDASI ESKALASI (wajib, terbaca mesin). Di bagian akhir dokumen audit, tulis bagian",
11729
11976
  "`## Rekomendasi eskalasi` berisi penjelasan singkat untuk manusia, LALU tepat SATU blok ```json",
@@ -11830,6 +12077,7 @@ var init_custom_agents = __esm({
11830
12077
  "use strict";
11831
12078
  init_src();
11832
12079
  init_code_style();
12080
+ init_prompt();
11833
12081
  }
11834
12082
  });
11835
12083
 
@@ -11896,13 +12144,14 @@ var init_agent_definition = __esm({
11896
12144
  });
11897
12145
 
11898
12146
  // ../runner/src/phase-agents.ts
11899
- var PHASE_AGENT_RULES, PHASE_AGENT_REPORT;
12147
+ var PHASE_AGENT_AUTONOMY, PHASE_AGENT_RULES, PHASE_AGENT_REPORT;
11900
12148
  var init_phase_agents = __esm({
11901
12149
  "../runner/src/phase-agents.ts"() {
11902
12150
  "use strict";
11903
12151
  init_src();
11904
12152
  init_prompt();
11905
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}.`;
11906
12155
  PHASE_AGENT_RULES = [
11907
12156
  "Batas peran fase:",
11908
12157
  "- JANGAN menulis `$HANOMAN_PHASE_FILE` \u2014 orchestrator satu-satunya penulis marker fase.",
@@ -11912,10 +12161,10 @@ var init_phase_agents = __esm({
11912
12161
  ].join("\n");
11913
12162
  PHASE_AGENT_REPORT = [
11914
12163
  "Kontrak laporan (wajib, di akhir):",
11915
- "- Baris pertama: `Status: selesai | sebagian | terhalang`.",
12164
+ "- Baris pertama: `Status: selesai | sebagian | terhalang | menunggu-keputusan`.",
11916
12165
  "- `Artefak:` path berkas yang kamu tulis/ubah.",
11917
12166
  "- `Bukti:` perintah yang dijalankan beserta hasil yang benar-benar kamu baca.",
11918
- "- `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 `-`.",
11919
12168
  "- `Rekomendasi fase:` (opsional) mis. `jalur-cepat` sesudah Audit qa.",
11920
12169
  "Klaim tanpa bukti bukan bukti. Maksimal 1200 kata."
11921
12170
  ].join("\n");
@@ -22103,11 +22352,11 @@ function scanXMcpHeaderDeclarations(inputSchema) {
22103
22352
  function pathName(path) {
22104
22353
  return path.length === 0 ? "<root>" : path.join(".");
22105
22354
  }
22106
- function rejection(rung, cell, httpStatus, error2, settled) {
22355
+ function rejection(rung, cell2, httpStatus, error2, settled) {
22107
22356
  return {
22108
22357
  kind: "reject",
22109
22358
  rung,
22110
- cell,
22359
+ cell: cell2,
22111
22360
  httpStatus,
22112
22361
  code: error2.code,
22113
22362
  message: error2.message,
@@ -23790,10 +24039,10 @@ var init_src_CX2iR2pK = __esm({
23790
24039
  * `Server` instances never receive `input_required` responses on their
23791
24040
  * outbound legs and leave the base behavior in place.
23792
24041
  */
23793
- _resolveNonCompleteResult(decoded, flow) {
23794
- return Promise.reject(new SdkError(SdkErrorCode.UnsupportedResultType, `Unsupported result type '${decoded.kind}' for ${flow.request.method}`, {
24042
+ _resolveNonCompleteResult(decoded, flow2) {
24043
+ return Promise.reject(new SdkError(SdkErrorCode.UnsupportedResultType, `Unsupported result type '${decoded.kind}' for ${flow2.request.method}`, {
23795
24044
  resultType: decoded.kind,
23796
- method: flow.request.method
24045
+ method: flow2.request.method
23797
24046
  }));
23798
24047
  }
23799
24048
  /**
@@ -24233,7 +24482,7 @@ var init_src_CX2iR2pK = __esm({
24233
24482
  if (decoded.kind === "invalid") return reject(decoded.error);
24234
24483
  if (decoded.kind === "input_required") {
24235
24484
  if (options?.allowInputRequired === true) return resolve5(manualInputRequiredValue(decoded));
24236
- const flow = {
24485
+ const flow2 = {
24237
24486
  codec,
24238
24487
  request,
24239
24488
  resultSchema,
@@ -24244,7 +24493,7 @@ var init_src_CX2iR2pK = __esm({
24244
24493
  params
24245
24494
  }, resultSchema, legOptions)
24246
24495
  };
24247
- return resolve5(this._resolveNonCompleteResult(decoded, flow));
24496
+ return resolve5(this._resolveNonCompleteResult(decoded, flow2));
24248
24497
  }
24249
24498
  const result = decoded.result;
24250
24499
  validateStandardSchema(resultSchema, result).then((parseResult) => {
@@ -33633,7 +33882,7 @@ function redactToken(text, token) {
33633
33882
  return out.replace(/hnm_agt_[A-Za-z0-9_-]+/g, MASK);
33634
33883
  }
33635
33884
  var MASK;
33636
- var init_redact = __esm({
33885
+ var init_redact2 = __esm({
33637
33886
  "src/mcp/redact.ts"() {
33638
33887
  "use strict";
33639
33888
  MASK = "\xABtoken disembunyikan\xBB";
@@ -33698,7 +33947,7 @@ var init_client = __esm({
33698
33947
  "src/mcp/client.ts"() {
33699
33948
  "use strict";
33700
33949
  init_errors4();
33701
- init_redact();
33950
+ init_redact2();
33702
33951
  }
33703
33952
  });
33704
33953
 
@@ -33770,7 +34019,7 @@ var init_server = __esm({
33770
34019
  "use strict";
33771
34020
  init_dist();
33772
34021
  init_src();
33773
- init_redact();
34022
+ init_redact2();
33774
34023
  }
33775
34024
  });
33776
34025
 
@@ -33811,7 +34060,7 @@ var init_mcp2 = __esm({
33811
34060
  init_config2();
33812
34061
  init_client();
33813
34062
  init_server();
33814
- init_redact();
34063
+ init_redact2();
33815
34064
  agentTokenPath = (env) => join7(resolveHome(env), "agent-token");
33816
34065
  tokenFile = (env) => {
33817
34066
  try {