hanoman 0.1.5 → 0.1.6

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.5",
3
- "sha": "5ae0e2b",
4
- "builtAt": "2026-07-31T02:00:54.075Z"
2
+ "version": "0.1.6",
3
+ "sha": "0969f50",
4
+ "builtAt": "2026-07-31T08:27:27.058Z"
5
5
  }
package/dist/cli.js CHANGED
@@ -4359,7 +4359,7 @@ var init_enums = __esm({
4359
4359
  });
4360
4360
 
4361
4361
  // ../shared/src/entities.ts
4362
- var zProject, zBriefPayload, zQaPayload, zGoalPayload, zSpec, NOTIFY_SOUNDS, zCodex, CODEX_DEFAULTS, zSourceCommon, zScheduler, SCHEDULER_DEFAULTS, zGoal, GOAL_DEFAULTS, zConflict, CONFLICT_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4362
+ var zProject, zBriefPayload, zQaPayload, zGoalPayload, zSpec, NOTIFY_SOUNDS, zCodex, CODEX_DEFAULTS, zSourceCommon, zScheduler, SCHEDULER_DEFAULTS, zGoal, GOAL_DEFAULTS, zConflict, CONFLICT_DEFAULTS, zLeadEngine, zLead, LEAD_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4363
4363
  var init_entities = __esm({
4364
4364
  "../shared/src/entities.ts"() {
4365
4365
  "use strict";
@@ -4417,8 +4417,12 @@ var init_entities = __esm({
4417
4417
  // SPEC-407 · +goal
4418
4418
  branchFrom: external_exports.string().nullable(),
4419
4419
  // SPEC-143 · null = default project (main)
4420
- baseSha: external_exports.string().nullable()
4420
+ baseSha: external_exports.string().nullable(),
4421
4421
  // SPEC-186 · null = belum pernah ada sesi (belum dimulai)
4422
+ // SPEC-408 · ADR-0090 · stempel waktu backlog (ISO string di wire — kolom DateTime di DB).
4423
+ // `startedAt` null = belum pernah dikerjakan; ia tak pernah ditulis ulang saat sesi dilanjutkan.
4424
+ createdAt: external_exports.string(),
4425
+ startedAt: external_exports.string().nullable()
4422
4426
  });
4423
4427
  NOTIFY_SOUNDS = [
4424
4428
  "off",
@@ -4471,6 +4475,31 @@ var init_entities = __esm({
4471
4475
  effort: external_exports.string().default("xhigh")
4472
4476
  });
4473
4477
  CONFLICT_DEFAULTS = zConflict.parse({});
4478
+ zLeadEngine = external_exports.object({
4479
+ enabled: external_exports.boolean().default(false),
4480
+ agent: zAgent.default("claude"),
4481
+ model: external_exports.string().default("claude-opus-5"),
4482
+ effort: external_exports.string().default("xhigh")
4483
+ });
4484
+ zLead = external_exports.object({
4485
+ enabled: external_exports.boolean().default(false),
4486
+ // master switch (AC-30)
4487
+ paused: external_exports.boolean().default(false),
4488
+ // rem darurat global (AC-27)
4489
+ pausedProjects: external_exports.array(external_exports.string()).default([]),
4490
+ // rem per project (AC-15/US-4)
4491
+ everyMin: external_exports.number().int().min(1).max(1440).default(5),
4492
+ // denyut proaktif (OQ-2)
4493
+ timeoutSec: external_exports.number().int().min(10).max(900).default(120),
4494
+ // batas waktu satu putusan (AC-4/35)
4495
+ // AC-11 / OQ-10 · berapa jawaban otomatis berturut-turut untuk SATU sesi sebelum lead berhenti.
4496
+ maxAutoAnswers: external_exports.number().int().min(1).max(20).default(3),
4497
+ // OQ-3 · syarat objektif sebelum lead boleh mengintegrasikan ke branch utama. Default MENYALA:
4498
+ // risiko "kode masuk main tanpa mata manusia" diterima sadar, tapi syaratnya tetap terukur.
4499
+ requireGreenBeforeIntegrate: external_exports.boolean().default(true),
4500
+ engine: zLeadEngine.default({})
4501
+ });
4502
+ LEAD_DEFAULTS = zLead.parse({});
4474
4503
  zSetting = external_exports.object({
4475
4504
  model: external_exports.string().default("claude-opus-5"),
4476
4505
  effort: external_exports.string().default("xhigh"),
@@ -4497,13 +4526,17 @@ var init_entities = __esm({
4497
4526
  // SPEC-338 · ADR-0074 · model/effort codex
4498
4527
  verifyScope: zVerifyScope.default("changed"),
4499
4528
  // SPEC-376 · ADR-0080 · scope verifikasi sesi
4500
- conflict: zConflict.default(CONFLICT_DEFAULTS)
4529
+ conflict: zConflict.default(CONFLICT_DEFAULTS),
4501
4530
  // SPEC-383 · ADR-0081 · default sesi konflik rebase/merge
4531
+ lead: zLead.default(LEAD_DEFAULTS)
4532
+ // SPEC-409 · ADR-0091 · hanoman-lead (default mati)
4502
4533
  });
4503
4534
  zNotification = external_exports.object({
4504
4535
  id: external_exports.string(),
4505
- type: external_exports.enum(["done", "decision", "error", "ticket", "fail"]).default("done"),
4506
4536
  // SPEC-249 · +error; SPEC-253 · +ticket; SPEC-298 · +fail (sesi scheduler gagal/limit)
4537
+ // SPEC-409 · +lead (ADR-0091): keputusan berbobot / ragu / tindakan terkunci ditolak. MEMBERI
4538
+ // TAHU, bukan meminta izin — tak ada pekerjaan yang menunggu notifikasi ini dibaca (AC-25).
4539
+ type: external_exports.enum(["done", "decision", "error", "ticket", "fail", "lead"]).default("done"),
4507
4540
  specId: external_exports.string().nullable(),
4508
4541
  sessionId: external_exports.string().nullable(),
4509
4542
  title: external_exports.string(),
@@ -4553,7 +4586,13 @@ var init_agent = __esm({
4553
4586
  "support:read",
4554
4587
  "support:write",
4555
4588
  "notifications:read",
4556
- "notifications:write"
4589
+ "notifications:write",
4590
+ // SPEC-409 · ADR-0091 · minta putusan ke hanoman-lead + baca jejak keputusan. Domain TERSENDIRI,
4591
+ // bukan menumpang prefix baca yang sudah ada: meminta putusan adalah operasi TULIS (ia melahirkan
4592
+ // baris jejak & bisa menggerakkan sesi), dan SPEC-405 sudah membuktikan apa yang terjadi saat
4593
+ // endpoint tulis menumpang prefix status yang dipetakan tanpa melihat method (AC-5).
4594
+ "lead:read",
4595
+ "lead:write"
4557
4596
  ];
4558
4597
  zCapability = external_exports.enum(CAPABILITY_IDS);
4559
4598
  zCapabilityInfo = external_exports.object({
@@ -4587,13 +4626,77 @@ var init_agent = __esm({
4587
4626
  }
4588
4627
  });
4589
4628
 
4629
+ // ../shared/src/lead.ts
4630
+ var zLeadGate, zLeadKind, zLeadConfidence, zLeadStatus, LEAD_ACTIONS, zLeadAction, zLeadVerdict, zLeadAsk, zLeadOverride;
4631
+ var init_lead = __esm({
4632
+ "../shared/src/lead.ts"() {
4633
+ "use strict";
4634
+ init_zod();
4635
+ zLeadGate = external_exports.enum(["contract", "detected", "pulse"]);
4636
+ zLeadKind = external_exports.enum(["answer", "order", "collision", "quality", "refusal"]);
4637
+ zLeadConfidence = external_exports.enum(["tinggi", "sedang", "ragu"]);
4638
+ zLeadStatus = external_exports.enum(["berlaku", "ditimpa", "dibatalkan", "gagal"]);
4639
+ LEAD_ACTIONS = [
4640
+ "none",
4641
+ // keputusan murni jawaban; tak ada tindakan menyusul
4642
+ "answer-session",
4643
+ // ketik jawaban ke pane sesi (pintu deteksi otomatis)
4644
+ "start-session",
4645
+ // mulai sesi untuk sebuah backlog (lewat antrean scheduler)
4646
+ "stop-session",
4647
+ // hentikan sesi — worktree DIBIARKAN utuh (AC-32a)
4648
+ "resume-session",
4649
+ // lanjutkan sesi terputus (jalur ADR-0084)
4650
+ "restart-session",
4651
+ // ulangi pekerjaan dari awal
4652
+ "order-queue",
4653
+ // tata urutan antrean yang sudah ada (ADR-0072) — bukan antrean kedua
4654
+ "hold-work",
4655
+ // tunda satu pekerjaan karena tabrakan area kerja
4656
+ "push-branch",
4657
+ // dorong perubahan ke branch
4658
+ "integrate-main",
4659
+ // integrasikan ke branch utama (risiko yang diterima sadar, PRD §Risiko)
4660
+ "run-migration"
4661
+ // jalankan migration pada basis data LOKAL operator
4662
+ ];
4663
+ zLeadAction = external_exports.enum(LEAD_ACTIONS);
4664
+ zLeadVerdict = external_exports.object({
4665
+ decision: external_exports.string().min(1),
4666
+ reason: external_exports.string().min(1),
4667
+ refs: external_exports.array(external_exports.string()).default([]),
4668
+ confidence: zLeadConfidence.default("sedang"),
4669
+ // Sengaja `string`, BUKAN `zLeadAction`: tindakan di luar allowlist harus bisa MASUK supaya
4670
+ // server menolaknya secara sadar — mencatat penolakan & menotifikasi operator (AC-33). Kalau
4671
+ // enum yang menyaring di sini, permintaan "deploy ke produksi" hanya akan tampak sebagai
4672
+ // keluaran rusak, dan justru peristiwa paling layak dilaporkan itulah yang hilang dari jejak.
4673
+ action: external_exports.string().default("none"),
4674
+ /** Teks yang benar-benar diketik ke pane sesi (pintu deteksi otomatis). */
4675
+ reply: external_exports.string().default("")
4676
+ });
4677
+ zLeadAsk = external_exports.object({
4678
+ projectId: external_exports.string().min(1),
4679
+ specId: external_exports.string().nullish(),
4680
+ sessionId: external_exports.string().nullish(),
4681
+ question: external_exports.string().min(1).max(8e3),
4682
+ options: external_exports.array(external_exports.string().max(2e3)).max(20).default([]),
4683
+ context: external_exports.string().max(2e4).default("")
4684
+ });
4685
+ zLeadOverride = external_exports.object({
4686
+ answer: external_exports.string().min(1).max(8e3),
4687
+ reason: external_exports.string().max(8e3).default("")
4688
+ });
4689
+ }
4690
+ });
4691
+
4590
4692
  // ../shared/src/dto.ts
4591
- var zIssueDeviceToken, zSessionResult, zSessionHistory, zCreateProject, zProjectId, zRenameProject, zCreateLink, zUpdateProject, zCreateSpec, zPatchSpec, zIntegrate, zSessionSummary, zProjectView, zSchedulerQueueItem, zSchedulerSourceView, zSchedulerSessionView, zSchedulerState, zFlow, zPrdBrief, zPrdDoc, zBreakdownItem, zBreakdownDoc, zBatchCreateSpec, zEscalationTarget, zEscalationPrefill, zAuditEscalation, zAuditEscalationView, zTerminalSession, zDocFileContent, zDocIndexCat, zDocIndex, HOST_RE, USER_RE, zCreateVps, zPatchVps, zLogin, zSignup, zChangePassword, zVpsCheck, zMarkNa, zMarkNaBulk, zAttest, zRemediate, UPDATE_RESTART_EXIT, zUpdateApplyBody, zStackFrame, zSymbolicatedFrame, zSourceMapUpload, zIngestPayload, zErrorGroupView, zErrorEventView, zErrorGroupDetail, zIngestKeyView, zTicketView, zTicketAttachmentView, zTicketDetail, zTicketEditInput, zHelpInfo, zPublicTicketStatus;
4693
+ var zIssueDeviceToken, zSessionResult, zSessionHistory, zCreateProject, zProjectId, zRenameProject, zCreateLink, zUpdateProject, zCreateSpec, zPatchSpec, zIntegrate, zSessionSummary, zProjectView, zSchedulerQueueItem, zSchedulerSourceView, zSchedulerSessionView, zSchedulerState, zLeadDecisionView, zLeadAnswer, zLeadProjectStatus, zLeadStatusView, zFlow, zPrdBrief, zPrdDoc, zBreakdownItem, zBreakdownDoc, zBatchCreateSpec, zEscalationTarget, zEscalationPrefill, zAuditEscalation, zAuditEscalationView, zTerminalSession, zDocFileContent, zDocIndexCat, zDocIndex, HOST_RE, USER_RE, zCreateVps, zPatchVps, zLogin, zSignup, zChangePassword, zVpsCheck, zMarkNa, zMarkNaBulk, zAttest, zRemediate, UPDATE_RESTART_EXIT, zUpdateApplyBody, zStackFrame, zSymbolicatedFrame, zSourceMapUpload, zIngestPayload, zErrorGroupView, zErrorEventView, zErrorGroupDetail, zIngestKeyView, zTicketView, zTicketAttachmentView, zTicketDetail, zTicketEditInput, zHelpInfo, zPublicTicketStatus;
4592
4694
  var init_dto = __esm({
4593
4695
  "../shared/src/dto.ts"() {
4594
4696
  "use strict";
4595
4697
  init_zod();
4596
4698
  init_entities();
4699
+ init_lead();
4597
4700
  init_enums();
4598
4701
  zIssueDeviceToken = external_exports.object({ name: external_exports.string().min(1) });
4599
4702
  zSessionResult = external_exports.object({
@@ -4649,8 +4752,10 @@ var init_dto = __esm({
4649
4752
  // SPEC-213 · set git remote resmi project
4650
4753
  repoDir: external_exports.string().nullable().optional(),
4651
4754
  // SPEC-217 · path default/server editable (null = kosongkan)
4652
- schedulerOptIn: external_exports.boolean().optional()
4755
+ schedulerOptIn: external_exports.boolean().optional(),
4653
4756
  // SPEC-294 · opt-in scheduler otonom (lokal, tak disync)
4757
+ leadOptIn: external_exports.boolean().optional()
4758
+ // SPEC-409 · ADR-0091 · opt-in hanoman-lead (lokal, tak disync)
4654
4759
  });
4655
4760
  zCreateSpec = external_exports.object({
4656
4761
  project: external_exports.string(),
@@ -4698,7 +4803,9 @@ var init_dto = __esm({
4698
4803
  // SPEC-249 · hint prefix DSN (bukan hash/rahasia)
4699
4804
  helpEnabled: external_exports.boolean().default(false),
4700
4805
  // SPEC-253 · Help Center publik aktif
4701
- schedulerOptIn: external_exports.boolean().default(false)
4806
+ schedulerOptIn: external_exports.boolean().default(false),
4807
+ // SPEC-294 · opt-in scheduler otonom
4808
+ leadOptIn: external_exports.boolean().default(false)
4702
4809
  });
4703
4810
  zSchedulerQueueItem = external_exports.object({
4704
4811
  id: external_exports.string(),
@@ -4738,6 +4845,50 @@ var init_dto = __esm({
4738
4845
  queue: external_exports.array(zSchedulerQueueItem),
4739
4846
  sessions: external_exports.array(zSchedulerSessionView)
4740
4847
  });
4848
+ zLeadDecisionView = external_exports.object({
4849
+ id: external_exports.string(),
4850
+ projectId: external_exports.string(),
4851
+ specId: external_exports.string().nullable(),
4852
+ sessionId: external_exports.string().nullable(),
4853
+ gate: zLeadGate,
4854
+ kind: zLeadKind,
4855
+ question: external_exports.string(),
4856
+ answer: external_exports.string(),
4857
+ reason: external_exports.string(),
4858
+ refs: external_exports.array(external_exports.string()),
4859
+ confidence: zLeadConfidence,
4860
+ action: zLeadAction,
4861
+ status: zLeadStatus,
4862
+ weighty: external_exports.boolean(),
4863
+ supersededById: external_exports.string().nullable(),
4864
+ createdAt: external_exports.string()
4865
+ });
4866
+ zLeadAnswer = external_exports.object({
4867
+ id: external_exports.string(),
4868
+ decision: external_exports.string(),
4869
+ reason: external_exports.string(),
4870
+ refs: external_exports.array(external_exports.string()),
4871
+ confidence: zLeadConfidence,
4872
+ action: zLeadAction
4873
+ });
4874
+ zLeadProjectStatus = external_exports.object({
4875
+ projectId: external_exports.string(),
4876
+ name: external_exports.string(),
4877
+ optIn: external_exports.boolean(),
4878
+ paused: external_exports.boolean(),
4879
+ decisions24h: external_exports.number(),
4880
+ openSessions: external_exports.number()
4881
+ });
4882
+ zLeadStatusView = external_exports.object({
4883
+ config: zLead,
4884
+ projects: external_exports.array(zLeadProjectStatus),
4885
+ queue: external_exports.array(zSchedulerQueueItem),
4886
+ deciding: external_exports.array(external_exports.string()),
4887
+ // id sesi yang sedang disusun keputusannya (AC-3)
4888
+ waiting: external_exports.array(external_exports.string()),
4889
+ // id sesi ber-marker keputusan terisi
4890
+ lastPulseAt: external_exports.string().nullable()
4891
+ });
4741
4892
  zFlow = external_exports.enum(["feature", "qa", "scaffold", "reverse", "prd", "audit", "breakdown", "cross-audit", "goal"]);
4742
4893
  zPrdBrief = external_exports.object({
4743
4894
  title: external_exports.string().min(1),
@@ -5128,6 +5279,12 @@ var init_api = __esm({
5128
5279
  // SPEC-299 · panel scheduler (daun #6) — konsumen read-only fondasi SPEC-294/ADR-0072.
5129
5280
  schedulerConfig: `${API}/scheduler/config`,
5130
5281
  schedulerState: `${API}/scheduler/state`,
5282
+ // SPEC-409 · ADR-0091 · hanoman-lead. Semua HTTP (polling) — tak ada kanal WS baru (AC-26).
5283
+ leadConfig: `${API}/lead/config`,
5284
+ leadStatus: `${API}/lead/status`,
5285
+ leadDecisions: `${API}/lead/decisions`,
5286
+ leadDecisionOverride: (id) => `${API}/lead/decisions/${encodeURIComponent(id)}/override`,
5287
+ leadDecisionCancel: (id) => `${API}/lead/decisions/${encodeURIComponent(id)}/cancel`,
5131
5288
  // SPEC-268 · ADR-0066 · pemicu sync manual (cookie-authed)
5132
5289
  syncNow: `${API}/sync/now`,
5133
5290
  // SPEC-270 · ADR-0067 · antrean konflik rekonsil (cookie-authed)
@@ -5416,6 +5573,7 @@ var init_src2 = __esm({
5416
5573
  init_enums();
5417
5574
  init_entities();
5418
5575
  init_agent();
5576
+ init_lead();
5419
5577
  init_dto();
5420
5578
  init_api();
5421
5579
  init_coverage();
@@ -6067,6 +6225,7 @@ var init_migrate_pg = __esm({
6067
6225
  "SyncConflict",
6068
6226
  "SchedulerQueueItem",
6069
6227
  "RuntimeConfig",
6228
+ "LeadDecision",
6070
6229
  "ErrorGroup",
6071
6230
  "ErrorEvent",
6072
6231
  "SourceMapArtifact",