hanoman 0.1.9 → 0.1.11

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.9",
3
- "sha": "fbea930",
4
- "builtAt": "2026-07-31T23:44:47.571Z"
2
+ "version": "0.1.11",
3
+ "sha": "2ad97cf",
4
+ "builtAt": "2026-08-01T07:44:18.428Z"
5
5
  }
package/dist/cli.js CHANGED
@@ -4281,6 +4281,105 @@ var init_enums = __esm({
4281
4281
  }
4282
4282
  });
4283
4283
 
4284
+ // ../shared/src/telegram.ts
4285
+ var zTelegramSettings, TELEGRAM_DEFAULTS, zTelegramReadiness, zTelegramGatewayStatus, zTelegramMemoryRecord, zTelegramChatContext, TELEGRAM_REPLY_KINDS, zTelegramReplyKind, zTelegramConfirmationRequest, zTelegramReplyInput, zTelegramAuditRecord, zTerminalSteerInput;
4286
+ var init_telegram = __esm({
4287
+ "../shared/src/telegram.ts"() {
4288
+ "use strict";
4289
+ init_zod();
4290
+ init_enums();
4291
+ zTelegramSettings = external_exports.object({
4292
+ enabled: external_exports.boolean().default(false),
4293
+ progress: external_exports.boolean().default(true)
4294
+ });
4295
+ TELEGRAM_DEFAULTS = zTelegramSettings.parse({});
4296
+ zTelegramReadiness = external_exports.enum([
4297
+ "disabled",
4298
+ "misconfigured",
4299
+ "ready",
4300
+ "running",
4301
+ "error"
4302
+ ]);
4303
+ zTelegramGatewayStatus = external_exports.object({
4304
+ configured: external_exports.boolean(),
4305
+ enabled: external_exports.boolean(),
4306
+ running: external_exports.boolean(),
4307
+ readiness: zTelegramReadiness,
4308
+ botUsername: external_exports.string().min(1).nullable().default(null),
4309
+ allowlistCount: external_exports.number().int().min(0),
4310
+ agentTokenConfigured: external_exports.boolean(),
4311
+ missingCapabilities: external_exports.array(external_exports.string()).default([]),
4312
+ lastUpdateAt: external_exports.string().datetime().nullable().default(null),
4313
+ lastError: external_exports.string().nullable().default(null)
4314
+ });
4315
+ zTelegramMemoryRecord = external_exports.object({
4316
+ id: external_exports.string().min(1),
4317
+ chatId: external_exports.string().min(1),
4318
+ content: external_exports.string().trim().min(1).max(1e3),
4319
+ createdAt: external_exports.string().datetime(),
4320
+ updatedAt: external_exports.string().datetime()
4321
+ });
4322
+ zTelegramChatContext = external_exports.object({
4323
+ chatId: external_exports.string().min(1),
4324
+ userId: external_exports.string().min(1),
4325
+ sessionId: external_exports.string().nullable(),
4326
+ activeProjectId: external_exports.string().nullable(),
4327
+ activeSessionId: external_exports.string().nullable(),
4328
+ personalityAgentId: external_exports.string().nullable(),
4329
+ summary: external_exports.string().max(4e3).nullable(),
4330
+ agent: zAgent,
4331
+ model: external_exports.string().min(1),
4332
+ effort: external_exports.string().min(1),
4333
+ memories: external_exports.array(zTelegramMemoryRecord)
4334
+ });
4335
+ TELEGRAM_REPLY_KINDS = [
4336
+ "progress",
4337
+ "final",
4338
+ "decision",
4339
+ "failure",
4340
+ "confirmation"
4341
+ ];
4342
+ zTelegramReplyKind = external_exports.enum(TELEGRAM_REPLY_KINDS);
4343
+ zTelegramConfirmationRequest = external_exports.object({
4344
+ description: external_exports.string().trim().min(1).max(500),
4345
+ method: external_exports.enum(["POST", "PATCH", "PUT", "DELETE"]),
4346
+ path: external_exports.string().startsWith("/api/").max(1e3)
4347
+ });
4348
+ zTelegramReplyInput = external_exports.object({
4349
+ chatId: external_exports.string().min(1),
4350
+ updateId: external_exports.number().int().nonnegative(),
4351
+ kind: zTelegramReplyKind,
4352
+ text: external_exports.string().trim().min(1).max(12e3),
4353
+ summary: external_exports.string().trim().min(1).max(4e3).optional(),
4354
+ remember: external_exports.array(external_exports.string().trim().min(1).max(1e3)).max(20).optional(),
4355
+ confirmation: zTelegramConfirmationRequest.optional()
4356
+ }).superRefine((value, ctx) => {
4357
+ if (value.kind === "confirmation" && !value.confirmation) {
4358
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["confirmation"], message: "confirmation required" });
4359
+ }
4360
+ if (value.kind !== "confirmation" && value.confirmation) {
4361
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["confirmation"], message: "confirmation only valid for confirmation replies" });
4362
+ }
4363
+ });
4364
+ zTelegramAuditRecord = external_exports.object({
4365
+ id: external_exports.string().min(1),
4366
+ chatId: external_exports.string().nullable(),
4367
+ userId: external_exports.string().nullable(),
4368
+ updateId: external_exports.number().int().nonnegative().nullable(),
4369
+ action: external_exports.string().min(1),
4370
+ outcome: external_exports.string().min(1),
4371
+ correlationId: external_exports.string().nullable(),
4372
+ method: external_exports.string().nullable(),
4373
+ path: external_exports.string().nullable(),
4374
+ statusCode: external_exports.number().int().nullable(),
4375
+ createdAt: external_exports.string().datetime()
4376
+ });
4377
+ zTerminalSteerInput = external_exports.object({
4378
+ text: external_exports.string().trim().min(1).max(16e3)
4379
+ });
4380
+ }
4381
+ });
4382
+
4284
4383
  // ../shared/src/entities.ts
