hanoman 0.9.28 → 0.9.29

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 (35) hide show
  1. package/README.md +5 -2
  2. package/dist/build-info.json +3 -3
  3. package/dist/cli.js +337 -90
  4. package/dist/server.js +2677 -1389
  5. package/docs/agent-integration.md +100 -6
  6. package/package.json +1 -1
  7. package/prisma/migrations/20261014130000_cron_report/migration.sql +19 -0
  8. package/prisma/schema.prisma +25 -0
  9. package/scripts/vps/provision.sh +26 -3
  10. package/web/assets/{DalangHanomanScreen-C3UMPHFg.js → DalangHanomanScreen-BMrikKnt.js} +1 -1
  11. package/web/assets/{DocPreviewModal-Bp5stb4M.js → DocPreviewModal-5j31WUwI.js} +1 -1
  12. package/web/assets/{DocsWorkspace-C9yFxK4D.js → DocsWorkspace-GkTrniF3.js} +1 -1
  13. package/web/assets/{IdeScreen-CRFRAP6E.js → IdeScreen-CAQfv1_e.js} +1 -1
  14. package/web/assets/LeadScreen-Da5-1FLe.js +1 -0
  15. package/web/assets/{ReviewScreen-CMHOlmgX.js → ReviewScreen-B8KHzQpd.js} +1 -1
  16. package/web/assets/SchedulerScreen-CBd4O5kw.js +1 -0
  17. package/web/assets/SettingsScreen-BxQ3CH2D.js +62 -0
  18. package/web/assets/{TeamScreen-D4tA34Mj.js → TeamScreen-P6vz88Pp.js} +1 -1
  19. package/web/assets/TerminalScreen-B_cagBZd.js +2 -0
  20. package/web/assets/{TriageScreen-B8ZCexaX.js → TriageScreen-IYkxyhdm.js} +1 -1
  21. package/web/assets/{VpsScreen-BCrLfZh7.js → VpsScreen-DFGT5S8Y.js} +2 -2
  22. package/web/assets/fields-CmVwp6QK.js +1 -0
  23. package/web/assets/{index-BqAP-VDq.css → index-0T3s-I82.css} +1 -1
  24. package/web/assets/index-C-iSWHn3.js +1012 -0
  25. package/web/assets/{live-DuBdI0MZ.js → live-lSo-u7M6.js} +1 -1
  26. package/web/assets/{sched-lead-shared-QqbtjoVv.js → sched-lead-shared-BTz6aILx.js} +1 -1
  27. package/web/assets/{scheduler-CQt-VP9-.css → scheduler-D64RlGvZ.css} +1 -1
  28. package/web/assets/settings-rebase-CPawFVpp.js +1 -0
  29. package/web/index.html +2 -2
  30. package/web/assets/LeadScreen-DfVUawoK.js +0 -1
  31. package/web/assets/SchedulerScreen-CK5QvX5c.js +0 -1
  32. package/web/assets/SettingsScreen-D7P5JgjU.js +0 -62
  33. package/web/assets/TerminalScreen-CKySL63X.js +0 -2
  34. package/web/assets/index-BRR3JL_o.js +0 -1012
  35. package/web/assets/settings-rebase-Cbh-JGJ-.js +0 -1
package/dist/cli.js CHANGED
@@ -582,11 +582,11 @@ function datetimeRegex(args) {
582
582
  regex = `${regex}(${opts.join("|")})`;
583
583
  return new RegExp(`^${regex}$`);
584
584
  }
