hanoman 0.4.0 → 0.5.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 (26) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/cli.js +149 -1
  3. package/dist/server.js +1993 -916
  4. package/docs/agent-integration.md +4 -0
  5. package/package.json +1 -1
  6. package/prisma/migrations/20260915120000_log_terpusat/migration.sql +34 -0
  7. package/prisma/schema.prisma +39 -0
  8. package/web/assets/{ChangelogScreen-aqsJmmfe.js → ChangelogScreen-CqVppy70.js} +1 -1
  9. package/web/assets/{DalangHanomanScreen-D3rNURz7.js → DalangHanomanScreen-DRFC8ZdR.js} +1 -1
  10. package/web/assets/{DocPreviewModal-B7r_7p8N.js → DocPreviewModal-Di28IHju.js} +1 -1
  11. package/web/assets/{DocsWorkspace-_w6pncu9.js → DocsWorkspace-DY0x50eq.js} +1 -1
  12. package/web/assets/{IdeScreen-etZ2QyO-.js → IdeScreen-BpSi7o5r.js} +1 -1
  13. package/web/assets/{LeadScreen-Bo0K2-ML.js → LeadScreen-BRzdha5a.js} +1 -1
  14. package/web/assets/{ReviewScreen-lRf2FW30.js → ReviewScreen-D2SwZTqF.js} +1 -1
  15. package/web/assets/{SchedulerScreen-D75twy4J.js → SchedulerScreen-w6hID1yX.js} +1 -1
  16. package/web/assets/SettingsScreen-DC4OFYQ-.js +62 -0
  17. package/web/assets/{TeamScreen-nsttkE2J.js → TeamScreen-D0W-oNAi.js} +1 -1
  18. package/web/assets/{TerminalScreen-BG9vRE1-.js → TerminalScreen-B2keWEDd.js} +1 -1
  19. package/web/assets/{TriageScreen-7eM8gjr_.js → TriageScreen-CmVGUNpA.js} +1 -1
  20. package/web/assets/{VpsScreen-C29j52Tu.js → VpsScreen-BKoJ_dAB.js} +1 -1
  21. package/web/assets/{diff-view-RZNZ9Nz6.js → diff-view-B_pIZnWa.js} +1 -1
  22. package/web/assets/index-C_-gADIr.js +923 -0
  23. package/web/assets/{live-CniaVDeP.js → live-DJzk8BTb.js} +1 -1
  24. package/web/index.html +1 -1
  25. package/web/assets/SettingsScreen-rMIR22vv.js +0 -62
  26. package/web/assets/index-BHI_f9DD.js +0 -923
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.4.0",
3
- "sha": "67478d09",
4
- "builtAt": "2026-09-14T09:24:41.787Z"
2
+ "version": "0.5.0",
3
+ "sha": "c507df84",
4
+ "builtAt": "2026-09-14T23:17:43.632Z"
5
5
  }
package/dist/cli.js CHANGED
@@ -4412,6 +4412,128 @@ var init_auto_merge = __esm({
4412
4412
  }
4413
4413
  });
4414
4414
 