4285
4384
  var zProject, zBriefPayload, zQaPayload, zGoalPayload, zSpecBlocker, zSpec, NOTIFY_SOUNDS, zCodex, CODEX_DEFAULTS, zSourceCommon, zScheduler, SCHEDULER_DEFAULTS, zGoal, GOAL_DEFAULTS, zConflict, CONFLICT_DEFAULTS, zLeadEngine, zLead, LEAD_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4286
4385
  var init_entities = __esm({
@@ -4288,6 +4387,7 @@ var init_entities = __esm({
4288
4387
  "use strict";
4289
4388
  init_zod();
4290
4389
  init_enums();
4390
+ init_telegram();
4291
4391
  zProject = external_exports.object({
4292
4392
  id: external_exports.string(),
4293
4393
  name: external_exports.string(),
@@ -4462,8 +4562,10 @@ var init_entities = __esm({
4462
4562
  // SPEC-376 · ADR-0080 · scope verifikasi sesi
4463
4563
  conflict: zConflict.default(CONFLICT_DEFAULTS),
4464
4564
  // SPEC-383 · ADR-0081 · default sesi konflik rebase/merge
4465
- lead: zLead.default(LEAD_DEFAULTS)
4565
+ lead: zLead.default(LEAD_DEFAULTS),
4466
4566
  // SPEC-409 · ADR-0091 · hanoman-lead (default mati)
4567
+ telegram: zTelegramSettings.default(TELEGRAM_DEFAULTS)
4568
+ // SPEC-476 · ADR-0096 · gateway Telegram (default mati)
4467
4569
  });
4468
4570
  zNotification = external_exports.object({
4469
4571
  id: external_exports.string(),
@@ -4532,7 +4634,11 @@ var init_agent = __esm({
4532
4634
  // definisi agen mengubah apa yang dilihat SETIAP sesi baru di seluruh workspace, jadi izin
4533
4635
  // baca tak pernah cukup untuk itu (kelas bug SPEC-405).
4534
4636
  "agents:read",
4535
- "agents:write"
4637
+ "agents:write",
4638
+ // SPEC-476 · ADR-0096 · context/memory/reply/audit kanal Telegram. Aksi produk tetap memakai
4639
+ // capability domain produk masing-masing; domain ini tidak memberi akses shell atau sesi.
4640
+ "telegram:read",
4641
+ "telegram:write"
4536
4642
  ];
4537
4643
  zCapability = external_exports.enum(CAPABILITY_IDS);
4538
4644
  zCapabilityInfo = external_exports.object({
@@ -4600,6 +4706,36 @@ var init_custom_agent = __esm({
4600
4706
  }
4601
4707
  });
4602
4708
 
4709
+ // ../shared/src/github.ts
4710
+ var zGithubIssueStatus, zNormalIssue, zGithubIssueView;
4711
+ var init_github = __esm({
4712
+ "../shared/src/github.ts"() {
4713
+ "use strict";
4714
+ init_zod();
4715
+ zGithubIssueStatus = external_exports.enum(["new", "accepted", "rejected"]);
4716
+ zNormalIssue = external_exports.object({
4717
+ number: external_exports.number().int().positive(),
4718
+ title: external_exports.string(),
4719
+ body: external_exports.string(),
4720
+ authorLogin: external_exports.string(),
4721
+ labels: external_exports.array(external_exports.string()),
4722
+ url: external_exports.string(),
4723
+ issueState: external_exports.enum(["open", "closed"]),
4724
+ issueCreatedAt: external_exports.string(),
4725
+ // ISO-8601 apa adanya dari GitHub
4726
+ issueUpdatedAt: external_exports.string()
4727
+ });
4728
+ zGithubIssueView = zNormalIssue.extend({
4729
+ id: external_exports.string(),
4730
+ projectId: external_exports.string(),
4731
+ repoSlug: external_exports.string(),
4732
+ status: zGithubIssueStatus,
4733
+ specId: external_exports.string().nullable(),
4734
+ pulledAt: external_exports.string()
4735
+ });
4736
+ }
4737
+ });
4738
+
4603
4739
  // ../shared/src/lead.ts
4604
4740
  var zLeadGate, zLeadKind, zLeadConfidence, zLeadStatus, LEAD_ACTIONS, zLeadAction, zLeadVerdict, zLeadAsk, zLeadOverride;
4605
4741
  var init_lead = __esm({
@@ -5135,6 +5271,8 @@ var init_api = __esm({
5135
5271
  fsBrowse: (path) => `${API}/fs/browse${path ? `?path=${encodeURIComponent(path)}` : ""}`,
5136
5272
  terminalSessions: `${API}/terminal/sessions`,
5137
5273
  terminalSession: (id) => `${API}/terminal/sessions/${id}`,
5274
+ terminalSteer: (id) => `${API}/terminal/sessions/${id}/steer`,
5275
+ terminalInterrupt: (id) => `${API}/terminal/sessions/${id}/interrupt`,
5138
5276
  terminalPhases: (id) => `${API}/terminal/sessions/${id}/phases`,
5139
5277
  // SPEC-230 · review + integrate ber-skop sesi (sesi project-level PRD, tanpa Spec).
5140
5278
  sessionReview: (id) => `${API}/terminal/sessions/${id}/review`,
@@ -5189,6 +5327,13 @@ var init_api = __esm({
5189
5327
  // SPEC-450 · ADR-0094 · katalog custom agent. `?projectId=` → himpunan EFEKTIF (global+project).
5190
5328
  customAgents: `${API}/custom-agents`,
5191
5329
  customAgent: (id) => `${API}/custom-agents/${encodeURIComponent(id)}`,
5330
+ // SPEC-476 · ADR-0096 · observability/context/reply kanal Telegram.
5331
+ telegramStatus: `${API}/telegram/status`,
5332
+ telegramContext: (chatId) => `${API}/telegram/chats/${encodeURIComponent(chatId)}/context`,
5333
+ telegramMemories: (chatId) => `${API}/telegram/chats/${encodeURIComponent(chatId)}/memories`,
5334
+ telegramMemory: (chatId, id) => `${API}/telegram/chats/${encodeURIComponent(chatId)}/memories/${encodeURIComponent(id)}`,
5335
+ telegramReplies: `${API}/telegram/replies`,
5336
+ telegramAudit: `${API}/telegram/audit`,
5192
5337
  // SPEC-268 · ADR-0066 · pemicu sync manual (cookie-authed)
5193
5338
  syncNow: `${API}/sync/now`,
5194
5339
  // SPEC-270 · ADR-0067 · antrean konflik rekonsil (cookie-authed)
@@ -5211,6 +5356,14 @@ var init_api = __esm({
5211
5356
  ticketUnlink: (id) => `${API}/tickets/${id}/unlink`,
5212
5357
  // SPEC-271 · lepas tautan backlog
5213
5358
  ticketReject: (id) => `${API}/tickets/${id}/reject`,
5359
+ // SPEC-471 · ADR-0095 · tarik & triase issue GitHub (di belakang gate cookie, capability `support`).
5360
+ // hanoman TIDAK PERNAH menulis ke GitHub — tak ada path komentar/close di sini, dan itu disengaja.
5361
+ githubPull: (id) => `${API}/projects/${encodeURIComponent(id)}/github/pull`,
5362
+ githubIssues: (id) => `${API}/projects/${encodeURIComponent(id)}/github/issues`,
5363
+ githubIssuesAccept: `${API}/github-issues/accept`,
5364
+ githubIssueAccept: (id) => `${API}/github-issues/${encodeURIComponent(id)}/accept`,
5365
+ githubIssueReject: (id) => `${API}/github-issues/${encodeURIComponent(id)}/reject`,
5366
+ githubIssueUnlink: (id) => `${API}/github-issues/${encodeURIComponent(id)}/unlink`,
5214
5367
  // SPEC-361 · ADR-0078 · unduh dokumen: query ditempelkan ke URL endpoint dokumen yang sudah ada
5215
5368
  // (tak ada endpoint ekspor terpisah). `base` bisa sudah membawa query, mis. ideFile(?path=…).
5216
5369
  download: (base, fmt) => `${base}${base.includes("?") ? "&" : "?"}download=${fmt}`
@@ -5293,7 +5446,8 @@ var init_session_kind = __esm({
5293
5446
  "vps",
5294
5447
  "shell",
5295
5448
  "worktree",
5296
- "terminal"
5449
+ "terminal",
5450
+ "telegram"
5297
5451
  ];
5298
5452
  zSessionKind = external_exports.enum(SESSION_KINDS);
5299
5453
  }
@@ -5373,6 +5527,28 @@ var init_config_registry = __esm({
5373
5527
  // vps
5374
5528
  { key: "HANOMAN_SSH_KEY_DIR", group: "vps", label: "Dir key SSH", kind: "path", apply: "new-session", category: "knob", help: "Default ~/.hanoman." },
5375
5529
  { key: "HANOMAN_SSH_BIN", group: "vps", label: "Biner ssh", kind: "path", apply: "new-session", category: "knob", default: "ssh" },
5530
+ // github (SPEC-471 · ADR-0095 · tarik issue → backlog). Dua mode auth, satu jalur kode:
5531
+ // `gh` memakai keyring mesin; bila GITHUB_TOKEN diisi ia diteruskan sebagai GH_TOKEN ke
5532
+ // proses gh DAN dipakai jalur REST (hub VPS yang tak punya keyring).
5533
+ {
5534
+ key: "GITHUB_TOKEN",
5535
+ group: "github",
5536
+ label: "GitHub token",
5537
+ kind: "secret",
5538
+ apply: "live",
5539
+ category: "credential",
5540
+ help: "PAT scope `repo` (atau `public_repo`). Kosong = andalkan `gh auth login` di mesin ini."
5541
+ },
5542
+ {
5543
+ key: "HANOMAN_GH_BIN",
5544
+ group: "github",
5545
+ label: "Biner gh",
5546
+ kind: "path",
5547
+ apply: "live",
5548
+ category: "knob",
5549
+ default: "gh",
5550
+ help: "Absen = tarik issue lewat HTTPS langsung ke api.github.com."
5551
+ },
5376
5552
  // runtime
5377
5553
  { key: "HANOMAN_EVENTS_TICK_MS", group: "runtime", label: "Interval events (ms)", kind: "int", apply: "live", category: "knob", default: "1000", min: 100 },
5378
5554
  { key: "HANOMAN_UPDATE_FETCH", group: "runtime", label: "Deteksi update saat boot", kind: "bool", apply: "live", category: "knob", default: "1" },
@@ -5465,6 +5641,7 @@ var init_src = __esm({
5465
5641
  init_entities();
5466
5642
  init_agent();
5467
5643
  init_custom_agent();
5644
+ init_github();
5468
5645
  init_lead();
5469
5646
  init_dto();
5470
5647
  init_api();
@@ -5474,6 +5651,7 @@ var init_src = __esm({
5474
5651
  init_config();
5475
5652
  init_config_registry();
5476
5653
  init_semver();
5654
+ init_telegram();
5477
5655
  }
5478
5656
  });
5479
5657
 
@@ -5542,6 +5720,13 @@ var init_paths = __esm({
5542
5720
  }
5543
5721
  });
5544
5722
 
5723
+ // ../runner/src/telegram-operator.ts
5724
+ var init_telegram_operator = __esm({
5725
+ "../runner/src/telegram-operator.ts"() {
5726
+ "use strict";
5727
+ }
5728
+ });
5729
+
5545
5730
  // ../runner/src/index.ts
5546
5731
  var init_src2 = __esm({
5547
5732
  "../runner/src/index.ts"() {
@@ -5558,6 +5743,7 @@ var init_src2 = __esm({
5558
5743
  init_custom_agents();
5559
5744
  init_verify_scope();
5560
5745
  init_paths();
5746
+ init_telegram_operator();
5561
5747
  }
5562
5748
  });
5563
5749
 
@@ -5960,6 +6146,12 @@ function doctorReport(p) {
5960
6146
  { mark: p.tmux ? "\u2713" : "\u2717", text: p.tmux ?? "tmux \u2014 TAK ADA (wajib: sesi agen hidup di tmux)", fatal: !p.tmux },
5961
6147
  { mark: p.claude ? "\u2713" : "\xB7", text: p.claude ? `claude ${p.claude}` : "claude \u2014 tak ada", fatal: false },
5962
6148
  { mark: p.codex ? "\u2713" : "\xB7", text: p.codex ? `codex ${p.codex}` : "codex \u2014 tak ada", fatal: false },
6149
+ // SPEC-471 · ADR-0095 · `gh` opsional: tanpa dia tarik issue jatuh ke HTTPS + GITHUB_TOKEN.
6150
+ {
6151
+ mark: p.gh ? "\u2713" : "\xB7",
6152
+ text: p.gh ? `gh ${p.gh}` : "gh \u2014 tak ada (tarik issue akan lewat HTTP + GITHUB_TOKEN)",
6153
+ fatal: false
6154
+ },
5963
6155
  { mark: p.homeWritable ? "\u2713" : "\u2717", text: `data dir ${p.homeWritable ? "bisa ditulis" : "TAK bisa ditulis"}`, fatal: !p.homeWritable },
5964
6156
  { mark: p.web ? "\u2713" : "!", text: p.web ? "aset dashboard ada" : "aset dashboard tak ada \u2014 API jalan, dashboard tidak", fatal: false },
5965
6157
  { mark: "\xB7", text: `db ${p.db}`, fatal: false }
@@ -6000,6 +6192,7 @@ async function doctor(_argv, ctx) {
6000
6192
  tmux: version("tmux", ["-V"]),
6001
6193
  claude: version(ctx.env.HANOMAN_CLAUDE_BIN ?? "claude", ["--version"]),
6002
6194
  codex: version(ctx.env.HANOMAN_CODEX_BIN ?? "codex", ["--version"]),
6195
+ gh: version(ctx.env.HANOMAN_GH_BIN ?? "gh", ["--version"]),
6003
6196
  homeWritable,
6004
6197
  web: layout.web !== null,
6005
6198
  db
@@ -6203,8 +6396,21 @@ var init_migrate_pg = __esm({
6203
6396
  "SchedulerQueueItem",
6204
6397
  "RuntimeConfig",
6205
6398
  "LeadDecision",
6399
+ // SPEC-476 · ADR-0096 · tabel gateway LOCAL-only; sumber Postgres lama lazimnya tidak punya
6400
+ // tabel ini dan jalur 42P01 di bawah memperlakukannya sebagai nol baris.
6401
+ "TelegramGatewayState",
6402
+ "TelegramChat",
6403
+ "TelegramUpdate",
6404
+ "TelegramMemory",
6405
+ "TelegramOutbox",
6406
+ "TelegramConfirmation",
6407
+ "TelegramAudit",
6206
6408
  "Ticket",
6207
- "TicketAttachment"
6409
+ "TicketAttachment",
6410
+ // SPEC-471 · ADR-0095 · GithubIssue sesudah Project (FK projectId) DAN sesudah Spec: `specId`
6411
+ // memang tanpa FK, tapi memindahkannya lebih awal membuat urutan tabel tak lagi mencerminkan
6412
+ // arah tautannya bagi pembaca berikutnya.
6413
+ "GithubIssue"
6208
6414
  ];
6209
6415
  CHUNK = 200;
6210
6416
  INT8_OID = 20;