585
- function isValidIP(ip, version3) {
586
- if ((version3 === "v4" || !version3) && ipv4Regex.test(ip)) {
585
+ function isValidIP(ip, version2) {
586
+ if ((version2 === "v4" || !version2) && ipv4Regex.test(ip)) {
587
587
  return true;
588
588
  }
589
- if ((version3 === "v6" || !version3) && ipv6Regex.test(ip)) {
589
+ if ((version2 === "v6" || !version2) && ipv6Regex.test(ip)) {
590
590
  return true;
591
591
  }
592
592
  return false;
@@ -613,11 +613,11 @@ function isValidJWT(jwt, alg) {
613
613
  return false;
614
614
  }
615
615
  }
616
- function isValidCidr(ip, version3) {
617
- if ((version3 === "v4" || !version3) && ipv4CidrRegex.test(ip)) {
616
+ function isValidCidr(ip, version2) {
617
+ if ((version2 === "v4" || !version2) && ipv4CidrRegex.test(ip)) {
618
618
  return true;
619
619
  }
620
- if ((version3 === "v6" || !version3) && ipv6CidrRegex.test(ip)) {
620
+ if ((version2 === "v6" || !version2) && ipv6CidrRegex.test(ip)) {
621
621
  return true;
622
622
  }
623
623
  return false;
@@ -4133,7 +4133,7 @@ var init_enums = __esm({
4133
4133
  zDocStatus = external_exports.enum(["ok", "drift", "broken"]);
4134
4134
  zPriority = external_exports.enum(["tinggi", "sedang", "rendah"]);
4135
4135
  zProjectKind = external_exports.enum(["from-scratch", "existing"]);
4136
- zAgent = external_exports.enum(["claude", "codex"]);
4136
+ zAgent = external_exports.enum(["claude", "codex", "antigravity"]);
4137
4137
  zSeverity = external_exports.enum(["critical", "major", "minor"]);
4138
4138
  zTicketCategory = external_exports.enum(["bug", "fitur", "pertanyaan", "lainnya"]);
4139
4139
  zTicketStatus = external_exports.enum(["new", "accepted", "rejected"]);
@@ -4210,6 +4210,7 @@ var init_method_catalog = __esm({
4210
4210
  exitSkills: [VERIFICATION_GATE],
4211
4211
  requires: ["superpowers"],
4212
4212
  install: {
4213
+ antigravity: [],
4213
4214
  claude: [
4214
4215
  "claude plugin marketplace add obra/superpowers-marketplace",
4215
4216
  "claude plugin install superpowers@superpowers-marketplace"
@@ -4244,6 +4245,7 @@ var init_method_catalog = __esm({
4244
4245
  // dari sana (INVARIAN 2). codex belum punya plugin native mattpocock — jalur resminya
4245
4246
  // `npx skills`, dan ia INTERAKTIF; itu justru alasan pemasangan hidup di pane yang ditonton.
4246
4247
  install: {
4248
+ antigravity: [],
4247
4249
  claude: [
4248
4250
  "claude plugin install mattpocock-skills",
4249
4251
  "claude plugin marketplace add obra/superpowers-marketplace",
@@ -4280,6 +4282,7 @@ var init_method_catalog = __esm({
4280
4282
  requires: ["agent-skills", "superpowers"],
4281
4283
  // Manifest upstream: marketplace Claude = addy-agent-skills, Codex = agent-skills.
4282
4284
  install: {
4285
+ antigravity: [],
4283
4286
  claude: [
4284
4287
  "claude plugin marketplace add addyosmani/agent-skills",
4285
4288
  "claude plugin install agent-skills@addy-agent-skills",
@@ -4314,15 +4317,18 @@ function methodStatus(m, agent, installed) {
4314
4317
  method: m.id,
4315
4318
  label: m.label,
4316
4319
  agent,
4317
- ready: missingPackages.length === 0 && missingSkills.length === 0,
4320
+ ...agent === "antigravity" ? { available: false, availabilityReason: ANTIGRAVITY_METHOD_UNAVAILABLE_REASON } : {},
4321
+ ready: agent !== "antigravity" && missingPackages.length === 0 && missingSkills.length === 0,
4318
4322
  missingPackages,
4319
4323
  missingSkills,
4320
4324
  install: [...m.install[agent]]
4321
4325
  };
4322
4326
  }
4327
+ var ANTIGRAVITY_METHOD_UNAVAILABLE_REASON;
4323
4328
  var init_method_status = __esm({
4324
4329
  "../shared/src/method-status.ts"() {
4325
4330
  "use strict";
4331
+ ANTIGRAVITY_METHOD_UNAVAILABLE_REASON = "Installer metode Antigravity belum terverifikasi dari upstream";
4326
4332
  }
4327
4333
  });
4328
4334
 
@@ -4342,8 +4348,29 @@ var init_agent_engine = __esm({
4342
4348
  }
4343
4349
  });
4344
4350
 
4351
+ // ../shared/src/antigravity.ts
4352
+ function isAntigravityChildTier(value) {
4353
+ return ANTIGRAVITY_CHILD_TIERS.some((tier) => tier === value);
4354
+ }
4355
+ var ANTIGRAVITY_CHILD_TIERS, BUILTIN_ANTIGRAVITY_RUNTIME_DEFAULTS, ANTIGRAVITY_MODELS;
4356
+ var init_antigravity = __esm({
4357
+ "../shared/src/antigravity.ts"() {
4358
+ "use strict";
4359
+ ANTIGRAVITY_CHILD_TIERS = ["inherit", "flash", "pro"];
4360
+ BUILTIN_ANTIGRAVITY_RUNTIME_DEFAULTS = {
4361
+ model: "gemini-3.8-flash-high",
4362
+ effort: "high"
4363
+ };
4364
+ ANTIGRAVITY_MODELS = [{
4365
+ id: BUILTIN_ANTIGRAVITY_RUNTIME_DEFAULTS.model,
4366
+ label: "Gemini 3.8 Flash High",
4367
+ efforts: [BUILTIN_ANTIGRAVITY_RUNTIME_DEFAULTS.effort]
4368
+ }];
4369
+ }
4370
+ });
4371
+
4345
4372
  // ../shared/src/telegram.ts
4346
- var zTelegramSettings, TELEGRAM_DEFAULTS, zTelegramReadiness, zTelegramGatewayStatus, zTelegramMemoryRecord, zTelegramChatContext, TELEGRAM_REPLY_KINDS, zTelegramReplyKind, zTelegramConfirmationRequest, zTelegramReplyInput, zTelegramAuditRecord, zTerminalSteerInput;
4373
+ var zTelegramSettings, TELEGRAM_DEFAULTS, zTelegramReadiness, zTelegramGatewayStatus, zTelegramMemoryRecord, zTelegramChatContext, TELEGRAM_REPLY_KINDS, zTelegramReplyKind, zTelegramConfirmationRequest, zTelegramReplyInput, zTelegramAuditRecord, zTerminalSteerInput, SESSION_NAME_MAX, zTerminalRenameInput;
4347
4374
  var init_telegram = __esm({
4348
4375
  "../shared/src/telegram.ts"() {
4349
4376
  "use strict";
@@ -4440,6 +4467,8 @@ var init_telegram = __esm({
4440
4467
  zTerminalSteerInput = external_exports.object({
4441
4468
  text: external_exports.string().trim().min(1).max(16e3)
4442
4469
  });
4470
+ SESSION_NAME_MAX = 80;
4471
+ zTerminalRenameInput = external_exports.object({ name: external_exports.string().max(SESSION_NAME_MAX * 4) });
4443
4472
  }
4444
4473
  });
4445
4474
 
@@ -4702,10 +4731,20 @@ var init_runtime_defaults = __esm({
4702
4731
  model: zRuntimeDefaultState.default("seeded"),
4703
4732
  effort: zRuntimeDefaultState.default("seeded")
4704
4733
  }).default({}),
4734
+ antigravity: external_exports.object({
4735
+ model: zRuntimeDefaultState.default("seeded"),
4736
+ effort: zRuntimeDefaultState.default("seeded")
4737
+ }).default({}),
4705
4738
  orchestration: external_exports.record(external_exports.string(), zRuntimeDefaultState).default({})
4706
4739
  });
4707
4740
  cell = (model, effort) => ({ model, effort });
4708
- flow = (claude, codex, enabled = true) => ({ enabled, executeMode: "inline", claude, codex });
4741
+ flow = (claude, codex, enabled = true) => ({
4742
+ enabled,
4743
+ executeMode: "inline",
4744
+ claude,
4745
+ codex,
4746
+ antigravity: Object.fromEntries(Object.keys(claude).map((phase) => [phase, { model: "inherit", effort: null }]))
4747
+ });
4709
4748
  BUILTIN_ORCHESTRATION_DEFAULTS = {
4710
4749
  feature: flow(
4711
4750
  {
@@ -4813,7 +4852,7 @@ var init_runtime_defaults = __esm({
4813
4852
  };
4814
4853
  seededFlows = Object.fromEntries(ORCHESTRATION_FLOWS.flatMap((flow2) => [
4815
4854
  [`${flow2}.enabled`, "seeded"],
4816
- ...["claude", "codex"].flatMap((runtime) => FLOW_PHASES[flow2].flatMap((phase) => [
4855
+ ...["claude", "codex", "antigravity"].flatMap((runtime) => FLOW_PHASES[flow2].flatMap((phase) => [
4817
4856
  [`${flow2}.${runtime}.${phase}.model`, "seeded"],
4818
4857
  [`${flow2}.${runtime}.${phase}.effort`, "seeded"]
4819
4858
  ]))
@@ -4822,6 +4861,7 @@ var init_runtime_defaults = __esm({
4822
4861
  version: RUNTIME_DEFAULTS_VERSION,
4823
4862
  claude: { model: "seeded", effort: "seeded" },
4824
4863
  codex: { model: "seeded", effort: "seeded" },
4864
+ antigravity: { model: "seeded", effort: "seeded" },
4825
4865
  orchestration: seededFlows
4826
4866
  };
4827
4867
  }
@@ -4837,11 +4877,12 @@ function cmpVersion(a, b) {
4837
4877
  }
4838
4878
  return 0;
4839
4879
  }
4840
- 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, zLeadEngine, zLead, LEAD_DEFAULTS, zPortalChat, PORTAL_CHAT_DEFAULTS, zPhaseCell, PHASE_OVERRIDE_LIMITS, zPhaseOverride, zPhaseOverrides, zFlowOrchestration, zOrchestration, ORCHESTRATION_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4880
+ var zProject, zBriefPayload, zQaPayload, zGoalPayload, zSpecBlocker, zSourceChange, zManualDone, zSpec, zSpecListItem, zSpecSlim, NOTIFY_SOUNDS, zCodex, CODEX_DEFAULTS, zAntigravity, ANTIGRAVITY_DEFAULTS, zSourceCommon, zScheduler, SCHEDULER_DEFAULTS, zGoal, GOAL_DEFAULTS, zConflict, CONFLICT_DEFAULTS, zLeadEngine, zLead, LEAD_DEFAULTS, zPortalChat, PORTAL_CHAT_DEFAULTS, zPhaseCell, zAntigravityPhaseCell, PHASE_OVERRIDE_LIMITS, zPhaseOverride, zPhaseOverrides, zFlowOrchestration, zOrchestration, ORCHESTRATION_DEFAULTS, zSetting, zNotification, zDocFile, zDeviceTokenView;
4841
4881
  var init_entities = __esm({
4842
4882
  "../shared/src/entities.ts"() {
4843
4883
  "use strict";
4844
4884
  init_zod();
4885
+ init_antigravity();
4845
4886
  init_enums();
4846
4887
  init_telegram();
4847
4888
  init_agent_engine();
@@ -4972,6 +5013,11 @@ var init_entities = __esm({
4972
5013
  effort: external_exports.string().default("medium")
4973
5014
  });
4974
5015
  CODEX_DEFAULTS = zCodex.parse({});
5016
+ zAntigravity = external_exports.object({
5017
+ model: external_exports.string().default(BUILTIN_ANTIGRAVITY_RUNTIME_DEFAULTS.model),
5018
+ effort: external_exports.string().default(BUILTIN_ANTIGRAVITY_RUNTIME_DEFAULTS.effort)
5019
+ });
5020
+ ANTIGRAVITY_DEFAULTS = zAntigravity.parse({});
4975
5021
  zSourceCommon = { enabled: external_exports.boolean().default(false) };
4976
5022
  zScheduler = external_exports.object({
4977
5023
  enabled: external_exports.boolean().default(false),
@@ -5062,10 +5108,14 @@ var init_entities = __esm({
5062
5108
  model: external_exports.string().nullable().default(null),
5063
5109
  effort: external_exports.string().nullable().default(null)
5064
5110
  });
5111
+ zAntigravityPhaseCell = external_exports.object({
5112
+ model: external_exports.enum(ANTIGRAVITY_CHILD_TIERS).nullable().default(null),
5113
+ effort: external_exports.null().default(null)
5114
+ });
5065
5115
  PHASE_OVERRIDE_LIMITS = { model: 200, effort: 64, phase: 64, phases: 32 };
5066
5116
  zPhaseOverride = external_exports.object({
5067
- model: external_exports.string().min(1).max(PHASE_OVERRIDE_LIMITS.model).optional(),
5068
- effort: external_exports.string().min(1).max(PHASE_OVERRIDE_LIMITS.effort).optional()
5117
+ model: external_exports.string().min(1).max(PHASE_OVERRIDE_LIMITS.model).nullable().optional(),
5118
+ effort: external_exports.string().min(1).max(PHASE_OVERRIDE_LIMITS.effort).nullable().optional()
5069
5119
  });
5070
5120
  zPhaseOverrides = external_exports.record(external_exports.string().min(1).max(PHASE_OVERRIDE_LIMITS.phase), zPhaseOverride).refine(
5071
5121
  (o) => Object.keys(o).length <= PHASE_OVERRIDE_LIMITS.phases,
@@ -5076,7 +5126,8 @@ var init_entities = __esm({
5076
5126
  // Amandemen ADR-0170 P2 · lenient: nilai asing jatuh ke `inline`, bukan Setting gagal parse.
5077
5127
  executeMode: external_exports.enum(["inline", "subagent"]).catch("inline").default("inline"),
5078
5128
  claude: external_exports.record(external_exports.string(), zPhaseCell).default({}),
5079
- codex: external_exports.record(external_exports.string(), zPhaseCell).default({})
5129
+ codex: external_exports.record(external_exports.string(), zPhaseCell).default({}),
5130
+ antigravity: external_exports.record(external_exports.string(), zPhaseCell).default({})
5080
5131
  });
5081
5132
  zOrchestration = external_exports.object({
5082
5133
  feature: zFlowOrchestration.default({}),
@@ -5114,6 +5165,7 @@ var init_entities = __esm({
5114
5165
  // SPEC-338 · ADR-0074 · mesin sesi default
5115
5166
  codex: zCodex.default(CODEX_DEFAULTS),
5116
5167
  // SPEC-338 · ADR-0074 · model/effort codex
5168
+ antigravity: zAntigravity.default(ANTIGRAVITY_DEFAULTS),
5117
5169
  verifyScope: zVerifyScope.default("changed"),
5118
5170
  // SPEC-376 · ADR-0080 · scope verifikasi sesi
5119
5171
  // SPEC-734 · ADR-0113 · metode workflow default. LENIENT (`z.string()`, bukan `z.enum`):
@@ -5189,14 +5241,15 @@ var init_entities = __esm({
5189
5241
  });
5190
5242
 
5191
5243
  // ../shared/src/orchestration-plan.ts
5192
- function codexNativeAgentsSupported(version3) {
5193
- const parsed = version3 ? /(\d+)\.(\d+)\.(\d+)/.exec(version3)?.[0] : null;
5244
+ function codexNativeAgentsSupported(version2) {
5245
+ const parsed = version2 ? /(\d+)\.(\d+)\.(\d+)/.exec(version2)?.[0] : null;
5194
5246
  return parsed ? cmpVersion(parsed, CODEX_NATIVE_AGENTS_MIN_CLIENT) >= 0 : false;
5195
5247
  }
5196
5248
  var CODEX_NATIVE_AGENTS_MIN_CLIENT;
5197
5249
  var init_orchestration_plan = __esm({
5198
5250
  "../shared/src/orchestration-plan.ts"() {
5199
5251
  "use strict";
5252
+ init_antigravity();
5200
5253
  init_entities();
5201
5254
  init_orchestration();
5202
5255
  CODEX_NATIVE_AGENTS_MIN_CLIENT = "0.151.0";
@@ -5358,6 +5411,7 @@ var init_agent = __esm({
5358
5411
 
5359
5412
  // ../shared/src/custom-agent.ts
5360
5413
  function validateCreateWorkspacePolicy(value, ctx) {
5414
+ validateAntigravityChild(value, ctx);
5361
5415
  if (value.workspacePolicy === "isolated-worktree" && value.runtime !== "claude") {
5362
5416
  ctx.addIssue({
5363
5417
  code: external_exports.ZodIssueCode.custom,
@@ -5366,13 +5420,23 @@ function validateCreateWorkspacePolicy(value, ctx) {
5366
5420
  });
5367
5421
  }
5368
5422
  }
5423
+ function validateAntigravityChild(value, ctx) {
5424
+ if (value.runtime !== "antigravity") return;
5425
+ if (value.model != null && !isAntigravityChildTier(value.model)) {
5426
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["model"], message: "Antigravity child memakai tier inherit, flash, atau pro" });
5427
+ }
5428
+ if (value.effort != null) {
5429
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["effort"], message: "Antigravity child tidak mendukung effort independen" });
5430
+ }
5431
+ }
5369
5432
  var AGENT_RUNTIMES, zAgentRuntime, AGENT_ACTIVATIONS, zAgentActivation, zAgentEffort, AGENT_WORKSPACE_POLICIES, zAgentWorkspacePolicy, AGENT_NAME_RE, DEFAULT_AGENT_TOOLS, zCustomAgent, zCreateCustomAgentFields, zCreateCustomAgent, zUpdateCustomAgent;
5370
5433
  var init_custom_agent = __esm({
5371
5434
  "../shared/src/custom-agent.ts"() {
5372
5435
  "use strict";
5373
5436
  init_zod();
5437
+ init_antigravity();
5374
5438
  init_orchestration();
5375
- AGENT_RUNTIMES = ["claude", "codex"];
5439
+ AGENT_RUNTIMES = ["claude", "codex", "antigravity"];
5376
5440
  zAgentRuntime = external_exports.enum(AGENT_RUNTIMES);
5377
5441
  AGENT_ACTIVATIONS = ["always", "smart"];
5378
5442
  zAgentActivation = external_exports.enum(AGENT_ACTIVATIONS);
@@ -5430,6 +5494,7 @@ var init_custom_agent = __esm({
5430
5494
  });
5431
5495
  zCreateCustomAgent = zCreateCustomAgentFields.superRefine(validateCreateWorkspacePolicy);
5432
5496
  zUpdateCustomAgent = zCreateCustomAgentFields.omit({ name: true, projectId: true }).partial().superRefine((value, ctx) => {
5497
+ validateAntigravityChild(value, ctx);
5433
5498
  if (value.workspacePolicy === "isolated-worktree" && value.runtime !== void 0 && value.runtime !== "claude") {
5434
5499
  ctx.addIssue({
5435
5500
  code: external_exports.ZodIssueCode.custom,
@@ -6448,6 +6513,7 @@ var BUILTIN_AGENT_TOOLS;
6448
6513
  var init_agent_catalog = __esm({
6449
6514
  "../shared/src/agent-catalog.ts"() {
6450
6515
  "use strict";
6516
+ init_antigravity();
6451
6517
  init_custom_agent();
6452
6518
  init_entities();
6453
6519
  BUILTIN_AGENT_TOOLS = DEFAULT_AGENT_TOOLS.map((id) => ({
@@ -7236,6 +7302,7 @@ var init_dto = __esm({
7236
7302
  "agent-image",
7237
7303
  "claude",
7238
7304
  "codex",
7305
+ "antigravity",
7239
7306
  "gh"
7240
7307
  ];
7241
7308
  zProvision = external_exports.object({
@@ -7484,6 +7551,7 @@ var init_api = __esm({
7484
7551
  limits: `${API}/limits`,
7485
7552
  // SPEC-339 · versi codex CLI (peringatan lunak model GPT-5.6).
7486
7553
  codexVersion: `${API}/codex/version`,
7554
+ antigravityVersion: `${API}/antigravity/version`,
7487
7555
  // SPEC-739 · ADR-0114 · kesiapan skill metode per agen. LOCAL-only, diturunkan live dari disk.
7488
7556
  methodStatus: `${API}/methods/status`,
7489
7557
  // SPEC-489 · panduan AI agent — markdown MENTAH & PUBLIC (tanpa auth). Satu definisi URL untuk
@@ -7651,6 +7719,9 @@ var init_api = __esm({
7651
7719
  schedulerCron: (id) => `${API}/scheduler/crons/${encodeURIComponent(id)}`,
7652
7720
  schedulerCronRunNow: (id) => `${API}/scheduler/crons/${encodeURIComponent(id)}/run`,
7653
7721
  schedulerCronRuns: (id) => `${API}/scheduler/crons/${encodeURIComponent(id)}/runs`,
7722
+ // ADR-0222 · laporan run cron (baca-saja).
7723
+ schedulerReports: `${API}/scheduler/reports`,
7724
+ schedulerReport: (id) => `${API}/scheduler/reports/${encodeURIComponent(id)}`,
7654
7725
  // SPEC-409 · ADR-0091 · hanoman-lead. Semua HTTP (polling) — tak ada kanal WS baru (AC-26).
7655
7726
  leadConfig: `${API}/lead/config`,
7656
7727
  leadStatus: `${API}/lead/status`,
@@ -8006,6 +8077,17 @@ var init_config_registry = __esm({
8006
8077
  { key: "HANOMAN_CLAUDE_BIN", group: "claude", label: "Biner claude", kind: "path", apply: "new-session", category: "knob", example: "/opt/homebrew/bin/claude", default: "claude" },
8007
8078
  // codex (SPEC-338 · ADR-0074)
8008
8079
  { key: "HANOMAN_CODEX_BIN", group: "claude", label: "Biner codex", kind: "path", apply: "new-session", category: "knob", example: "/opt/homebrew/bin/codex", default: "codex" },
8080
+ {
8081
+ key: "HANOMAN_ANTIGRAVITY_BIN",
8082
+ group: "claude",
8083
+ label: "Biner Antigravity",
8084
+ kind: "path",
8085
+ apply: "new-session",
8086
+ category: "knob",
8087
+ example: "/opt/homebrew/bin/agy",
8088
+ default: "agy",
8089
+ help: "Executable Antigravity CLI, bukan shell command atau daftar flag."
8090
+ },
8009
8091
  {
8010
8092
  key: "CLAUDE_CONFIG_DIR",
8011
8093
  group: "claude",
@@ -10378,7 +10460,7 @@ var init_settings = __esm({
10378
10460
  {
10379
10461
  name: "hanoman_settings_get",
10380
10462
  title: "Baca setelan instance",
10381
- description: "Seluruh setelan instance: agen & model default, effort, notifikasi, mode goal, verifikasi, dan blok Telegram. Panggil ini sebelum hanoman_settings_set \u2014 setelan disimpan sebagai satu blok.",
10463
+ description: "Seluruh setelan instance: runtime Claude/Codex/Antigravity, model parent, effort, tier child native Antigravity, notifikasi, mode goal, verifikasi, dan blok Telegram. Panggil ini sebelum hanoman_settings_set \u2014 setelan disimpan sebagai satu blok.",
10382
10464
  inputSchema: obj({ properties: {} }),
10383
10465
  mode: "read",
10384
10466
  capability: "settings:read",
@@ -10390,7 +10472,7 @@ var init_settings = __esm({
10390
10472
  {
10391
10473
  name: "hanoman_settings_set",
10392
10474
  title: "Simpan setelan instance",
10393
- description: "Menyimpan setelan instance. MENGGANTI blok penuh \u2014 kirim hasil hanoman_settings_get yang sudah diubah, bukan potongan. Panggil hanoman_settings_get TEPAT sebelum tool ini (jangan memakai hasil lama) dan ubah HANYA field yang dimaksud: setiap model/effort/sel orkestrasi yang berbeda dari nilai tersimpan ditandai milik operator dan tak lagi diperbarui default bawaan saat update. Setelan ini berlaku untuk SETIAP sesi baru di seluruh workspace. Menyentuh blok Telegram akan memuat ulang gateway.",
10475
+ description: "Menyimpan setelan instance. MENGGANTI blok penuh \u2014 kirim hasil hanoman_settings_get yang sudah diubah, bukan potongan. Panggil hanoman_settings_get TEPAT sebelum tool ini (jangan memakai hasil lama) dan ubah HANYA field yang dimaksud: setiap model/effort/sel orkestrasi yang berbeda dari nilai tersimpan ditandai milik operator dan tak lagi diperbarui default bawaan saat update. Parent Antigravity memakai blok antigravity.model/effort; sel orchestration.<flow>.antigravity hanya menerima tier inherit|flash|pro atau model null dan effort null, bukan slug parent. Phase override per sesi menerima model/effort null; model null mewarisi tier native, effort tetap unknown, bukan effort parent. Blok runtime Antigravity yang hilang dari klien lama dipertahankan. Setelan ini berlaku untuk SETIAP sesi baru di seluruh workspace. Menyentuh blok Telegram akan memuat ulang gateway.",
10394
10476
  inputSchema: obj({ properties: { settings: WHOLE_BLOCK("setelan") }, required: ["settings"] }),
10395
10477
  mode: "write",
10396
10478
  capability: "settings:write",
@@ -10543,6 +10625,7 @@ var init_agents = __esm({
10543
10625
  "../shared/src/mcp-catalog/agents.ts"() {
10544
10626
  "use strict";
10545
10627
  init_mcp_schema();
10628
+ init_custom_agent();
10546
10629
  init_helpers();
10547
10630
  AGENTS_TOOLS = [
10548
10631
  {
@@ -10564,13 +10647,16 @@ var init_agents = __esm({
10564
10647
  title: "Daftar custom agent",
10565
10648
  description: "Persona custom yang aktif. Tanpa `project` hanya yang global; dengan `project` ia menggabung global + milik project, dan nama yang ditimpa project muncul SEKALI dengan versi project yang menang.",
10566
10649
  inputSchema: obj({
10567
- properties: { project: str("Id project. Kosongkan untuk hanya persona global.") }
10650
+ properties: {
10651
+ project: str("Id project. Kosongkan untuk hanya persona global."),
10652
+ runtime: enumStr(AGENT_RUNTIMES, "Runtime parent untuk availability dan alasan ketidaktersediaan persona.")
10653
+ }
10568
10654
  }),
10569
10655
  mode: "read",
10570
10656
  capability: "agents:read",
10571
10657
  samplePath: "/custom-agents",
10572
10658
  sampleMethod: "GET",
10573
- build: (a) => ({ method: "GET", path: "/custom-agents", query: query({ projectId: s(a.project) }) }),
10659
+ build: (a) => ({ method: "GET", path: "/custom-agents", query: query({ projectId: s(a.project), runtime: s(a.runtime) }) }),
10574
10660
  shape: (raw) => raw
10575
10661
  },
10576
10662
  {
@@ -10584,9 +10670,9 @@ var init_agents = __esm({
10584
10670
  instructions: str("Instruksi persona (1\u201320.000 karakter). Inilah yang dibaca agen."),
10585
10671
  project: str("Id project. Kosongkan untuk persona GLOBAL yang berlaku di semua project."),
10586
10672
  tools: strArray("Tool yang boleh dipakai persona ini. Harus ada di hanoman_agents_catalog. Kosongkan untuk mewarisi."),
10587
- model: str("Model. Harus sah untuk `runtime` yang dipilih."),
10673
+ model: str("Model child. Antigravity hanya tier inherit|flash|pro; effort independen unavailable. Harus sah untuk `runtime` yang dipilih."),
10588
10674
  mentions: strArray("Nama persona lain yang boleh dipanggil."),
10589
- runtime: enumStr(["claude", "codex"], "Penyaring mesin sesi. Kosongkan untuk mengikuti sesi induk."),
10675
+ runtime: enumStr(AGENT_RUNTIMES, "Penyaring mesin sesi. Kosongkan untuk mengikuti sesi induk."),
10590
10676
  enabled: bool("Aktif atau tidak. Default aktif.")
10591
10677
  },
10592
10678
  required: ["name", "description", "instructions"]
@@ -10619,9 +10705,9 @@ var init_agents = __esm({
10619
10705
  description: str("Deskripsi baru."),
10620
10706
  instructions: str("Instruksi baru."),
10621
10707
  tools: strArray("Daftar tool baru."),
10622
- model: str("Model baru."),
10708
+ model: str("Model child baru. Antigravity hanya tier inherit|flash|pro; effort independen unavailable."),
10623
10709
  mentions: strArray("Daftar mention baru."),
10624
- runtime: enumStr(["claude", "codex"], "Penyaring mesin sesi."),
10710
+ runtime: enumStr(AGENT_RUNTIMES, "Penyaring mesin sesi."),
10625
10711
  enabled: bool("Aktif atau tidak.")
10626
10712
  },
10627
10713
  required: ["agent"]
@@ -10666,7 +10752,7 @@ var init_skills = __esm({
10666
10752
  {
10667
10753
  name: "hanoman_skills_list",
10668
10754
  title: "Daftar skill",
10669
- description: "Skill dari semua sumber: global hanoman ($HANOMAN_HOME/skills, disuntik ke setiap sesi), user (~/.claude|~/.codex|~/.agents), plugin (baca-saja), dan per project (.claude/.agents/.codex/skills + folder lain berisi SKILL.md). Tanpa `project`: global + satu grup per project. Dengan `project`: global (bertanda shadowedBy bila ditimpa) + skill project itu.",
10755
+ description: "Skill dari semua sumber: global hanoman ($HANOMAN_HOME/skills, disuntik ke setiap sesi), user (~/.claude|~/.codex|~/.agents|~/.gemini/antigravity-cli), plugin (baca-saja), dan per project (.claude/.agents/.codex/skills + folder lain berisi SKILL.md). Tanpa `project`: global + satu grup per project. Dengan `project`: global (bertanda shadowedBy bila ditimpa) + skill project itu.",
10670
10756
  inputSchema: obj({ properties: { project: str("Id project. Kosongkan untuk semua grup.") } }),
10671
10757
  mode: "read",
10672
10758
  capability: "skills:read",
@@ -10724,7 +10810,7 @@ var init_skills = __esm({
10724
10810
  layer: enumStr(["hanoman", "user", "project"], "Lapis tujuan."),
10725
10811
  name: str("Nama skill (kebab-case)."),
10726
10812
  description: str('Deskripsi \u2014 diawali kapan skill dipakai, mis. "Use when \u2026".'),
10727
- source: enumStr([".claude", ".agents", ".codex"], "Sumber untuk lapis user/project. Default .claude."),
10813
+ source: enumStr([".claude", ".agents", ".codex", ".gemini/antigravity-cli"], "Sumber untuk lapis user/project. .gemini/antigravity-cli hanya user. Default .claude."),
10728
10814
  project: str("Id project (wajib untuk layer project).")
10729
10815
  },
10730
10816
  required: ["layer", "name", "description"]
@@ -10743,13 +10829,13 @@ var init_skills = __esm({
10743
10829
  {
10744
10830
  name: "hanoman_skill_fork",
10745
10831
  title: "Fork skill",
10746
- description: "Menyalin skill mana pun (termasuk plugin yang baca-saja) ke global hanoman atau ke project, supaya bisa disunting. `name` default = nama asal.",
10832
+ description: "Menyalin skill mana pun (termasuk plugin yang baca-saja) ke global hanoman, user, atau project, supaya bisa disunting. `name` default = nama asal.",
10747
10833
  inputSchema: obj({
10748
10834
  properties: {
10749
10835
  key: str("Key skill sumber."),
10750
- layer: enumStr(["hanoman", "project"], "Tujuan. Default hanoman."),
10836
+ layer: enumStr(["hanoman", "user", "project"], "Tujuan. Default hanoman."),
10751
10837
  project: str("Id project (wajib untuk layer project)."),
10752
- source: enumStr([".claude", ".agents", ".codex"], "Sumber tujuan untuk layer project."),
10838
+ source: enumStr([".claude", ".agents", ".codex", ".gemini/antigravity-cli"], "Sumber tujuan user/project; .gemini/antigravity-cli hanya user."),
10753
10839
  name: str("Nama baru (opsional).")
10754
10840
  },
10755
10841
  required: ["key"]
@@ -11309,6 +11395,7 @@ var CORE3, MORE2, SESSIONS_TOOLS;
11309
11395
  var init_sessions = __esm({
11310
11396
  "../shared/src/mcp-catalog/sessions.ts"() {
11311
11397
  "use strict";
11398
+ init_entities();
11312
11399
  init_mcp_schema();
11313
11400
  init_mcp_shape();
11314
11401
  init_helpers();
@@ -11330,7 +11417,7 @@ var init_sessions = __esm({
11330
11417
  {
11331
11418
  name: "hanoman_session_phases",
11332
11419
  title: "Fase sesi",
11333
- description: "Pipeline fase sebuah sesi beserta posisinya sekarang. Menjawab 404 bila sesi itu bukan sesi ber-flow (terminal biasa tak punya fase).",
11420
+ description: "Pipeline fase sebuah sesi beserta posisinya sekarang. Antigravity menggunakan tier child native inherit|flash|pro, effort unknown dan protocol wait asynchronous; reviewer fase read-only instruksional, bukan enforcement runtime. Marker Execute menunggu review independen lulus. Menjawab 404 bila sesi itu bukan sesi ber-flow (terminal biasa tak punya fase).",
11334
11421
  inputSchema: obj({ properties: { session: str("Id sesi, dari hanoman_sessions_list.") }, required: ["session"] }),
11335
11422
  mode: "read",
11336
11423
  capability: "sessions:read",
@@ -11456,10 +11543,25 @@ var init_sessions = __esm({
11456
11543
  build: (a) => ({ method: "POST", path: `/terminal/sessions/${enc(String(a.session))}/interrupt` }),
11457
11544
  shape: (raw) => raw
11458
11545
  },
11546
+ {
11547
+ name: "hanoman_session_rename",
11548
+ title: "Ganti nama sesi",
11549
+ description: "Memberi nama kustom pada sesi terminal (hidup atau yang panenya masih ada) supaya mudah dikenali di Terminal. Nama maksimal 80 karakter, satu baris. Nama kosong menghapus nama kustom dan UI kembali memakai label turunan (backlog/flow/project).",
11550
+ inputSchema: obj({
11551
+ properties: { session: str("Id sesi."), name: str("Nama baru. Kosong = hapus nama kustom.") },
11552
+ required: ["session", "name"]
11553
+ }),
11554
+ mode: "write",
11555
+ capability: "sessions:write",
11556
+ samplePath: "/terminal/sessions/s1",
11557
+ sampleMethod: "PATCH",
11558
+ build: (a) => ({ method: "PATCH", path: `/terminal/sessions/${enc(String(a.session))}`, body: { name: String(a.name) } }),
11559
+ shape: (raw) => raw
11560
+ },
11459
11561
  {
11460
11562
  name: "hanoman_session_create",
11461
11563
  title: "Buka sesi agen baru (BERBAHAYA)",
11462
- description: "BERBAHAYA \u2014 membuka sesi agen BARU: hanoman menjalankan claude/codex dengan IZIN PENUH di worktree project, dan sesi itu bisa menulis berkas, menjalankan perintah, serta membuat commit tanpa manusia di pane. Menuntut capability `sessions:spawn`; `sessions:write` \u2014 yang cukup untuk mengendalikan sesi yang SUDAH ada \u2014 tidak cukup di sini. Panggil hanoman_sessions_list lebih dulu: sesi yang sudah berjalan untuk backlog yang sama akan DILANJUTKAN, bukan digandakan. Hanya muncul saat tingkat `--danger` menyala.",
11564
+ description: "BERBAHAYA \u2014 membuka sesi agen BARU: hanoman menjalankan claude/codex/antigravity dengan IZIN PENUH di worktree project, dan sesi itu bisa menulis berkas, menjalankan perintah, serta membuat commit tanpa manusia di pane. Menuntut capability `sessions:spawn`; `sessions:write` \u2014 yang cukup untuk mengendalikan sesi yang SUDAH ada \u2014 tidak cukup di sini. Panggil hanoman_sessions_list lebih dulu: sesi yang sudah berjalan untuk backlog yang sama akan DILANJUTKAN, bukan digandakan. Hanya muncul saat tingkat `--danger` menyala.",
11463
11565
  inputSchema: obj({
11464
11566
  properties: {
11465
11567
  spec: str("Id backlog, mis. `SPEC-482`. Mengisinya membuka sesi BACKLOG dan mewajibkan `flow`."),
@@ -11469,13 +11571,23 @@ var init_sessions = __esm({
11469
11571
  "Alur sesi. Wajib bila `spec` diisi. `reverse`/`prd`/`breakdown`/`scaffold` adalah sesi tingkat-project dan dipasangkan dengan `project`."
11470
11572
  ),
11471
11573
  shell: bool("true = terminal shell biasa di repo project, tanpa agen. Hanya dengan `project`."),
11472
- agent: enumStr(["claude", "codex"], "Mesin sesi. Kosong = default global."),
11574
+ agent: enumStr(["claude", "codex", "antigravity"], "Mesin sesi. Kosong = default global."),
11473
11575
  model: str("Model. Kosong = default global."),
11474
11576
  effort: str("Effort. Kosong = default global."),
11475
11577
  goal: bool("Mode goal per-sesi. Kosong = ikut setelan global."),
11476
11578
  goalCondition: str("Kondisi selesai mode goal (maks 4000 karakter)."),
11477
11579
  verifyScope: enumStr(["changed", "full"], "Scope verifikasi. Kosong = ikut setelan global."),
11478
11580
  method: str("Metode workflow. Id tak dikenal jatuh ke default, bukan ditolak."),
11581
+ phaseOverrides: {
11582
+ type: "object",
11583
+ maxProperties: PHASE_OVERRIDE_LIMITS.phases,
11584
+ propertyNames: { type: "string", minLength: 1, maxLength: PHASE_OVERRIDE_LIMITS.phase },
11585
+ description: "Override fase backlog. Antigravity memakai tier inherit|flash|pro, effort null; validasi mengikuti runtime efektif.",
11586
+ additionalProperties: obj({ properties: {
11587
+ model: { oneOf: [{ type: "string", minLength: 1, maxLength: PHASE_OVERRIDE_LIMITS.model }, { type: "null" }] },
11588
+ effort: { oneOf: [{ type: "string", minLength: 1, maxLength: PHASE_OVERRIDE_LIMITS.effort }, { type: "null" }] }
11589
+ } })
11590
+ },
11479
11591
  prdPath: str("flow `breakdown`: jalur PRD yang dipecah. WAJIB untuk alur itu."),
11480
11592
  force: bool("Lewati gerbang dependency. Pakai HANYA sesudah melihat daftar pemblokirnya.")
11481
11593
  },
@@ -11496,6 +11608,7 @@ var init_sessions = __esm({
11496
11608
  const body2 = { spec: String(a.spec), flow: String(a.flow) };
11497
11609
  for (const k of ["model", "effort", "goalCondition", "agent", "verifyScope", "method"])
11498
11610
  if (s(a[k]) !== void 0) body2[k] = s(a[k]);
11611
+ if (a.phaseOverrides && typeof a.phaseOverrides === "object" && !Array.isArray(a.phaseOverrides)) body2.phaseOverrides = a.phaseOverrides;
11499
11612
  for (const k of ["goal", "force"]) if (typeof a[k] === "boolean") body2[k] = a[k];
11500
11613
  return { method: "POST", path: "/terminal/sessions", body: body2 };
11501
11614
  }
@@ -12681,10 +12794,10 @@ var init_observability = __esm({
12681
12794
  {
12682
12795
  name: "hanoman_models",
12683
12796
  title: "Katalog model agen",
12684
- description: 'Katalog model claude & codex yang tersedia di MESIN ini: id, label, effort yang diterima, serta status probe per penyedia (`providers`: sumber `cli`/`cache`/`bundled`, kapan terakhir dicek, galatnya). Katalog dibaca dari CLI yang terpasang dan di-refresh server tiap 5 menit, jadi ini jawaban yang benar untuk "model/effort apa yang sah dipakai hanoman_session_create atau hanoman_agent_create" \u2014 jangan menebak id model. Hanya menampilkan data yang sudah disaring parser (detail akun CLI tak pernah tersimpan). Tak menuntut capability apa pun.',
12797
+ description: 'Katalog model claude, codex & antigravity yang tersedia di MESIN ini: id, label, effort yang diterima, serta status probe per penyedia (`providers`: sumber `cli`/`cache`/`bundled`, kapan terakhir dicek, galatnya). Katalog dibaca dari CLI yang terpasang dan di-refresh server tiap 5 menit, jadi ini jawaban yang benar untuk "model/effort apa yang sah dipakai hanoman_session_create atau hanoman_agent_create" \u2014 jangan menebak id model. Hanya menampilkan data yang sudah disaring parser (detail akun CLI tak pernah tersimpan). Tak menuntut capability apa pun.',
12685
12798
  inputSchema: obj({
12686
12799
  properties: {
12687
- agent: enumStr(["claude", "codex"], "Batasi ke satu mesin. Kosong = keduanya.")
12800
+ agent: enumStr(["claude", "codex", "antigravity"], "Batasi ke satu mesin. Kosong = semua runtime.")
12688
12801
  }
12689
12802
  }),
12690
12803
  mode: "read",
@@ -12695,7 +12808,7 @@ var init_observability = __esm({
12695
12808
  shape: (raw, a) => {
12696
12809
  const agent = s(a.agent);
12697
12810
  const r = raw ?? {};
12698
- if (agent !== "claude" && agent !== "codex") return raw;
12811
+ if (agent !== "claude" && agent !== "codex" && agent !== "antigravity") return raw;
12699
12812
  const providers = r.providers ?? {};
12700
12813
  return { [agent]: r[agent], providers: { [agent]: providers[agent] } };
12701
12814
  }
@@ -12712,10 +12825,22 @@ var init_observability = __esm({
12712
12825
  build: () => ({ method: "GET", path: "/codex/version" }),
12713
12826
  shape: (raw) => raw
12714
12827
  },
12828
+ {
12829
+ name: "hanoman_antigravity_version",
12830
+ title: "Versi Antigravity CLI",
12831
+ description: "Versi Antigravity CLI pada boundary sesi saat ini: `{version,error}`. Versi semver atau null beserta alasan aman bila biner hilang, timeout, keluaran tidak dikenal, atau sandbox belum didukung. Tidak memuat keluaran CLI mentah atau kredensial; kegagalan observasi tidak memblokir sesi host. Cache 5 menit, invalidasi saat biner/boundary berubah. Tak menuntut capability apa pun.",
12832
+ inputSchema: obj({ properties: {} }),
12833
+ mode: "read",
12834
+ capability: null,
12835
+ samplePath: "/antigravity/version",
12836
+ sampleMethod: "GET",
12837
+ build: () => ({ method: "GET", path: "/antigravity/version" }),
12838
+ shape: (raw) => raw
12839
+ },
12715
12840
  {
12716
12841
  name: "hanoman_methods_status",
12717
12842
  title: "Kesiapan metode workflow",
12718
- description: "Metode workflow mana yang benar-benar siap dipakai di MESIN ini, per agen (claude/codex): skill/paket apa yang sudah terpasang dan apa yang masih kurang. Diturunkan dari disk tiap dipanggil (tanpa cache), jadi hasilnya segar sesudah operator memasang skill. Baca-saja dan tak pernah memblokir kelahiran sesi \u2014 metode yang belum siap hanya ditandai; memasangnya tetap tindakan manusia di dashboard. Berisi path home/roots skill di mesin. Tak menuntut capability apa pun.",
12843
+ description: "Metode workflow mana yang benar-benar siap dipakai di MESIN ini, per agen (claude/codex/antigravity; installer Antigravity unavailable sampai upstream terverifikasi): skill/paket apa yang sudah terpasang dan apa yang masih kurang. Diturunkan dari disk tiap dipanggil (tanpa cache), jadi hasilnya segar sesudah operator memasang skill. Baca-saja dan tak pernah memblokir kelahiran sesi \u2014 metode yang belum siap hanya ditandai; memasangnya tetap tindakan manusia di dashboard. Berisi path home/roots skill di mesin. Tak menuntut capability apa pun.",
12719
12844
  inputSchema: obj({ properties: {} }),
12720
12845
  mode: "read",
12721
12846
  capability: null,
@@ -13383,7 +13508,7 @@ var init_gates = __esm({
13383
13508
  name: str("Nama cron (1\u2013120 karakter)."),
13384
13509
  expr: str("Cron expression 5 kolom (menit jam tanggal bulan hari-minggu), mis. `0 7 * * *`. Ekspresi tak sah ditolak 400."),
13385
13510
  prompt: str("Prompt awal yang dikirim ke sesi agen setiap kali cron jatuh tempo (maks 8000 karakter).", { maxLength: 8e3 }),
13386
- agent: enumStr(["claude", "codex"], "Mesin sesi. Kosong = default global."),
13511
+ agent: enumStr(["claude", "codex", "antigravity"], "Mesin sesi. Kosong = default global."),
13387
13512
  model: str("Model. Kosong = default global."),
13388
13513
  effort: str("Effort. Kosong = default global.")
13389
13514
  };
@@ -13420,6 +13545,45 @@ var init_gates = __esm({
13420
13545
  }),
13421
13546
  shape: (raw) => raw
13422
13547
  },
13548
+ {
13549
+ name: "hanoman_scheduler_reports",
13550
+ title: "Daftar laporan run cron",
13551
+ description: "Laporan hasil run cron (ADR-0222): pesan akhir agen yang disimpan sebagai dokumen markdown, satu per run, tersync antar mesin. Amplop berhalaman `{items,total,page,pageSize}`, terbaru dulu, TANPA isi (`id`, `cronId`, `cronName`, `runDate`, `dueAt`, `bytes`, `filename`). Isi dibaca lewat hanoman_scheduler_report_get. Saring menurut `cron` / `project`; cron dari mesin lain tetap terdaftar (cron tak harus ada di instance ini).",
13552
+ inputSchema: obj({ properties: {
13553
+ cron: str("Saring menurut id cron."),
13554
+ project: str("Saring menurut id project."),
13555
+ ...PAGE_PARAMS
13556
+ } }),
13557
+ mode: "read",
13558
+ capability: "scheduler:read",
13559
+ samplePath: "/scheduler/reports",
13560
+ sampleMethod: "GET",
13561
+ build: (a) => ({
13562
+ method: "GET",
13563
+ path: "/scheduler/reports",
13564
+ query: query({ cronId: s(a.cron), projectId: s(a.project), page: n(a.page)?.toString(), limit: n(a.limit)?.toString() })
13565
+ }),
13566
+ shape: (raw) => raw
13567
+ },
13568
+ {
13569
+ name: "hanoman_scheduler_report_get",
13570
+ title: "Baca laporan run cron",
13571
+ description: 'Baca SATU laporan run cron berikut isi markdown-nya (`body`) dan `filename` turunan. `report` = id laporan (sama dengan id run), atau `latest` (default) untuk laporan terbaru \u2014 saring dengan `cron` / `project`. 404 bila belum ada laporan. Contoh laporan terakhir sebuah cron: `{cron:"<id cron>"}`.',
13572
+ inputSchema: obj({ properties: {
13573
+ report: str("Id laporan, atau `latest` (default)."),
13574
+ cron: str("Untuk `latest`: batasi ke id cron ini."),
13575
+ project: str("Untuk `latest`: batasi ke id project ini.")
13576
+ } }),
13577
+ mode: "read",
13578
+ capability: "scheduler:read",
13579
+ samplePath: "/scheduler/reports/latest",
13580
+ sampleMethod: "GET",
13581
+ build: (a) => {
13582
+ const id = s(a.report);
13583
+ return id && id !== "latest" ? { method: "GET", path: `/scheduler/reports/${enc(id)}` } : { method: "GET", path: "/scheduler/reports/latest", query: query({ cronId: s(a.cron), projectId: s(a.project) }) };
13584
+ },
13585
+ shape: (raw) => raw
13586
+ },
13423
13587
  {
13424
13588
  name: "hanoman_scheduler_cron_create",
13425
13589
  title: "Buat cronjob (BERBAHAYA)",
@@ -14701,6 +14865,16 @@ var init_mcp = __esm({
14701
14865
  }
14702
14866
  });
14703
14867
 
14868
+ // ../shared/src/cron-report.ts
14869
+ var CRON_REPORT_MAX_BYTES, enc2;
14870
+ var init_cron_report = __esm({
14871
+ "../shared/src/cron-report.ts"() {
14872
+ "use strict";
14873
+ CRON_REPORT_MAX_BYTES = 64 * 1024;
14874
+ enc2 = new TextEncoder();
14875
+ }
14876
+ });
14877
+
14704
14878
  // ../shared/src/terminal-workspace.ts
14705
14879
  var zSessionId, zTrackSizes, zTerminalGroup, zTerminalWorkspaceV1, zTerminalWorkspaceWrite, zTerminalWorkspaceSnapshot;
14706
14880
  var init_terminal_workspace = __esm({
@@ -14867,6 +15041,7 @@ var PRESENCE_PROTOCOL, MAX_PRESENCE_SESSIONS, PRESENCE_MAX_FRAME_BYTES, zPresenc
14867
15041
  var init_presence = __esm({
14868
15042
  "../shared/src/presence.ts"() {
14869
15043
  "use strict";
15044
+ init_enums();
14870
15045
  init_zod();
14871
15046
  init_session_admission();
14872
15047
  PRESENCE_PROTOCOL = 1;
@@ -14879,7 +15054,7 @@ var init_presence = __esm({
14879
15054
  flow: external_exports.string().max(40).optional(),
14880
15055
  /** Fase `active` dari `readPhases()`. Absen = sesi tanpa berkas fase (mis. konsol VPS). */
14881
15056
  phase: external_exports.string().max(80).optional(),
14882
- agent: external_exports.enum(["claude", "codex"]),
15057
+ agent: zAgent,
14883
15058
  status: external_exports.enum(["working", "waiting", "exited"]),
14884
15059
  startedAt: external_exports.string().max(40)
14885
15060
  }).strict();
@@ -14914,6 +15089,7 @@ var init_pending = __esm({
14914
15089
  var init_model_catalog = __esm({
14915
15090
  "../shared/src/model-catalog.ts"() {
14916
15091
  "use strict";
15092
+ init_antigravity();
14917
15093
  init_entities();
14918
15094
  }
14919
15095
  });
@@ -14968,6 +15144,7 @@ var init_src = __esm({
14968
15144
  init_auto_merge();
14969
15145
  init_handled_by();
14970
15146
  init_cron_expr();
15147
+ init_cron_report();
14971
15148
  init_terminal_workspace();
14972
15149
  init_terminal_io();
14973
15150
  init_session_dialog();
@@ -14981,6 +15158,7 @@ var init_src = __esm({
14981
15158
  init_model_catalog();
14982
15159
  init_runtime_defaults();
14983
15160
  init_skills2();
15161
+ init_antigravity();
14984
15162
  }
14985
15163
  });
14986
15164
 
@@ -15383,6 +15561,7 @@ import { homedir as homedir2 } from "node:os";
15383
15561
  import { basename, dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
15384
15562
  import { existsSync, readdirSync, readFileSync } from "node:fs";
15385
15563
  function agentSkillHome(agent, env = process.env, osHome = homedir2()) {
15564
+ if (agent === "antigravity") return join2(osHome, ".gemini", "antigravity-cli");
15386
15565
  const own = (agent === "codex" ? env.HANOMAN_CODEX_HOME : env.HANOMAN_CLAUDE_HOME)?.trim();
15387
15566
  if (own) return own;
15388
15567
  if (agent === "codex") {
@@ -15477,12 +15656,13 @@ function cacheRoots(home) {
15477
15656
  const out = [];
15478
15657
  for (const marketplace of dirsIn(cache))
15479
15658
  for (const pkg of dirsIn(join2(cache, marketplace)))
15480
- for (const version3 of dirsIn(join2(cache, marketplace, pkg)))
15481
- out.push({ pkg, marketplace, dir: join2(cache, marketplace, pkg, version3) });
15659
+ for (const version2 of dirsIn(join2(cache, marketplace, pkg)))
15660
+ out.push({ pkg, marketplace, dir: join2(cache, marketplace, pkg, version2) });
15482
15661
  return out;
15483
15662
  }
15484
15663
  function disabledPlugins(agent, home) {
15485
15664
  const out = /* @__PURE__ */ new Set();
15665
+ if (agent === "antigravity") return out;
15486
15666
  if (agent === "claude") {
15487
15667
  const en = readJson(join2(home, "settings.json"))?.enabledPlugins;
15488
15668
  if (en && typeof en === "object") {
@@ -15530,7 +15710,7 @@ function scanAgentSkills(agent, env = process.env, osHome = homedir2()) {
15530
15710
  };
15531
15711
  const userDir = join2(home, "skills");
15532
15712
  add(userDir, skillsUnder(userDir, null));
15533
- for (const r of [...manifestRoots(home), ...cacheRoots(home)]) {
15713
+ for (const r of agent === "antigravity" ? [] : [...manifestRoots(home), ...cacheRoots(home)]) {
15534
15714
  if (disabled.has(`${r.pkg}@${r.marketplace}`)) continue;
15535
15715
  const found = pluginSkills(r.dir, r.pkg);
15536
15716
  if (!found.length) continue;
@@ -15645,6 +15825,25 @@ var init_config_env = __esm({
15645
15825
  }
15646
15826
  });
15647
15827
 
15828
+ // ../runner/src/agent-env.ts
15829
+ function agentEnvironment(agent, env) {
15830
+ const result = { ...env };
15831
+ if (agent === "antigravity") {
15832
+ delete result.CLAUDE_CODE_OAUTH_TOKEN;
15833
+ delete result.ANTHROPIC_API_KEY;
15834
+ } else {
15835
+ for (const key of ANTIGRAVITY_ENV_KEYS) delete result[key];
15836
+ }
15837
+ return result;
15838
+ }
15839
+ var ANTIGRAVITY_ENV_KEYS;
15840
+ var init_agent_env = __esm({
15841
+ "../runner/src/agent-env.ts"() {
15842
+ "use strict";
15843
+ ANTIGRAVITY_ENV_KEYS = ["GEMINI_API_KEY", "GOOGLE_GEMINI_BASE_URL"];
15844
+ }
15845
+ });
15846
+
15648
15847
  // ../runner/src/sandbox-probe.ts
15649
15848
  import { execFileSync } from "node:child_process";
15650
15849
  import { accessSync, constants } from "node:fs";
@@ -15709,15 +15908,15 @@ function prerequisites(env, facts) {
15709
15908
  function allReady(rows) {
15710
15909
  return rows.every((r) => r.ok);
15711
15910
  }
15712
- function run(file, args) {
15911
+ function run(file, args, env) {
15713
15912
  try {
15714
- return execFileSync(file, args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
15913
+ return execFileSync(file, args, { encoding: "utf8", env: agentEnvironment(null, env), stdio: ["ignore", "pipe", "ignore"] }).trim();
15715
15914
  } catch {
15716
15915
  return null;
15717
15916
  }
15718
15917
  }
15719
15918
  function collectProbeFacts(env) {
15720
- const podman = run("podman", ["--version"]);
15919
+ const podman = run("podman", ["--version"], env);
15721
15920
  const network = env.HANOMAN_SESSION_NETWORK ?? "hanoman-egress";
15722
15921
  const dir = env.HANOMAN_AGENT_CREDENTIAL_DIR;
15723
15922
  let credentialDirReadable = false;
@@ -15730,8 +15929,8 @@ function collectProbeFacts(env) {
15730
15929
  }
15731
15930
  return {
15732
15931
  podman,
15733
- rootless: podman ? run("podman", ["info", "--format", "{{.Host.Security.Rootless}}"]) === "true" : false,
15734
- networkExists: podman ? run("podman", ["network", "exists", network]) !== null : false,
15932
+ rootless: podman ? run("podman", ["info", "--format", "{{.Host.Security.Rootless}}"], env) === "true" : false,
15933
+ networkExists: podman ? run("podman", ["network", "exists", network], env) !== null : false,
15735
15934
  credentialDirReadable
15736
15935
  };
15737
15936
  }
@@ -15739,6 +15938,7 @@ var filled2;
15739
15938
  var init_sandbox_probe = __esm({
15740
15939
  "../runner/src/sandbox-probe.ts"() {
15741
15940
  "use strict";
15941
+ init_agent_env();
15742
15942
  filled2 = (v) => !!v && v.trim() !== "";
15743
15943
  }
15744
15944
  });
@@ -15795,6 +15995,16 @@ var init_skill_files = __esm({
15795
15995
  }
15796
15996
  });
15797
15997
 
15998
+ // ../runner/src/antigravity-agent-config.ts
15999
+ var init_antigravity_agent_config = __esm({
16000
+ "../runner/src/antigravity-agent-config.ts"() {
16001
+ "use strict";
16002
+ init_src();
16003
+ init_agent_env();
16004
+ init_custom_agents();
16005
+ }
16006
+ });
16007
+
15798
16008
  // ../runner/src/index.ts
15799
16009
  var init_src2 = __esm({
15800
16010
  "../runner/src/index.ts"() {
@@ -15826,6 +16036,8 @@ var init_src2 = __esm({
15826
16036
  init_subagent_statusline();
15827
16037
  init_skill_library();
15828
16038
  init_skill_files();
16039
+ init_agent_env();
16040
+ init_antigravity_agent_config();
15829
16041
  }
15830
16042
  });
15831
16043
 
@@ -16211,6 +16423,8 @@ var doctor_exports = {};
16211
16423
  __export(doctor_exports, {
16212
16424
  default: () => doctor,
16213
16425
  doctorReport: () => doctorReport,
16426
+ probeDoctorVersion: () => probeDoctorVersion,
16427
+ resolveDoctorAntigravityBin: () => resolveDoctorAntigravityBin,
16214
16428
  resolveDoctorCodexBin: () => resolveDoctorCodexBin
16215
16429
  });
16216
16430
  import { execFileSync as execFileSync4 } from "node:child_process";
@@ -16228,6 +16442,11 @@ function doctorReport(p3) {
16228
16442
  text: p3.codex ? `codex ${p3.codex} \u2014 custom agent native ${codexNativeAgentsSupported(p3.codex) ? "siap" : `butuh >= ${CODEX_NATIVE_AGENTS_MIN_CLIENT}; sesi parent tetap bisa berjalan`}` : "codex \u2014 tak ada",
16229
16443
  fatal: false
16230
16444
  },
16445
+ {
16446
+ mark: p3.antigravity ? p3.sandboxRequired ? "!" : "\u2713" : "\xB7",
16447
+ text: p3.antigravity ? `Antigravity CLI ${p3.antigravity} \u2014 auth manual; ${p3.sandboxRequired ? "sandbox belum didukung" : "host/lab; jalankan agy untuk login; autentikasi belum diverifikasi"}` : p3.sandboxRequired ? "Antigravity CLI \u2014 host/lab saja; sandbox belum didukung; probe/login tidak dijalankan" : "Antigravity CLI \u2014 tak ada (opsional; install/login manual)",
16448
+ fatal: false
16449
+ },
16231
16450
  // SPEC-471 · ADR-0095 · `gh` opsional: tanpa dia tarik issue jatuh ke HTTPS + GITHUB_TOKEN.
16232
16451
  {
16233
16452
  mark: p3.gh ? "\u2713" : "\xB7",
@@ -16257,16 +16476,16 @@ function doctorReport(p3) {
16257
16476
  }
16258
16477
  ];
16259
16478
  for (const m of p3.methods) {
16260
- const agent = m.agent === "codex" ? "Codex CLI" : "Claude Code";
16479
+ const agent = m.agent === "antigravity" ? "Antigravity CLI" : m.agent === "codex" ? "Codex CLI" : "Claude Code";
16261
16480
  rows.push({
16262
16481
  mark: m.ready ? "\u2713" : "!",
16263
- text: m.ready ? `metode ${m.method} \xB7 ${agent} \u2014 siap` : `metode ${m.method} \xB7 ${agent} \u2014 belum siap: ` + [...m.missingPackages, ...m.missingSkills].join(", ") + m.install.map((c) => `
16482
+ text: m.available === false ? `metode ${m.method} \xB7 ${agent} \u2014 tidak tersedia: ${m.availabilityReason}` : m.ready ? `metode ${m.method} \xB7 ${agent} \u2014 siap` : `metode ${m.method} \xB7 ${agent} \u2014 belum siap: ` + [...m.missingPackages, ...m.missingSkills].join(", ") + m.install.map((c) => `
16264
16483
  ${c}`).join(""),
16265
16484
  fatal: false
16266
16485
  });
16267
16486
  }
16268
- if (!p3.claude && !p3.codex) {
16269
- rows.push({ mark: "\u2717", text: "tak ada CLI agen (claude ATAU codex wajib ada)", fatal: true });
16487
+ if (!p3.claude && !p3.codex && (!p3.antigravity || p3.sandboxRequired)) {
16488
+ rows.push({ mark: "\u2717", text: "tak ada CLI agen (claude, codex ATAU Antigravity host/lab wajib ada)", fatal: true });
16270
16489
  }
16271
16490
  return { lines: rows.map((r) => ` ${r.mark} ${r.text}`), ok: !rows.some((r) => r.fatal) };
16272
16491
  }
@@ -16285,9 +16504,23 @@ function writable(path) {
16285
16504
  p3 = up;
16286
16505
  }
16287
16506
  }
16288
- function version(bin, args) {
16507
+ function probeDoctorVersion(bin, args, env, agent = null) {
16508
+ if (agent === "antigravity" && (resolveHardening(env) || (env.HANOMAN_SESSION_SANDBOX ?? "off") !== "off")) return null;
16289
16509
  try {
16290
- return execFileSync4(bin, args, { encoding: "utf8", timeout: 1e4, stdio: ["ignore", "pipe", "ignore"] }).trim().split("\n")[0] ?? null;
16510
+ const output = execFileSync4(bin, args, {
16511
+ encoding: "utf8",
16512
+ env: agentEnvironment(agent, env),
16513
+ timeout: 1e4,
16514
+ ...agent === "antigravity" ? { maxBuffer: 16 * 1024, killSignal: "SIGKILL" } : {},
16515
+ stdio: ["ignore", "pipe", "ignore"]
16516
+ }).trim();
16517
+ if (agent === "antigravity") {
16518
+ const numeric = "(?:0|[1-9]\\d*)";
16519
+ const identifier = "(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)";
16520
+ const semver = new RegExp(`^${numeric}\\.${numeric}\\.${numeric}(?:-${identifier}(?:\\.${identifier})*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$`);
16521
+ return semver.test(output) ? output : null;
16522
+ }
16523
+ return output.split("\n")[0] || null;
16291
16524
  } catch {
16292
16525
  return null;
16293
16526
  }
@@ -16300,6 +16533,14 @@ async function resolveDoctorCodexBin(env, dbUrl, read = readRuntimeConfig) {
16300
16533
  }
16301
16534
  return env.HANOMAN_CODEX_BIN?.trim() || "codex";
16302
16535
  }
16536
+ async function resolveDoctorAntigravityBin(env, dbUrl, read = readRuntimeConfig) {
16537
+ try {
16538
+ const configured = (await read(dbUrl, "HANOMAN_ANTIGRAVITY_BIN"))?.trim();
16539
+ if (configured) return configured;
16540
+ } catch {
16541
+ }
16542
+ return env.HANOMAN_ANTIGRAVITY_BIN?.trim() || "agy";
16543
+ }
16303
16544
  async function doctor(_argv, ctx) {
16304
16545
  let layout;
16305
16546
  let db;
@@ -16320,11 +16561,13 @@ async function doctor(_argv, ctx) {
16320
16561
  { label: "upload", path: d.uploads, writable: writable(d.uploads), fatal: false },
16321
16562
  { label: "key SSH", path: d.sshKeys, writable: writable(d.sshKeys), fatal: false }
16322
16563
  ];
16323
- const claude = version(ctx.env.HANOMAN_CLAUDE_BIN ?? "claude", ["--version"]);
16564
+ const version2 = (bin, args) => probeDoctorVersion(bin, args, ctx.env);
16565
+ const claude = version2(ctx.env.HANOMAN_CLAUDE_BIN ?? "claude", ["--version"]);
16566
+ const antigravity = probeDoctorVersion(await resolveDoctorAntigravityBin(ctx.env, dbUrl), ["--version"], ctx.env, "antigravity");
16324
16567
  const codexProbe = codexNativeVersionProbe(ctx.env, await resolveDoctorCodexBin(ctx.env, dbUrl));
16325
- const codex = version(codexProbe.bin, codexProbe.args);
16568
+ const codex = version2(codexProbe.bin, codexProbe.args);
16326
16569
  const method = METHODS[DEFAULT_METHOD];
16327
- const methods = zAgent.options.filter((a) => (a === "codex" ? codex : claude) !== null).map((a) => {
16570
+ const methods = zAgent.options.filter((a) => ({ claude, codex, antigravity })[a] !== null).map((a) => {
16328
16571
  const s2 = scanAgentSkills(a, ctx.env);
16329
16572
  return methodStatus(method, a, { skills: s2.skills.map((k) => k.id), packages: s2.packages });
16330
16573
  });
@@ -16334,12 +16577,13 @@ async function doctor(_argv, ctx) {
16334
16577
  const sandboxReady = allReady(prerequisites(ctx.env, podmanFacts));
16335
16578
  const r = doctorReport({
16336
16579
  node: process.version,
16337
- git: version("git", ["--version"]),
16338
- tmux: version("tmux", ["-V"]),
16580
+ git: version2("git", ["--version"]),
16581
+ tmux: version2("tmux", ["-V"]),
16339
16582
  claude,
16340
16583
  codex,
16341
- gh: version(ctx.env.HANOMAN_GH_BIN ?? "gh", ["--version"]),
16342
- curl: version("curl", ["--version"]),
16584
+ antigravity,
16585
+ gh: version2(ctx.env.HANOMAN_GH_BIN ?? "gh", ["--version"]),
16586
+ curl: version2("curl", ["--version"]),
16343
16587
  dirs,
16344
16588
  web: layout.web !== null,
16345
16589
  db,
@@ -17423,10 +17667,10 @@ var init_regexes = __esm({
17423
17667
  nanoid = /^[a-zA-Z0-9_-]{21}$/;
17424
17668
  duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
17425
17669
  guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
17426
- uuid = (version3) => {
17427
- if (!version3)
17670
+ uuid = (version2) => {
17671
+ if (!version2)
17428
17672
  return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
17429
- return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version3}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
17673
+ return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
17430
17674
  };
17431
17675
  email = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;
17432
17676
  _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
@@ -17894,10 +18138,10 @@ var init_doc = __esm({
17894
18138
  });
17895
18139
 
17896
18140
  // ../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js
17897
- var version2;
18141
+ var version;
17898
18142
  var init_versions = __esm({
17899
18143
  "../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js"() {
17900
- version2 = {
18144
+ version = {
17901
18145
  major: 4,
17902
18146
  minor: 4,
17903
18147
  patch: 3
@@ -18203,7 +18447,7 @@ var init_schemas = __esm({
18203
18447
  inst ?? (inst = {});
18204
18448
  inst._zod.def = def;
18205
18449
  inst._zod.bag = inst._zod.bag || {};
18206
- inst._zod.version = version2;
18450
+ inst._zod.version = version;
18207
18451
  const checks = [...inst._zod.def.checks ?? []];
18208
18452
  if (inst._zod.traits.has("$ZodCheck")) {
18209
18453
  checks.unshift(inst);
@@ -23288,14 +23532,14 @@ function missingClientCapabilities(required2, declared) {
23288
23532
  }
23289
23533
  return Object.keys(missing).length > 0 ? missing : void 0;
23290
23534
  }
23291
- function isModernProtocolVersion(version3) {
23292
- return version3 >= FIRST_MODERN_PROTOCOL_VERSION;
23535
+ function isModernProtocolVersion(version2) {
23536
+ return version2 >= FIRST_MODERN_PROTOCOL_VERSION;
23293
23537
  }
23294
23538
  function legacyProtocolVersions(versions) {
23295
- return versions.filter((version3) => !isModernProtocolVersion(version3));
23539
+ return versions.filter((version2) => !isModernProtocolVersion(version2));
23296
23540
  }
23297
23541
  function modernProtocolVersions(versions) {
23298
- return versions.filter((version3) => isModernProtocolVersion(version3));
23542
+ return versions.filter((version2) => isModernProtocolVersion(version2));
23299
23543
  }
23300
23544
  function appendTextFallbackForNonObject(result) {
23301
23545
  const sc = result.structuredContent;
@@ -25409,8 +25653,8 @@ function getWireResultSchemas() {
25409
25653
  };
25410
25654
  return wireResultSchemasMemo;
25411
25655
  }
25412
- function codecForVersion(version3) {
25413
- return version3 !== void 0 && isModernProtocolVersion(version3) ? rev2026Codec : rev2025Codec;
25656
+ function codecForVersion(version2) {
25657
+ return version2 !== void 0 && isModernProtocolVersion(version2) ? rev2026Codec : rev2025Codec;
25414
25658
  }
25415
25659
  function classifiedWireEra(classification) {
25416
25660
  if (classification.revision !== void 0) return codecForVersion(classification.revision).era;
@@ -25847,8 +26091,8 @@ function withRequestStateValue(ctx, value) {
25847
26091
  }
25848
26092
  };
25849
26093
  }
25850
- function setNegotiatedProtocolVersion(instance, version3) {
25851
- writeNegotiatedProtocolVersion(instance, version3);
26094
+ function setNegotiatedProtocolVersion(instance, version2) {
26095
+ writeNegotiatedProtocolVersion(instance, version2);
25852
26096
  }
25853
26097
  function isPlainObject$1(value) {
25854
26098
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -27078,8 +27322,8 @@ var init_src_CX2iR2pK = __esm({
27078
27322
  */
27079
27323
  _negotiatedProtocolVersion;
27080
27324
  static {
27081
- writeNegotiatedProtocolVersion = (instance, version3) => {
27082
- instance._negotiatedProtocolVersion = version3;
27325
+ writeNegotiatedProtocolVersion = (instance, version2) => {
27326
+ instance._negotiatedProtocolVersion = version2;
27083
27327
  };
27084
27328
  }
27085
27329
  _supportedProtocolVersions;
@@ -35294,7 +35538,7 @@ var init_mcp_DXXb3Vv3 = __esm({
35294
35538
  if (identity.clientInfo !== void 0) server._clientVersion = identity.clientInfo;
35295
35539
  };
35296
35540
  installDiscoverHandler = (server, servedModernVersions) => {
35297
- const missing = servedModernVersions.filter((version3) => !server._supportedProtocolVersions.includes(version3));
35541
+ const missing = servedModernVersions.filter((version2) => !server._supportedProtocolVersions.includes(version2));
35298
35542
  if (missing.length > 0) server._supportedProtocolVersions = [...server._supportedProtocolVersions, ...missing];
35299
35543
  server.setRequestHandler("server/discover", () => server._ondiscover());
35300
35544
  };
@@ -36852,8 +37096,8 @@ var init_stdio = __esm({
36852
37096
  if (this._outboundIntercept?.(message) === "handled") return;
36853
37097
  return this._wire.send(message, options);
36854
37098
  }
36855
- setProtocolVersion = (version3) => {
36856
- this._wire.setProtocolVersion?.(version3);
37099
+ setProtocolVersion = (version2) => {
37100
+ this._wire.setProtocolVersion?.(version2);
36857
37101
  };
36858
37102
  /** Forwards one inbound message to the connected instance. */
36859
37103
  deliver(message, extra) {
@@ -37642,7 +37886,7 @@ function localScriptPath(cwd = process.cwd()) {
37642
37886
  }
37643
37887
  function runScript(env, ctx) {
37644
37888
  return new Promise((resolve6) => {
37645
- const p3 = spawn2("bash", [localScriptPath(ctx.cwd)], { env: { ...process.env, ...env } });
37889
+ const p3 = spawn2("bash", [localScriptPath(ctx.cwd)], { env: { ...agentEnvironment(null, ctx.env), ...env } });
37646
37890
  p3.stdout.on("data", (d) => ctx.stdout(String(d)));
37647
37891
  p3.stderr.on("data", (d) => ctx.stderr(String(d)));
37648
37892
  p3.on("close", (code) => resolve6(code ?? 1));
@@ -37677,6 +37921,7 @@ var PROFILES, flag;
37677
37921
  var init_provision = __esm({
37678
37922
  "src/commands/provision.ts"() {
37679
37923
  "use strict";
37924
+ init_src2();
37680
37925
  PROFILES = ["lab", "production"];
37681
37926
  flag = (args, name) => args.find((a) => a.startsWith(`--${name}=`))?.split("=").slice(1).join("=");
37682
37927
  }
@@ -37920,7 +38165,9 @@ var init_migrate_pg = __esm({
37920
38165
  "QaReport",
37921
38166
  "QaCase",
37922
38167
  "QaFinding",
37923
- "QaAttachment"
38168
+ "QaAttachment",
38169
+ // ADR-0222 · CronReport sesudah Project (FK projectId, cascade); tak ada di sumber Postgres lama.
38170
+ "CronReport"
37924
38171
  ];
37925
38172
  CHUNK = 200;
37926
38173
  INT8_OID = 20;
@@ -38164,10 +38411,10 @@ var init_docs_link = __esm({
38164
38411
 
38165
38412
  // src/release/pack.ts
38166
38413
  import { join as join15 } from "node:path";
38167
- function packageJsonFor(version3, deps) {
38414
+ function packageJsonFor(version2, deps) {
38168
38415
  return {
38169
38416
  name: PKG_NAME,
38170
- version: version3,
38417
+ version: version2,
38171
38418
  description: "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
38172
38419
  type: "module",
38173
38420
  repository: { type: "git", url: REPO_URL },
@@ -38297,8 +38544,8 @@ async function pack(argv, ctx) {
38297
38544
  }
38298
38545
  const outIdx = argv.indexOf("--out");
38299
38546
  const out = outIdx === -1 ? join16(repo, "dist-npm") : join16(repo, argv[outIdx + 1] ?? "dist-npm");
38300
- const version3 = JSON.parse(readFileSync9(join16(repo, "package.json"), "utf8")).version;
38301
- if (!version3) {
38547
+ const version2 = JSON.parse(readFileSync9(join16(repo, "package.json"), "utf8")).version;
38548
+ if (!version2) {
38302
38549
  ctx.stderr("pack: root package.json tanpa field version\n");
38303
38550
  return 1;
38304
38551
  }
@@ -38323,14 +38570,14 @@ async function pack(argv, ctx) {
38323
38570
  cpSync(item.from, dest, item.dir ? { recursive: true } : {});
38324
38571
  }
38325
38572
  writeFileSync3(join16(out, "bin/hanoman.mjs"), BIN_SHIM);
38326
- writeFileSync3(join16(out, "package.json"), JSON.stringify(packageJsonFor(version3, deps), null, 2) + "\n");
38573
+ writeFileSync3(join16(out, "package.json"), JSON.stringify(packageJsonFor(version2, deps), null, 2) + "\n");
38327
38574
  const missing = REQUIRED_ARTIFACTS.filter((a) => !existsSync10(join16(out, a)));
38328
38575
  if (missing.length) {
38329
38576
  ctx.stderr(`pack: artefak wajib hilang: ${missing.join(", ")}
38330
38577
  `);
38331
38578
  return 1;
38332
38579
  }
38333
- ctx.stdout(`pack \xB7 ${out} \xB7 hanoman@${version3} \xB7 ${REQUIRED_ARTIFACTS.length} artefak wajib ada
38580
+ ctx.stdout(`pack \xB7 ${out} \xB7 hanoman@${version2} \xB7 ${REQUIRED_ARTIFACTS.length} artefak wajib ada
38334
38581
  `);
38335
38582
  ctx.stdout("terbitkan MANUAL: cd dist-npm && npm publish --otp <kode>\n");
38336
38583
  return 0;
@@ -38439,10 +38686,10 @@ var init_router = __esm({
38439
38686
  doctor periksa prasyarat: node, git, tmux, CLI agen, data dir
38440
38687
  update [--check] bandingkan versi dengan registry npm; pasang yang terbaru
38441
38688
  provision [--with=a,b] [--probe] pasang komponen di MESIN INI (hanoman, caddy, claude,
38442
- [--profile=lab|production] codex, gh, \u2026). --probe hanya melaporkan apa yang ada.
38689
+ [--profile=lab|production] codex, antigravity (host/lab), gh, \u2026). --probe hanya melaporkan apa yang ada.
38443
38690
  [--domain=<d>] [--dry-run] [--yes]
38444
38691
  mcp [--read-only] [--host <url>] MCP server stdio untuk klien AI (Claude Code/Desktop,
38445
- [--max-bytes <n>] Codex, Cursor, Copilot). Token dari HANOMAN_AGENT_TOKEN.
38692
+ [--max-bytes <n>] Codex, Antigravity, Cursor, Copilot). Token dari HANOMAN_AGENT_TOKEN.
38446
38693
  [--transfer-dir <d>] direktori tambahan untuk unggah/unduh berkas (ADR-0183)
38447
38694
  migrate-from-postgres --from <url> pindahkan data Postgres lama ke SQLite
38448
38695
  [--to <file>] [--dry-run] [--force]