4415
+ // ../shared/src/relay.ts
4416
+ function utf8Bytes(s2) {
4417
+ let n2 = 0;
4418
+ for (let i = 0; i < s2.length; i++) {
4419
+ const cp = s2.codePointAt(i);
4420
+ n2 += cpBytes(cp);
4421
+ if (cp > 65535) i++;
4422
+ }
4423
+ return n2;
4424
+ }
4425
+ var RELAY_PART_MAX_BYTES, RELAY_RESPONSE_MAX_BYTES, RELAY_REASSEMBLY_MAX_BYTES, RELAY_REQUEST_BODY_MAX_BYTES, RELAY_CREDIT_INITIAL, RELAY_CREDIT_REFILL_BELOW, RELAY_SOCKET_MAX_BUFFERED, RELAY_UNSUPPORTED_RETRY_MS, REMOTE_CAPABILITIES, zRemoteCapability, zRemoteControl, REMOTE_CONTROL_DEFAULTS, cpBytes, zRelayActor, zId, UNSAFE_PATH, zRelayPath, zPart, RELAY_METHODS, zWelcome, zReq, zCancel, zOpen, zHubData, zCredit, zClose, zHubToClientFrame, zHello, zRes, zGeometryFields, zOpened, zGeometry, zClientData, zClientToHubFrame, zRemoteControlPut;
4426
+ var init_relay = __esm({
4427
+ "../shared/src/relay.ts"() {
4428
+ "use strict";
4429
+ init_zod();
4430
+ RELAY_PART_MAX_BYTES = 32 * 1024;
4431
+ RELAY_RESPONSE_MAX_BYTES = 1024 * 1024;
4432
+ RELAY_REASSEMBLY_MAX_BYTES = 1024 * 1024;
4433
+ RELAY_REQUEST_BODY_MAX_BYTES = 32 * 1024;
4434
+ RELAY_CREDIT_INITIAL = 256 * 1024;
4435
+ RELAY_CREDIT_REFILL_BELOW = 64 * 1024;
4436
+ RELAY_SOCKET_MAX_BUFFERED = 1024 * 1024;
4437
+ RELAY_UNSUPPORTED_RETRY_MS = 30 * 6e4;
4438
+ REMOTE_CAPABILITIES = [
4439
+ "sessions:read",
4440
+ "sessions:write",
4441
+ "sessions:spawn",
4442
+ "backlog:read",
4443
+ "backlog:write",
4444
+ "ide:read"
4445
+ ];
4446
+ zRemoteCapability = external_exports.enum(REMOTE_CAPABILITIES);
4447
+ zRemoteControl = external_exports.object({
4448
+ enabled: external_exports.boolean().default(false),
4449
+ capabilities: external_exports.array(zRemoteCapability).default([])
4450
+ });
4451
+ REMOTE_CONTROL_DEFAULTS = { enabled: false, capabilities: [] };
4452
+ cpBytes = (cp) => cp < 128 ? 1 : cp < 2048 ? 2 : cp < 65536 ? 3 : 4;
4453
+ zRelayActor = external_exports.object({
4454
+ hubOrigin: external_exports.string().min(1).max(200),
4455
+ userId: external_exports.string().min(1).max(200),
4456
+ email: external_exports.string().min(1).max(320)
4457
+ }).strict();
4458
+ zId = external_exports.string().min(1).max(64);
4459
+ UNSAFE_PATH = /(^|\/)\.\.?(\/|$)|%2e|%2f|%5c|\\|[?#]/i;
4460
+ zRelayPath = external_exports.string().max(2048).regex(/^\/api\//).refine((p3) => !UNSAFE_PATH.test(p3), "path relay tak sah");
4461
+ zPart = external_exports.string().refine((s2) => utf8Bytes(s2) <= RELAY_PART_MAX_BYTES, "part relay > 32 KiB");
4462
+ RELAY_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
4463
+ zWelcome = external_exports.object({ t: external_exports.literal("welcome"), v: external_exports.literal(1), protocol: external_exports.number().int(), version: external_exports.string().max(40) }).strict();
4464
+ zReq = external_exports.object({
4465
+ t: external_exports.literal("req"),
4466
+ id: zId,
4467
+ method: external_exports.enum(RELAY_METHODS),
4468
+ path: zRelayPath,
4469
+ query: external_exports.string().max(2048).optional(),
4470
+ body: external_exports.unknown().optional(),
4471
+ actor: zRelayActor
4472
+ }).strict();
4473
+ zCancel = external_exports.object({ t: external_exports.literal("cancel"), id: zId }).strict();
4474
+ zOpen = external_exports.object({ t: external_exports.literal("open"), sid: zId, path: zRelayPath, mode: external_exports.enum(["read", "write"]), actor: zRelayActor }).strict();
4475
+ zHubData = external_exports.object({ t: external_exports.literal("data"), sid: zId, d: zPart }).strict();
4476
+ zCredit = external_exports.object({ t: external_exports.literal("credit"), sid: zId, n: external_exports.number().int().min(1).max(4 * 1024 * 1024) }).strict();
4477
+ zClose = external_exports.object({ t: external_exports.literal("close"), sid: zId, code: external_exports.number().int().min(1e3).max(4999), reason: external_exports.string().max(120).optional() }).strict();
4478
+ zHubToClientFrame = external_exports.discriminatedUnion("t", [zWelcome, zReq, zCancel, zOpen, zHubData, zCredit, zClose]);
4479
+ zHello = external_exports.object({
4480
+ t: external_exports.literal("hello"),
4481
+ v: external_exports.literal(1),
4482
+ // Sengaja number, bukan literal: hub harus bisa MELIHAT protokol yang beda untuk menutup 4001
4483
+ // dan menampilkan "protocol-mismatch", bukan membuang frame-nya senyap.
4484
+ protocol: external_exports.number().int(),
4485
+ version: external_exports.string().max(40),
4486
+ capabilities: external_exports.array(zRemoteCapability).max(REMOTE_CAPABILITIES.length)
4487
+ }).strict();
4488
+ zRes = external_exports.object({
4489
+ t: external_exports.literal("res"),
4490
+ id: zId,
4491
+ status: external_exports.number().int().min(100).max(599).optional(),
4492
+ contentType: external_exports.string().max(200).optional(),
4493
+ part: zPart,
4494
+ end: external_exports.boolean()
4495
+ }).strict();
4496
+ zGeometryFields = { cols: external_exports.number().int().min(1).max(1e3), rows: external_exports.number().int().min(1).max(1e3) };
4497
+ zOpened = external_exports.object({ t: external_exports.literal("opened"), sid: zId, geometry: external_exports.object(zGeometryFields).strict().optional() }).strict();
4498
+ zGeometry = external_exports.object({ t: external_exports.literal("geometry"), sid: zId, ...zGeometryFields }).strict();
4499
+ zClientData = external_exports.object({ t: external_exports.literal("data"), sid: zId, d: zPart, more: external_exports.literal(true).optional() }).strict();
4500
+ zClientToHubFrame = external_exports.discriminatedUnion("t", [zHello, zRes, zOpened, zGeometry, zClientData, zClose]);
4501
+ zRemoteControlPut = external_exports.object({
4502
+ control: external_exports.object({ enabled: external_exports.boolean(), capabilities: external_exports.array(external_exports.string().max(40)).max(20) }).strict().optional(),
4503
+ logs: external_exports.object({ event: external_exports.boolean(), server: external_exports.boolean(), transcript: external_exports.boolean() }).strict().optional()
4504
+ }).strict();
4505
+ }
4506
+ });
4507
+
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;
4510
+ var init_logs = __esm({
4511
+ "../shared/src/logs.ts"() {
4512
+ "use strict";
4513
+ init_zod();
4514
+ LOG_LANES = ["event", "server", "transcript"];
4515
+ zLogLane = external_exports.enum(LOG_LANES);
4516
+ LOG_LEVELS = ["debug", "info", "warn", "error"];
4517
+ zLogLevel = external_exports.enum(LOG_LEVELS);
4518
+ LOG_MSG_MAX_BYTES = 4 * 1024;
4519
+ LOG_DATA_MAX_BYTES = 8 * 1024;
4520
+ LOG_SHIPPING_DEFAULTS = { event: true, server: false, transcript: false };
4521
+ zLogShipping = external_exports.object({
4522
+ event: external_exports.boolean().default(true),
4523
+ server: external_exports.boolean().default(false),
4524
+ transcript: external_exports.boolean().default(false)
4525
+ });
4526
+ LOG_RETENTION_DEFAULTS = { eventDays: 90, serverDays: 7, transcriptDays: 30, maxBytes: 256 * 1024 ** 2 };
4527
+ days = (d) => external_exports.number().int().min(1).max(365).default(d);
4528
+ zLogRetention = external_exports.object({
4529
+ eventDays: days(90),
4530
+ serverDays: days(7),
4531
+ transcriptDays: days(30),
4532
+ maxBytes: external_exports.number().int().min(16 * 1024 ** 2).max(4 * 1024 ** 3).default(256 * 1024 ** 2)
4533
+ });
4534
+ }
4535
+ });
4536
+
4415
4537
  // ../shared/src/entities.ts
4416
4538
  function cmpVersion(a, b) {
4417
4539
  const pa = a.split(".").map(Number);
@@ -4432,6 +4554,8 @@ var init_entities = __esm({
4432
4554
  init_agent_engine();
4433
4555
  init_auto_merge();
4434
4556
  init_method_catalog();
4557
+ init_relay();
4558
+ init_logs();
4435
4559
  zProject = external_exports.object({
4436
4560
  id: external_exports.string(),
4437
4561
  name: external_exports.string(),
@@ -4695,6 +4819,15 @@ var init_entities = __esm({
4695
4819
  // SPEC-854 · ADR-0130 · chat portal klien (opt-in, mati)
4696
4820
  orchestration: zOrchestration.default(ORCHESTRATION_DEFAULTS),
4697
4821
  // ADR-0164 · orkestrasi subagent per fase (default aktif)
4822
+ // SPEC-1215 · ADR-0165/0166 · LOCAL-only (setting tak ada di SYNCED) dan TAK ditulis `PUT /settings`
4823
+ // (routes/settings.ts mempertahankan nilai tersimpan). Pengelolanya `PUT /api/remote-control` dan,
4824
+ // kelak, `PUT /api/logs/retention` — keduanya COOKIE_ONLY.
4825
+ remoteControl: zRemoteControl.default(REMOTE_CONTROL_DEFAULTS),
4826
+ // grant kendali jarak jauh (default mati)
4827
+ logShipping: zLogShipping.default(LOG_SHIPPING_DEFAULTS),
4828
+ // lajur log ke hub (SPEC-1217)
4829
+ logRetention: zLogRetention.default(LOG_RETENTION_DEFAULTS),
4830
+ // retensi log di hub (SPEC-1217)
4698
4831
  // SPEC-881 · ADR-0136 · sidik jari isi bawaan yang TERAKHIR ditulis seed di mesin ini, per nama
4699
4832
  // agen. Dipakai seed untuk membedakan "belum pernah disunting operator" dari "sudah". WAJIB
4700
4833
  // dideklarasikan di sini: zod membuang kunci tak dikenal dan `PUT /settings` menulis balik hasil
@@ -6647,6 +6780,8 @@ var init_api = __esm({
6647
6780
  // SPEC-213 · device token + activity log
6648
6781
  deviceTokens: `${API}/device-tokens`,
6649
6782
  deviceToken: (id) => `${API}/device-tokens/${id}`,
6783
+ // SPEC-1215 · ADR-0165 · grant kendali jarak jauh mesin ini (cookie-only)
6784
+ remoteControl: `${API}/remote-control`,
6650
6785
  sessionResults: (projectId) => `${API}/session-results${projectId ? `?projectId=${encodeURIComponent(projectId)}` : ""}`,
6651
6786
  // SPEC-215 · config runtime
6652
6787
  config: `${API}/config`,
@@ -11407,11 +11542,12 @@ var init_session_ask = __esm({
11407
11542
  });
11408
11543
 
11409
11544
  // ../shared/src/presence.ts
11410
- var PRESENCE_PROTOCOL, MAX_PRESENCE_SESSIONS, PRESENCE_MAX_FRAME_BYTES, zPresenceSession, zPresenceFrame;
11545
+ var PRESENCE_PROTOCOL, MAX_PRESENCE_SESSIONS, PRESENCE_MAX_FRAME_BYTES, zPresenceSession, zPresenceFrame, zCapacityFrame;
11411
11546
  var init_presence = __esm({
11412
11547
  "../shared/src/presence.ts"() {
11413
11548
  "use strict";
11414
11549
  init_zod();
11550
+ init_session_admission();
11415
11551
  PRESENCE_PROTOCOL = 1;
11416
11552
  MAX_PRESENCE_SESSIONS = 100;
11417
11553
  PRESENCE_MAX_FRAME_BYTES = 32 * 1024;
@@ -11431,6 +11567,11 @@ var init_presence = __esm({
11431
11567
  v: external_exports.literal(PRESENCE_PROTOCOL),
11432
11568
  sessions: external_exports.array(zPresenceSession).max(MAX_PRESENCE_SESSIONS)
11433
11569
  }).strict();
11570
+ zCapacityFrame = external_exports.object({
11571
+ t: external_exports.literal("capacity"),
11572
+ v: external_exports.literal(PRESENCE_PROTOCOL),
11573
+ admission: zLaunchStatus
11574
+ }).strict();
11434
11575
  }
11435
11576
  });
11436
11577
 
@@ -11492,6 +11633,8 @@ var init_src = __esm({
11492
11633
  init_session_dialog();
11493
11634
  init_session_ask();
11494
11635
  init_presence();
11636
+ init_relay();
11637
+ init_logs();
11495
11638
  init_pending();
11496
11639
  init_team();
11497
11640
  init_model_catalog();
@@ -33955,6 +34098,11 @@ var init_migrate_pg = __esm({
33955
34098
  "SyncState",
33956
34099
  "SyncConflict",
33957
34100
  "SyncTombstone",
34101
+ // SPEC-1215 · ADR-0166 · LOCAL-only, tanpa FK. Tabel ini tak ada di sumber Postgres lama — jalur
34102
+ // 42P01 memperlakukannya sebagai nol baris (cermin AgentInvocation/Changelog). Tetap WAJIB
34103
+ // terdaftar: test migrate-pg menuntut PG_ORDER = seluruh model DMMF.
34104
+ "LogEntry",
34105
+ "LogCursor",
33958
34106
  // SPEC-485 · ADR-0102 · LeadFlow SEBELUM LeadDecision: `flowId` menunjuk ke sana. Tanpa FK, tapi
33959
34107
  // urutan tabel harus tetap mencerminkan arah tautannya bagi pembaca berikutnya.
33960
34108
  // SPEC-646 · ADR-0112 · SchedulerCron SEBELUM SchedulerCronRun: `cronId` menunjuk ke sana. Tanpa