hanoman 0.9.28 → 0.9.30
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.
- package/README.md +5 -2
- package/dist/build-info.json +3 -3
- package/dist/cli.js +360 -90
- package/dist/server.js +2904 -1418
- package/docs/agent-integration.md +100 -6
- package/package.json +1 -1
- package/prisma/migrations/20261014130000_cron_report/migration.sql +19 -0
- package/prisma/schema.prisma +25 -0
- package/scripts/vps/provision.sh +26 -3
- package/web/assets/{DalangHanomanScreen-C3UMPHFg.js → DalangHanomanScreen-Fd7_DcSP.js} +1 -1
- package/web/assets/{DocPreviewModal-Bp5stb4M.js → DocPreviewModal-SMRN2K98.js} +1 -1
- package/web/assets/{DocsWorkspace-C9yFxK4D.js → DocsWorkspace-pxj0N6QW.js} +1 -1
- package/web/assets/{IdeScreen-CRFRAP6E.js → IdeScreen-Cr9Vqdrc.js} +1 -1
- package/web/assets/LeadScreen-CQXpJy0y.js +1 -0
- package/web/assets/{ReviewScreen-CMHOlmgX.js → ReviewScreen-B7NNEjxk.js} +1 -1
- package/web/assets/SchedulerScreen-D3rPdS-F.js +1 -0
- package/web/assets/SettingsScreen-Bx13PWKQ.js +62 -0
- package/web/assets/{TeamScreen-D4tA34Mj.js → TeamScreen-BBAsYLpT.js} +1 -1
- package/web/assets/TerminalScreen-DpVp4h1n.js +2 -0
- package/web/assets/{TriageScreen-B8ZCexaX.js → TriageScreen-wAPnttRe.js} +1 -1
- package/web/assets/{VpsScreen-BCrLfZh7.js → VpsScreen-DeQVx9Jy.js} +2 -2
- package/web/assets/fields-qnBoIMR_.js +1 -0
- package/web/assets/index-BQw6xQI4.js +1012 -0
- package/web/assets/{index-BqAP-VDq.css → index-C3KwOJxI.css} +2 -2
- package/web/assets/{live-DuBdI0MZ.js → live-CONO0GTu.js} +1 -1
- package/web/assets/{sched-lead-shared-QqbtjoVv.js → sched-lead-shared-CDR0pOqs.js} +1 -1
- package/web/assets/{scheduler-CQt-VP9-.css → scheduler-D64RlGvZ.css} +1 -1
- package/web/assets/settings-rebase-CpaFw0Tm.js +1 -0
- package/web/index.html +2 -2
- package/web/assets/LeadScreen-DfVUawoK.js +0 -1
- package/web/assets/SchedulerScreen-CK5QvX5c.js +0 -1
- package/web/assets/SettingsScreen-D7P5JgjU.js +0 -62
- package/web/assets/TerminalScreen-CKySL63X.js +0 -2
- package/web/assets/index-BRR3JL_o.js +0 -1012
- 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,
|
|
586
|
-
if ((
|
|
585
|
+
function isValidIP(ip, version2) {
|
|
586
|
+
if ((version2 === "v4" || !version2) && ipv4Regex.test(ip)) {
|
|
587
587
|
return true;
|
|
588
588
|
}
|
|
589
|
-
if ((
|
|
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,
|
|
617
|
-
if ((
|
|
616
|
+
function isValidCidr(ip, version2) {
|
|
617
|
+
if ((version2 === "v4" || !version2) && ipv4CidrRegex.test(ip)) {
|
|
618
618
|
return true;
|
|
619
619
|
}
|
|
620
|
-
if ((
|
|
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
|
-
|
|
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) => ({
|
|
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(
|
|
5193
|
-
const parsed =
|
|
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",
|
|
@@ -8096,6 +8178,17 @@ var init_config_registry = __esm({
|
|
|
8096
8178
|
// runtime
|
|
8097
8179
|
{ key: "HANOMAN_EVENTS_TICK_MS", group: "runtime", label: "Interval events (ms)", kind: "int", apply: "live", category: "knob", example: "1000", default: "1000", min: 100 },
|
|
8098
8180
|
{ key: "HANOMAN_UPDATE_FETCH", group: "runtime", label: "Deteksi update saat boot", kind: "bool", apply: "live", category: "knob", default: "1" },
|
|
8181
|
+
// ADR-0224 · limit Antigravity membaca token agy di Keychain dan memanggil Cloud Code API Google.
|
|
8182
|
+
{
|
|
8183
|
+
key: "HANOMAN_ANTIGRAVITY_LIMITS_FETCH",
|
|
8184
|
+
group: "runtime",
|
|
8185
|
+
label: "Baca limit Antigravity",
|
|
8186
|
+
kind: "bool",
|
|
8187
|
+
apply: "live",
|
|
8188
|
+
category: "knob",
|
|
8189
|
+
default: "1",
|
|
8190
|
+
help: "Membaca token agy di Keychain macOS lalu memanggil API kuota Google (endpoint internal, tak terdokumentasi). Matikan bila tak ingin hanoman menyentuh kredensial agy."
|
|
8191
|
+
},
|
|
8099
8192
|
// SPEC-398 · ADR-0087 · deteksi update kini membandingkan semver dengan registry npm, bukan
|
|
8100
8193
|
// menghitung commit di repo git (HANOMAN_REPO_ROOT dicabut bersama jalur git itu).
|
|
8101
8194
|
{
|
|
@@ -10378,7 +10471,7 @@ var init_settings = __esm({
|
|
|
10378
10471
|
{
|
|
10379
10472
|
name: "hanoman_settings_get",
|
|
10380
10473
|
title: "Baca setelan instance",
|
|
10381
|
-
description: "Seluruh setelan instance:
|
|
10474
|
+
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
10475
|
inputSchema: obj({ properties: {} }),
|
|
10383
10476
|
mode: "read",
|
|
10384
10477
|
capability: "settings:read",
|
|
@@ -10390,7 +10483,7 @@ var init_settings = __esm({
|
|
|
10390
10483
|
{
|
|
10391
10484
|
name: "hanoman_settings_set",
|
|
10392
10485
|
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.",
|
|
10486
|
+
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
10487
|
inputSchema: obj({ properties: { settings: WHOLE_BLOCK("setelan") }, required: ["settings"] }),
|
|
10395
10488
|
mode: "write",
|
|
10396
10489
|
capability: "settings:write",
|
|
@@ -10543,6 +10636,7 @@ var init_agents = __esm({
|
|
|
10543
10636
|
"../shared/src/mcp-catalog/agents.ts"() {
|
|
10544
10637
|
"use strict";
|
|
10545
10638
|
init_mcp_schema();
|
|
10639
|
+
init_custom_agent();
|
|
10546
10640
|
init_helpers();
|
|
10547
10641
|
AGENTS_TOOLS = [
|
|
10548
10642
|
{
|
|
@@ -10564,13 +10658,16 @@ var init_agents = __esm({
|
|
|
10564
10658
|
title: "Daftar custom agent",
|
|
10565
10659
|
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
10660
|
inputSchema: obj({
|
|
10567
|
-
properties: {
|
|
10661
|
+
properties: {
|
|
10662
|
+
project: str("Id project. Kosongkan untuk hanya persona global."),
|
|
10663
|
+
runtime: enumStr(AGENT_RUNTIMES, "Runtime parent untuk availability dan alasan ketidaktersediaan persona.")
|
|
10664
|
+
}
|
|
10568
10665
|
}),
|
|
10569
10666
|
mode: "read",
|
|
10570
10667
|
capability: "agents:read",
|
|
10571
10668
|
samplePath: "/custom-agents",
|
|
10572
10669
|
sampleMethod: "GET",
|
|
10573
|
-
build: (a) => ({ method: "GET", path: "/custom-agents", query: query({ projectId: s(a.project) }) }),
|
|
10670
|
+
build: (a) => ({ method: "GET", path: "/custom-agents", query: query({ projectId: s(a.project), runtime: s(a.runtime) }) }),
|
|
10574
10671
|
shape: (raw) => raw
|
|
10575
10672
|
},
|
|
10576
10673
|
{
|
|
@@ -10584,9 +10681,9 @@ var init_agents = __esm({
|
|
|
10584
10681
|
instructions: str("Instruksi persona (1\u201320.000 karakter). Inilah yang dibaca agen."),
|
|
10585
10682
|
project: str("Id project. Kosongkan untuk persona GLOBAL yang berlaku di semua project."),
|
|
10586
10683
|
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."),
|
|
10684
|
+
model: str("Model child. Antigravity hanya tier inherit|flash|pro; effort independen unavailable. Harus sah untuk `runtime` yang dipilih."),
|
|
10588
10685
|
mentions: strArray("Nama persona lain yang boleh dipanggil."),
|
|
10589
|
-
runtime: enumStr(
|
|
10686
|
+
runtime: enumStr(AGENT_RUNTIMES, "Penyaring mesin sesi. Kosongkan untuk mengikuti sesi induk."),
|
|
10590
10687
|
enabled: bool("Aktif atau tidak. Default aktif.")
|
|
10591
10688
|
},
|
|
10592
10689
|
required: ["name", "description", "instructions"]
|
|
@@ -10619,9 +10716,9 @@ var init_agents = __esm({
|
|
|
10619
10716
|
description: str("Deskripsi baru."),
|
|
10620
10717
|
instructions: str("Instruksi baru."),
|
|
10621
10718
|
tools: strArray("Daftar tool baru."),
|
|
10622
|
-
model: str("Model baru."),
|
|
10719
|
+
model: str("Model child baru. Antigravity hanya tier inherit|flash|pro; effort independen unavailable."),
|
|
10623
10720
|
mentions: strArray("Daftar mention baru."),
|
|
10624
|
-
runtime: enumStr(
|
|
10721
|
+
runtime: enumStr(AGENT_RUNTIMES, "Penyaring mesin sesi."),
|
|
10625
10722
|
enabled: bool("Aktif atau tidak.")
|
|
10626
10723
|
},
|
|
10627
10724
|
required: ["agent"]
|
|
@@ -10666,7 +10763,7 @@ var init_skills = __esm({
|
|
|
10666
10763
|
{
|
|
10667
10764
|
name: "hanoman_skills_list",
|
|
10668
10765
|
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.",
|
|
10766
|
+
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
10767
|
inputSchema: obj({ properties: { project: str("Id project. Kosongkan untuk semua grup.") } }),
|
|
10671
10768
|
mode: "read",
|
|
10672
10769
|
capability: "skills:read",
|
|
@@ -10724,7 +10821,7 @@ var init_skills = __esm({
|
|
|
10724
10821
|
layer: enumStr(["hanoman", "user", "project"], "Lapis tujuan."),
|
|
10725
10822
|
name: str("Nama skill (kebab-case)."),
|
|
10726
10823
|
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."),
|
|
10824
|
+
source: enumStr([".claude", ".agents", ".codex", ".gemini/antigravity-cli"], "Sumber untuk lapis user/project. .gemini/antigravity-cli hanya user. Default .claude."),
|
|
10728
10825
|
project: str("Id project (wajib untuk layer project).")
|
|
10729
10826
|
},
|
|
10730
10827
|
required: ["layer", "name", "description"]
|
|
@@ -10743,13 +10840,13 @@ var init_skills = __esm({
|
|
|
10743
10840
|
{
|
|
10744
10841
|
name: "hanoman_skill_fork",
|
|
10745
10842
|
title: "Fork skill",
|
|
10746
|
-
description: "Menyalin skill mana pun (termasuk plugin yang baca-saja) ke global hanoman atau
|
|
10843
|
+
description: "Menyalin skill mana pun (termasuk plugin yang baca-saja) ke global hanoman, user, atau project, supaya bisa disunting. `name` default = nama asal.",
|
|
10747
10844
|
inputSchema: obj({
|
|
10748
10845
|
properties: {
|
|
10749
10846
|
key: str("Key skill sumber."),
|
|
10750
|
-
layer: enumStr(["hanoman", "project"], "Tujuan. Default hanoman."),
|
|
10847
|
+
layer: enumStr(["hanoman", "user", "project"], "Tujuan. Default hanoman."),
|
|
10751
10848
|
project: str("Id project (wajib untuk layer project)."),
|
|
10752
|
-
source: enumStr([".claude", ".agents", ".codex"], "Sumber tujuan
|
|
10849
|
+
source: enumStr([".claude", ".agents", ".codex", ".gemini/antigravity-cli"], "Sumber tujuan user/project; .gemini/antigravity-cli hanya user."),
|
|
10753
10850
|
name: str("Nama baru (opsional).")
|
|
10754
10851
|
},
|
|
10755
10852
|
required: ["key"]
|
|
@@ -11309,6 +11406,7 @@ var CORE3, MORE2, SESSIONS_TOOLS;
|
|
|
11309
11406
|
var init_sessions = __esm({
|
|
11310
11407
|
"../shared/src/mcp-catalog/sessions.ts"() {
|
|
11311
11408
|
"use strict";
|
|
11409
|
+
init_entities();
|
|
11312
11410
|
init_mcp_schema();
|
|
11313
11411
|
init_mcp_shape();
|
|
11314
11412
|
init_helpers();
|
|
@@ -11330,7 +11428,7 @@ var init_sessions = __esm({
|
|
|
11330
11428
|
{
|
|
11331
11429
|
name: "hanoman_session_phases",
|
|
11332
11430
|
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).",
|
|
11431
|
+
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
11432
|
inputSchema: obj({ properties: { session: str("Id sesi, dari hanoman_sessions_list.") }, required: ["session"] }),
|
|
11335
11433
|
mode: "read",
|
|
11336
11434
|
capability: "sessions:read",
|
|
@@ -11456,10 +11554,25 @@ var init_sessions = __esm({
|
|
|
11456
11554
|
build: (a) => ({ method: "POST", path: `/terminal/sessions/${enc(String(a.session))}/interrupt` }),
|
|
11457
11555
|
shape: (raw) => raw
|
|
11458
11556
|
},
|
|
11557
|
+
{
|
|
11558
|
+
name: "hanoman_session_rename",
|
|
11559
|
+
title: "Ganti nama sesi",
|
|
11560
|
+
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).",
|
|
11561
|
+
inputSchema: obj({
|
|
11562
|
+
properties: { session: str("Id sesi."), name: str("Nama baru. Kosong = hapus nama kustom.") },
|
|
11563
|
+
required: ["session", "name"]
|
|
11564
|
+
}),
|
|
11565
|
+
mode: "write",
|
|
11566
|
+
capability: "sessions:write",
|
|
11567
|
+
samplePath: "/terminal/sessions/s1",
|
|
11568
|
+
sampleMethod: "PATCH",
|
|
11569
|
+
build: (a) => ({ method: "PATCH", path: `/terminal/sessions/${enc(String(a.session))}`, body: { name: String(a.name) } }),
|
|
11570
|
+
shape: (raw) => raw
|
|
11571
|
+
},
|
|
11459
11572
|
{
|
|
11460
11573
|
name: "hanoman_session_create",
|
|
11461
11574
|
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.",
|
|
11575
|
+
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
11576
|
inputSchema: obj({
|
|
11464
11577
|
properties: {
|
|
11465
11578
|
spec: str("Id backlog, mis. `SPEC-482`. Mengisinya membuka sesi BACKLOG dan mewajibkan `flow`."),
|
|
@@ -11469,13 +11582,23 @@ var init_sessions = __esm({
|
|
|
11469
11582
|
"Alur sesi. Wajib bila `spec` diisi. `reverse`/`prd`/`breakdown`/`scaffold` adalah sesi tingkat-project dan dipasangkan dengan `project`."
|
|
11470
11583
|
),
|
|
11471
11584
|
shell: bool("true = terminal shell biasa di repo project, tanpa agen. Hanya dengan `project`."),
|
|
11472
|
-
agent: enumStr(["claude", "codex"], "Mesin sesi. Kosong = default global."),
|
|
11585
|
+
agent: enumStr(["claude", "codex", "antigravity"], "Mesin sesi. Kosong = default global."),
|
|
11473
11586
|
model: str("Model. Kosong = default global."),
|
|
11474
11587
|
effort: str("Effort. Kosong = default global."),
|
|
11475
11588
|
goal: bool("Mode goal per-sesi. Kosong = ikut setelan global."),
|
|
11476
11589
|
goalCondition: str("Kondisi selesai mode goal (maks 4000 karakter)."),
|
|
11477
11590
|
verifyScope: enumStr(["changed", "full"], "Scope verifikasi. Kosong = ikut setelan global."),
|
|
11478
11591
|
method: str("Metode workflow. Id tak dikenal jatuh ke default, bukan ditolak."),
|
|
11592
|
+
phaseOverrides: {
|
|
11593
|
+
type: "object",
|
|
11594
|
+
maxProperties: PHASE_OVERRIDE_LIMITS.phases,
|
|
11595
|
+
propertyNames: { type: "string", minLength: 1, maxLength: PHASE_OVERRIDE_LIMITS.phase },
|
|
11596
|
+
description: "Override fase backlog. Antigravity memakai tier inherit|flash|pro, effort null; validasi mengikuti runtime efektif.",
|
|
11597
|
+
additionalProperties: obj({ properties: {
|
|
11598
|
+
model: { oneOf: [{ type: "string", minLength: 1, maxLength: PHASE_OVERRIDE_LIMITS.model }, { type: "null" }] },
|
|
11599
|
+
effort: { oneOf: [{ type: "string", minLength: 1, maxLength: PHASE_OVERRIDE_LIMITS.effort }, { type: "null" }] }
|
|
11600
|
+
} })
|
|
11601
|
+
},
|
|
11479
11602
|
prdPath: str("flow `breakdown`: jalur PRD yang dipecah. WAJIB untuk alur itu."),
|
|
11480
11603
|
force: bool("Lewati gerbang dependency. Pakai HANYA sesudah melihat daftar pemblokirnya.")
|
|
11481
11604
|
},
|
|
@@ -11496,6 +11619,7 @@ var init_sessions = __esm({
|
|
|
11496
11619
|
const body2 = { spec: String(a.spec), flow: String(a.flow) };
|
|
11497
11620
|
for (const k of ["model", "effort", "goalCondition", "agent", "verifyScope", "method"])
|
|
11498
11621
|
if (s(a[k]) !== void 0) body2[k] = s(a[k]);
|
|
11622
|
+
if (a.phaseOverrides && typeof a.phaseOverrides === "object" && !Array.isArray(a.phaseOverrides)) body2.phaseOverrides = a.phaseOverrides;
|
|
11499
11623
|
for (const k of ["goal", "force"]) if (typeof a[k] === "boolean") body2[k] = a[k];
|
|
11500
11624
|
return { method: "POST", path: "/terminal/sessions", body: body2 };
|
|
11501
11625
|
}
|
|
@@ -12582,6 +12706,18 @@ var init_system = __esm({
|
|
|
12582
12706
|
build: () => ({ method: "GET", path: "/limits/codex" }),
|
|
12583
12707
|
shape: (raw) => raw
|
|
12584
12708
|
},
|
|
12709
|
+
{
|
|
12710
|
+
name: "hanoman_limits_antigravity",
|
|
12711
|
+
title: "Sisa kuota Antigravity",
|
|
12712
|
+
description: "Sisa kuota Antigravity CLI (agy) per grup model (Gemini; Claude/GPT) untuk jendela mingguan dan 5 jam, berikut kapan resetnya. Dibaca live dari Cloud Code API Google memakai token agy yang sedang hidup dan di-cache 60 detik; token yang kedaluwarsa (agy tak berjalan) memberi `stale` atau `unavailable`, bukan angka karangan. Endpoint terpisah dari hanoman_limits karena sumbernya beda. Tak menuntut capability apa pun.",
|
|
12713
|
+
inputSchema: obj({ properties: {} }),
|
|
12714
|
+
mode: "read",
|
|
12715
|
+
capability: null,
|
|
12716
|
+
samplePath: "/limits/antigravity",
|
|
12717
|
+
sampleMethod: "GET",
|
|
12718
|
+
build: () => ({ method: "GET", path: "/limits/antigravity" }),
|
|
12719
|
+
shape: (raw) => raw
|
|
12720
|
+
},
|
|
12585
12721
|
{
|
|
12586
12722
|
name: "hanoman_overview_get",
|
|
12587
12723
|
title: "Ringkasan kinerja hari ini (Overview)",
|
|
@@ -12681,10 +12817,10 @@ var init_observability = __esm({
|
|
|
12681
12817
|
{
|
|
12682
12818
|
name: "hanoman_models",
|
|
12683
12819
|
title: "Katalog model agen",
|
|
12684
|
-
description: 'Katalog model claude &
|
|
12820
|
+
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
12821
|
inputSchema: obj({
|
|
12686
12822
|
properties: {
|
|
12687
|
-
agent: enumStr(["claude", "codex"], "Batasi ke satu mesin. Kosong =
|
|
12823
|
+
agent: enumStr(["claude", "codex", "antigravity"], "Batasi ke satu mesin. Kosong = semua runtime.")
|
|
12688
12824
|
}
|
|
12689
12825
|
}),
|
|
12690
12826
|
mode: "read",
|
|
@@ -12695,7 +12831,7 @@ var init_observability = __esm({
|
|
|
12695
12831
|
shape: (raw, a) => {
|
|
12696
12832
|
const agent = s(a.agent);
|
|
12697
12833
|
const r = raw ?? {};
|
|
12698
|
-
if (agent !== "claude" && agent !== "codex") return raw;
|
|
12834
|
+
if (agent !== "claude" && agent !== "codex" && agent !== "antigravity") return raw;
|
|
12699
12835
|
const providers = r.providers ?? {};
|
|
12700
12836
|
return { [agent]: r[agent], providers: { [agent]: providers[agent] } };
|
|
12701
12837
|
}
|
|
@@ -12712,10 +12848,22 @@ var init_observability = __esm({
|
|
|
12712
12848
|
build: () => ({ method: "GET", path: "/codex/version" }),
|
|
12713
12849
|
shape: (raw) => raw
|
|
12714
12850
|
},
|
|
12851
|
+
{
|
|
12852
|
+
name: "hanoman_antigravity_version",
|
|
12853
|
+
title: "Versi Antigravity CLI",
|
|
12854
|
+
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.",
|
|
12855
|
+
inputSchema: obj({ properties: {} }),
|
|
12856
|
+
mode: "read",
|
|
12857
|
+
capability: null,
|
|
12858
|
+
samplePath: "/antigravity/version",
|
|
12859
|
+
sampleMethod: "GET",
|
|
12860
|
+
build: () => ({ method: "GET", path: "/antigravity/version" }),
|
|
12861
|
+
shape: (raw) => raw
|
|
12862
|
+
},
|
|
12715
12863
|
{
|
|
12716
12864
|
name: "hanoman_methods_status",
|
|
12717
12865
|
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.",
|
|
12866
|
+
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
12867
|
inputSchema: obj({ properties: {} }),
|
|
12720
12868
|
mode: "read",
|
|
12721
12869
|
capability: null,
|
|
@@ -13383,7 +13531,7 @@ var init_gates = __esm({
|
|
|
13383
13531
|
name: str("Nama cron (1\u2013120 karakter)."),
|
|
13384
13532
|
expr: str("Cron expression 5 kolom (menit jam tanggal bulan hari-minggu), mis. `0 7 * * *`. Ekspresi tak sah ditolak 400."),
|
|
13385
13533
|
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."),
|
|
13534
|
+
agent: enumStr(["claude", "codex", "antigravity"], "Mesin sesi. Kosong = default global."),
|
|
13387
13535
|
model: str("Model. Kosong = default global."),
|
|
13388
13536
|
effort: str("Effort. Kosong = default global.")
|
|
13389
13537
|
};
|
|
@@ -13420,6 +13568,45 @@ var init_gates = __esm({
|
|
|
13420
13568
|
}),
|
|
13421
13569
|
shape: (raw) => raw
|
|
13422
13570
|
},
|
|
13571
|
+
{
|
|
13572
|
+
name: "hanoman_scheduler_reports",
|
|
13573
|
+
title: "Daftar laporan run cron",
|
|
13574
|
+
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).",
|
|
13575
|
+
inputSchema: obj({ properties: {
|
|
13576
|
+
cron: str("Saring menurut id cron."),
|
|
13577
|
+
project: str("Saring menurut id project."),
|
|
13578
|
+
...PAGE_PARAMS
|
|
13579
|
+
} }),
|
|
13580
|
+
mode: "read",
|
|
13581
|
+
capability: "scheduler:read",
|
|
13582
|
+
samplePath: "/scheduler/reports",
|
|
13583
|
+
sampleMethod: "GET",
|
|
13584
|
+
build: (a) => ({
|
|
13585
|
+
method: "GET",
|
|
13586
|
+
path: "/scheduler/reports",
|
|
13587
|
+
query: query({ cronId: s(a.cron), projectId: s(a.project), page: n(a.page)?.toString(), limit: n(a.limit)?.toString() })
|
|
13588
|
+
}),
|
|
13589
|
+
shape: (raw) => raw
|
|
13590
|
+
},
|
|
13591
|
+
{
|
|
13592
|
+
name: "hanoman_scheduler_report_get",
|
|
13593
|
+
title: "Baca laporan run cron",
|
|
13594
|
+
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>"}`.',
|
|
13595
|
+
inputSchema: obj({ properties: {
|
|
13596
|
+
report: str("Id laporan, atau `latest` (default)."),
|
|
13597
|
+
cron: str("Untuk `latest`: batasi ke id cron ini."),
|
|
13598
|
+
project: str("Untuk `latest`: batasi ke id project ini.")
|
|
13599
|
+
} }),
|
|
13600
|
+
mode: "read",
|
|
13601
|
+
capability: "scheduler:read",
|
|
13602
|
+
samplePath: "/scheduler/reports/latest",
|
|
13603
|
+
sampleMethod: "GET",
|
|
13604
|
+
build: (a) => {
|
|
13605
|
+
const id = s(a.report);
|
|
13606
|
+
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) }) };
|
|
13607
|
+
},
|
|
13608
|
+
shape: (raw) => raw
|
|
13609
|
+
},
|
|
13423
13610
|
{
|
|
13424
13611
|
name: "hanoman_scheduler_cron_create",
|
|
13425
13612
|
title: "Buat cronjob (BERBAHAYA)",
|
|
@@ -14701,6 +14888,16 @@ var init_mcp = __esm({
|
|
|
14701
14888
|
}
|
|
14702
14889
|
});
|
|
14703
14890
|
|
|
14891
|
+
// ../shared/src/cron-report.ts
|
|
14892
|
+
var CRON_REPORT_MAX_BYTES, enc2;
|
|
14893
|
+
var init_cron_report = __esm({
|
|
14894
|
+
"../shared/src/cron-report.ts"() {
|
|
14895
|
+
"use strict";
|
|
14896
|
+
CRON_REPORT_MAX_BYTES = 64 * 1024;
|
|
14897
|
+
enc2 = new TextEncoder();
|
|
14898
|
+
}
|
|
14899
|
+
});
|
|
14900
|
+
|
|
14704
14901
|
// ../shared/src/terminal-workspace.ts
|
|
14705
14902
|
var zSessionId, zTrackSizes, zTerminalGroup, zTerminalWorkspaceV1, zTerminalWorkspaceWrite, zTerminalWorkspaceSnapshot;
|
|
14706
14903
|
var init_terminal_workspace = __esm({
|
|
@@ -14867,6 +15064,7 @@ var PRESENCE_PROTOCOL, MAX_PRESENCE_SESSIONS, PRESENCE_MAX_FRAME_BYTES, zPresenc
|
|
|
14867
15064
|
var init_presence = __esm({
|
|
14868
15065
|
"../shared/src/presence.ts"() {
|
|
14869
15066
|
"use strict";
|
|
15067
|
+
init_enums();
|
|
14870
15068
|
init_zod();
|
|
14871
15069
|
init_session_admission();
|
|
14872
15070
|
PRESENCE_PROTOCOL = 1;
|
|
@@ -14879,7 +15077,7 @@ var init_presence = __esm({
|
|
|
14879
15077
|
flow: external_exports.string().max(40).optional(),
|
|
14880
15078
|
/** Fase `active` dari `readPhases()`. Absen = sesi tanpa berkas fase (mis. konsol VPS). */
|
|
14881
15079
|
phase: external_exports.string().max(80).optional(),
|
|
14882
|
-
agent:
|
|
15080
|
+
agent: zAgent,
|
|
14883
15081
|
status: external_exports.enum(["working", "waiting", "exited"]),
|
|
14884
15082
|
startedAt: external_exports.string().max(40)
|
|
14885
15083
|
}).strict();
|
|
@@ -14914,6 +15112,7 @@ var init_pending = __esm({
|
|
|
14914
15112
|
var init_model_catalog = __esm({
|
|
14915
15113
|
"../shared/src/model-catalog.ts"() {
|
|
14916
15114
|
"use strict";
|
|
15115
|
+
init_antigravity();
|
|
14917
15116
|
init_entities();
|
|
14918
15117
|
}
|
|
14919
15118
|
});
|
|
@@ -14968,6 +15167,7 @@ var init_src = __esm({
|
|
|
14968
15167
|
init_auto_merge();
|
|
14969
15168
|
init_handled_by();
|
|
14970
15169
|
init_cron_expr();
|
|
15170
|
+
init_cron_report();
|
|
14971
15171
|
init_terminal_workspace();
|
|
14972
15172
|
init_terminal_io();
|
|
14973
15173
|
init_session_dialog();
|
|
@@ -14981,6 +15181,7 @@ var init_src = __esm({
|
|
|
14981
15181
|
init_model_catalog();
|
|
14982
15182
|
init_runtime_defaults();
|
|
14983
15183
|
init_skills2();
|
|
15184
|
+
init_antigravity();
|
|
14984
15185
|
}
|
|
14985
15186
|
});
|
|
14986
15187
|
|
|
@@ -15383,6 +15584,7 @@ import { homedir as homedir2 } from "node:os";
|
|
|
15383
15584
|
import { basename, dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
|
|
15384
15585
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
15385
15586
|
function agentSkillHome(agent, env = process.env, osHome = homedir2()) {
|
|
15587
|
+
if (agent === "antigravity") return join2(osHome, ".gemini", "antigravity-cli");
|
|
15386
15588
|
const own = (agent === "codex" ? env.HANOMAN_CODEX_HOME : env.HANOMAN_CLAUDE_HOME)?.trim();
|
|
15387
15589
|
if (own) return own;
|
|
15388
15590
|
if (agent === "codex") {
|
|
@@ -15477,12 +15679,13 @@ function cacheRoots(home) {
|
|
|
15477
15679
|
const out = [];
|
|
15478
15680
|
for (const marketplace of dirsIn(cache))
|
|
15479
15681
|
for (const pkg of dirsIn(join2(cache, marketplace)))
|
|
15480
|
-
for (const
|
|
15481
|
-
out.push({ pkg, marketplace, dir: join2(cache, marketplace, pkg,
|
|
15682
|
+
for (const version2 of dirsIn(join2(cache, marketplace, pkg)))
|
|
15683
|
+
out.push({ pkg, marketplace, dir: join2(cache, marketplace, pkg, version2) });
|
|
15482
15684
|
return out;
|
|
15483
15685
|
}
|
|
15484
15686
|
function disabledPlugins(agent, home) {
|
|
15485
15687
|
const out = /* @__PURE__ */ new Set();
|
|
15688
|
+
if (agent === "antigravity") return out;
|
|
15486
15689
|
if (agent === "claude") {
|
|
15487
15690
|
const en = readJson(join2(home, "settings.json"))?.enabledPlugins;
|
|
15488
15691
|
if (en && typeof en === "object") {
|
|
@@ -15530,7 +15733,7 @@ function scanAgentSkills(agent, env = process.env, osHome = homedir2()) {
|
|
|
15530
15733
|
};
|
|
15531
15734
|
const userDir = join2(home, "skills");
|
|
15532
15735
|
add(userDir, skillsUnder(userDir, null));
|
|
15533
|
-
for (const r of [...manifestRoots(home), ...cacheRoots(home)]) {
|
|
15736
|
+
for (const r of agent === "antigravity" ? [] : [...manifestRoots(home), ...cacheRoots(home)]) {
|
|
15534
15737
|
if (disabled.has(`${r.pkg}@${r.marketplace}`)) continue;
|
|
15535
15738
|
const found = pluginSkills(r.dir, r.pkg);
|
|
15536
15739
|
if (!found.length) continue;
|
|
@@ -15645,6 +15848,25 @@ var init_config_env = __esm({
|
|
|
15645
15848
|
}
|
|
15646
15849
|
});
|
|
15647
15850
|
|
|
15851
|
+
// ../runner/src/agent-env.ts
|
|
15852
|
+
function agentEnvironment(agent, env) {
|
|
15853
|
+
const result = { ...env };
|
|
15854
|
+
if (agent === "antigravity") {
|
|
15855
|
+
delete result.CLAUDE_CODE_OAUTH_TOKEN;
|
|
15856
|
+
delete result.ANTHROPIC_API_KEY;
|
|
15857
|
+
} else {
|
|
15858
|
+
for (const key of ANTIGRAVITY_ENV_KEYS) delete result[key];
|
|
15859
|
+
}
|
|
15860
|
+
return result;
|
|
15861
|
+
}
|
|
15862
|
+
var ANTIGRAVITY_ENV_KEYS;
|
|
15863
|
+
var init_agent_env = __esm({
|
|
15864
|
+
"../runner/src/agent-env.ts"() {
|
|
15865
|
+
"use strict";
|
|
15866
|
+
ANTIGRAVITY_ENV_KEYS = ["GEMINI_API_KEY", "GOOGLE_GEMINI_BASE_URL"];
|
|
15867
|
+
}
|
|
15868
|
+
});
|
|
15869
|
+
|
|
15648
15870
|
// ../runner/src/sandbox-probe.ts
|
|
15649
15871
|
import { execFileSync } from "node:child_process";
|
|
15650
15872
|
import { accessSync, constants } from "node:fs";
|
|
@@ -15709,15 +15931,15 @@ function prerequisites(env, facts) {
|
|
|
15709
15931
|
function allReady(rows) {
|
|
15710
15932
|
return rows.every((r) => r.ok);
|
|
15711
15933
|
}
|
|
15712
|
-
function run(file, args) {
|
|
15934
|
+
function run(file, args, env) {
|
|
15713
15935
|
try {
|
|
15714
|
-
return execFileSync(file, args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
15936
|
+
return execFileSync(file, args, { encoding: "utf8", env: agentEnvironment(null, env), stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
15715
15937
|
} catch {
|
|
15716
15938
|
return null;
|
|
15717
15939
|
}
|
|
15718
15940
|
}
|
|
15719
15941
|
function collectProbeFacts(env) {
|
|
15720
|
-
const podman = run("podman", ["--version"]);
|
|
15942
|
+
const podman = run("podman", ["--version"], env);
|
|
15721
15943
|
const network = env.HANOMAN_SESSION_NETWORK ?? "hanoman-egress";
|
|
15722
15944
|
const dir = env.HANOMAN_AGENT_CREDENTIAL_DIR;
|
|
15723
15945
|
let credentialDirReadable = false;
|
|
@@ -15730,8 +15952,8 @@ function collectProbeFacts(env) {
|
|
|
15730
15952
|
}
|
|
15731
15953
|
return {
|
|
15732
15954
|
podman,
|
|
15733
|
-
rootless: podman ? run("podman", ["info", "--format", "{{.Host.Security.Rootless}}"]) === "true" : false,
|
|
15734
|
-
networkExists: podman ? run("podman", ["network", "exists", network]) !== null : false,
|
|
15955
|
+
rootless: podman ? run("podman", ["info", "--format", "{{.Host.Security.Rootless}}"], env) === "true" : false,
|
|
15956
|
+
networkExists: podman ? run("podman", ["network", "exists", network], env) !== null : false,
|
|
15735
15957
|
credentialDirReadable
|
|
15736
15958
|
};
|
|
15737
15959
|
}
|
|
@@ -15739,6 +15961,7 @@ var filled2;
|
|
|
15739
15961
|
var init_sandbox_probe = __esm({
|
|
15740
15962
|
"../runner/src/sandbox-probe.ts"() {
|
|
15741
15963
|
"use strict";
|
|
15964
|
+
init_agent_env();
|
|
15742
15965
|
filled2 = (v) => !!v && v.trim() !== "";
|
|
15743
15966
|
}
|
|
15744
15967
|
});
|
|
@@ -15795,6 +16018,16 @@ var init_skill_files = __esm({
|
|
|
15795
16018
|
}
|
|
15796
16019
|
});
|
|
15797
16020
|
|
|
16021
|
+
// ../runner/src/antigravity-agent-config.ts
|
|
16022
|
+
var init_antigravity_agent_config = __esm({
|
|
16023
|
+
"../runner/src/antigravity-agent-config.ts"() {
|
|
16024
|
+
"use strict";
|
|
16025
|
+
init_src();
|
|
16026
|
+
init_agent_env();
|
|
16027
|
+
init_custom_agents();
|
|
16028
|
+
}
|
|
16029
|
+
});
|
|
16030
|
+
|
|
15798
16031
|
// ../runner/src/index.ts
|
|
15799
16032
|
var init_src2 = __esm({
|
|
15800
16033
|
"../runner/src/index.ts"() {
|
|
@@ -15826,6 +16059,8 @@ var init_src2 = __esm({
|
|
|
15826
16059
|
init_subagent_statusline();
|
|
15827
16060
|
init_skill_library();
|
|
15828
16061
|
init_skill_files();
|
|
16062
|
+
init_agent_env();
|
|
16063
|
+
init_antigravity_agent_config();
|
|
15829
16064
|
}
|
|
15830
16065
|
});
|
|
15831
16066
|
|
|
@@ -16211,6 +16446,8 @@ var doctor_exports = {};
|
|
|
16211
16446
|
__export(doctor_exports, {
|
|
16212
16447
|
default: () => doctor,
|
|
16213
16448
|
doctorReport: () => doctorReport,
|
|
16449
|
+
probeDoctorVersion: () => probeDoctorVersion,
|
|
16450
|
+
resolveDoctorAntigravityBin: () => resolveDoctorAntigravityBin,
|
|
16214
16451
|
resolveDoctorCodexBin: () => resolveDoctorCodexBin
|
|
16215
16452
|
});
|
|
16216
16453
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -16228,6 +16465,11 @@ function doctorReport(p3) {
|
|
|
16228
16465
|
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
16466
|
fatal: false
|
|
16230
16467
|
},
|
|
16468
|
+
{
|
|
16469
|
+
mark: p3.antigravity ? p3.sandboxRequired ? "!" : "\u2713" : "\xB7",
|
|
16470
|
+
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)",
|
|
16471
|
+
fatal: false
|
|
16472
|
+
},
|
|
16231
16473
|
// SPEC-471 · ADR-0095 · `gh` opsional: tanpa dia tarik issue jatuh ke HTTPS + GITHUB_TOKEN.
|
|
16232
16474
|
{
|
|
16233
16475
|
mark: p3.gh ? "\u2713" : "\xB7",
|
|
@@ -16257,16 +16499,16 @@ function doctorReport(p3) {
|
|
|
16257
16499
|
}
|
|
16258
16500
|
];
|
|
16259
16501
|
for (const m of p3.methods) {
|
|
16260
|
-
const agent = m.agent === "codex" ? "Codex CLI" : "Claude Code";
|
|
16502
|
+
const agent = m.agent === "antigravity" ? "Antigravity CLI" : m.agent === "codex" ? "Codex CLI" : "Claude Code";
|
|
16261
16503
|
rows.push({
|
|
16262
16504
|
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) => `
|
|
16505
|
+
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
16506
|
${c}`).join(""),
|
|
16265
16507
|
fatal: false
|
|
16266
16508
|
});
|
|
16267
16509
|
}
|
|
16268
|
-
if (!p3.claude && !p3.codex) {
|
|
16269
|
-
rows.push({ mark: "\u2717", text: "tak ada CLI agen (claude ATAU
|
|
16510
|
+
if (!p3.claude && !p3.codex && (!p3.antigravity || p3.sandboxRequired)) {
|
|
16511
|
+
rows.push({ mark: "\u2717", text: "tak ada CLI agen (claude, codex ATAU Antigravity host/lab wajib ada)", fatal: true });
|
|
16270
16512
|
}
|
|
16271
16513
|
return { lines: rows.map((r) => ` ${r.mark} ${r.text}`), ok: !rows.some((r) => r.fatal) };
|
|
16272
16514
|
}
|
|
@@ -16285,9 +16527,23 @@ function writable(path) {
|
|
|
16285
16527
|
p3 = up;
|
|
16286
16528
|
}
|
|
16287
16529
|
}
|
|
16288
|
-
function
|
|
16530
|
+
function probeDoctorVersion(bin, args, env, agent = null) {
|
|
16531
|
+
if (agent === "antigravity" && (resolveHardening(env) || (env.HANOMAN_SESSION_SANDBOX ?? "off") !== "off")) return null;
|
|
16289
16532
|
try {
|
|
16290
|
-
|
|
16533
|
+
const output = execFileSync4(bin, args, {
|
|
16534
|
+
encoding: "utf8",
|
|
16535
|
+
env: agentEnvironment(agent, env),
|
|
16536
|
+
timeout: 1e4,
|
|
16537
|
+
...agent === "antigravity" ? { maxBuffer: 16 * 1024, killSignal: "SIGKILL" } : {},
|
|
16538
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
16539
|
+
}).trim();
|
|
16540
|
+
if (agent === "antigravity") {
|
|
16541
|
+
const numeric = "(?:0|[1-9]\\d*)";
|
|
16542
|
+
const identifier = "(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)";
|
|
16543
|
+
const semver = new RegExp(`^${numeric}\\.${numeric}\\.${numeric}(?:-${identifier}(?:\\.${identifier})*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$`);
|
|
16544
|
+
return semver.test(output) ? output : null;
|
|
16545
|
+
}
|
|
16546
|
+
return output.split("\n")[0] || null;
|
|
16291
16547
|
} catch {
|
|
16292
16548
|
return null;
|
|
16293
16549
|
}
|
|
@@ -16300,6 +16556,14 @@ async function resolveDoctorCodexBin(env, dbUrl, read = readRuntimeConfig) {
|
|
|
16300
16556
|
}
|
|
16301
16557
|
return env.HANOMAN_CODEX_BIN?.trim() || "codex";
|
|
16302
16558
|
}
|
|
16559
|
+
async function resolveDoctorAntigravityBin(env, dbUrl, read = readRuntimeConfig) {
|
|
16560
|
+
try {
|
|
16561
|
+
const configured = (await read(dbUrl, "HANOMAN_ANTIGRAVITY_BIN"))?.trim();
|
|
16562
|
+
if (configured) return configured;
|
|
16563
|
+
} catch {
|
|
16564
|
+
}
|
|
16565
|
+
return env.HANOMAN_ANTIGRAVITY_BIN?.trim() || "agy";
|
|
16566
|
+
}
|
|
16303
16567
|
async function doctor(_argv, ctx) {
|
|
16304
16568
|
let layout;
|
|
16305
16569
|
let db;
|
|
@@ -16320,11 +16584,13 @@ async function doctor(_argv, ctx) {
|
|
|
16320
16584
|
{ label: "upload", path: d.uploads, writable: writable(d.uploads), fatal: false },
|
|
16321
16585
|
{ label: "key SSH", path: d.sshKeys, writable: writable(d.sshKeys), fatal: false }
|
|
16322
16586
|
];
|
|
16323
|
-
const
|
|
16587
|
+
const version2 = (bin, args) => probeDoctorVersion(bin, args, ctx.env);
|
|
16588
|
+
const claude = version2(ctx.env.HANOMAN_CLAUDE_BIN ?? "claude", ["--version"]);
|
|
16589
|
+
const antigravity = probeDoctorVersion(await resolveDoctorAntigravityBin(ctx.env, dbUrl), ["--version"], ctx.env, "antigravity");
|
|
16324
16590
|
const codexProbe = codexNativeVersionProbe(ctx.env, await resolveDoctorCodexBin(ctx.env, dbUrl));
|
|
16325
|
-
const codex =
|
|
16591
|
+
const codex = version2(codexProbe.bin, codexProbe.args);
|
|
16326
16592
|
const method = METHODS[DEFAULT_METHOD];
|
|
16327
|
-
const methods = zAgent.options.filter((a) => (
|
|
16593
|
+
const methods = zAgent.options.filter((a) => ({ claude, codex, antigravity })[a] !== null).map((a) => {
|
|
16328
16594
|
const s2 = scanAgentSkills(a, ctx.env);
|
|
16329
16595
|
return methodStatus(method, a, { skills: s2.skills.map((k) => k.id), packages: s2.packages });
|
|
16330
16596
|
});
|
|
@@ -16334,12 +16600,13 @@ async function doctor(_argv, ctx) {
|
|
|
16334
16600
|
const sandboxReady = allReady(prerequisites(ctx.env, podmanFacts));
|
|
16335
16601
|
const r = doctorReport({
|
|
16336
16602
|
node: process.version,
|
|
16337
|
-
git:
|
|
16338
|
-
tmux:
|
|
16603
|
+
git: version2("git", ["--version"]),
|
|
16604
|
+
tmux: version2("tmux", ["-V"]),
|
|
16339
16605
|
claude,
|
|
16340
16606
|
codex,
|
|
16341
|
-
|
|
16342
|
-
|
|
16607
|
+
antigravity,
|
|
16608
|
+
gh: version2(ctx.env.HANOMAN_GH_BIN ?? "gh", ["--version"]),
|
|
16609
|
+
curl: version2("curl", ["--version"]),
|
|
16343
16610
|
dirs,
|
|
16344
16611
|
web: layout.web !== null,
|
|
16345
16612
|
db,
|
|
@@ -17423,10 +17690,10 @@ var init_regexes = __esm({
|
|
|
17423
17690
|
nanoid = /^[a-zA-Z0-9_-]{21}$/;
|
|
17424
17691
|
duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
|
|
17425
17692
|
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 = (
|
|
17427
|
-
if (!
|
|
17693
|
+
uuid = (version2) => {
|
|
17694
|
+
if (!version2)
|
|
17428
17695
|
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}-${
|
|
17696
|
+
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
17697
|
};
|
|
17431
17698
|
email = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;
|
|
17432
17699
|
_emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
|
|
@@ -17894,10 +18161,10 @@ var init_doc = __esm({
|
|
|
17894
18161
|
});
|
|
17895
18162
|
|
|
17896
18163
|
// ../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js
|
|
17897
|
-
var
|
|
18164
|
+
var version;
|
|
17898
18165
|
var init_versions = __esm({
|
|
17899
18166
|
"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js"() {
|
|
17900
|
-
|
|
18167
|
+
version = {
|
|
17901
18168
|
major: 4,
|
|
17902
18169
|
minor: 4,
|
|
17903
18170
|
patch: 3
|
|
@@ -18203,7 +18470,7 @@ var init_schemas = __esm({
|
|
|
18203
18470
|
inst ?? (inst = {});
|
|
18204
18471
|
inst._zod.def = def;
|
|
18205
18472
|
inst._zod.bag = inst._zod.bag || {};
|
|
18206
|
-
inst._zod.version =
|
|
18473
|
+
inst._zod.version = version;
|
|
18207
18474
|
const checks = [...inst._zod.def.checks ?? []];
|
|
18208
18475
|
if (inst._zod.traits.has("$ZodCheck")) {
|
|
18209
18476
|
checks.unshift(inst);
|
|
@@ -23288,14 +23555,14 @@ function missingClientCapabilities(required2, declared) {
|
|
|
23288
23555
|
}
|
|
23289
23556
|
return Object.keys(missing).length > 0 ? missing : void 0;
|
|
23290
23557
|
}
|
|
23291
|
-
function isModernProtocolVersion(
|
|
23292
|
-
return
|
|
23558
|
+
function isModernProtocolVersion(version2) {
|
|
23559
|
+
return version2 >= FIRST_MODERN_PROTOCOL_VERSION;
|
|
23293
23560
|
}
|
|
23294
23561
|
function legacyProtocolVersions(versions) {
|
|
23295
|
-
return versions.filter((
|
|
23562
|
+
return versions.filter((version2) => !isModernProtocolVersion(version2));
|
|
23296
23563
|
}
|
|
23297
23564
|
function modernProtocolVersions(versions) {
|
|
23298
|
-
return versions.filter((
|
|
23565
|
+
return versions.filter((version2) => isModernProtocolVersion(version2));
|
|
23299
23566
|
}
|
|
23300
23567
|
function appendTextFallbackForNonObject(result) {
|
|
23301
23568
|
const sc = result.structuredContent;
|
|
@@ -25409,8 +25676,8 @@ function getWireResultSchemas() {
|
|
|
25409
25676
|
};
|
|
25410
25677
|
return wireResultSchemasMemo;
|
|
25411
25678
|
}
|
|
25412
|
-
function codecForVersion(
|
|
25413
|
-
return
|
|
25679
|
+
function codecForVersion(version2) {
|
|
25680
|
+
return version2 !== void 0 && isModernProtocolVersion(version2) ? rev2026Codec : rev2025Codec;
|
|
25414
25681
|
}
|
|
25415
25682
|
function classifiedWireEra(classification) {
|
|
25416
25683
|
if (classification.revision !== void 0) return codecForVersion(classification.revision).era;
|
|
@@ -25847,8 +26114,8 @@ function withRequestStateValue(ctx, value) {
|
|
|
25847
26114
|
}
|
|
25848
26115
|
};
|
|
25849
26116
|
}
|
|
25850
|
-
function setNegotiatedProtocolVersion(instance,
|
|
25851
|
-
writeNegotiatedProtocolVersion(instance,
|
|
26117
|
+
function setNegotiatedProtocolVersion(instance, version2) {
|
|
26118
|
+
writeNegotiatedProtocolVersion(instance, version2);
|
|
25852
26119
|
}
|
|
25853
26120
|
function isPlainObject$1(value) {
|
|
25854
26121
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -27078,8 +27345,8 @@ var init_src_CX2iR2pK = __esm({
|
|
|
27078
27345
|
*/
|
|
27079
27346
|
_negotiatedProtocolVersion;
|
|
27080
27347
|
static {
|
|
27081
|
-
writeNegotiatedProtocolVersion = (instance,
|
|
27082
|
-
instance._negotiatedProtocolVersion =
|
|
27348
|
+
writeNegotiatedProtocolVersion = (instance, version2) => {
|
|
27349
|
+
instance._negotiatedProtocolVersion = version2;
|
|
27083
27350
|
};
|
|
27084
27351
|
}
|
|
27085
27352
|
_supportedProtocolVersions;
|
|
@@ -35294,7 +35561,7 @@ var init_mcp_DXXb3Vv3 = __esm({
|
|
|
35294
35561
|
if (identity.clientInfo !== void 0) server._clientVersion = identity.clientInfo;
|
|
35295
35562
|
};
|
|
35296
35563
|
installDiscoverHandler = (server, servedModernVersions) => {
|
|
35297
|
-
const missing = servedModernVersions.filter((
|
|
35564
|
+
const missing = servedModernVersions.filter((version2) => !server._supportedProtocolVersions.includes(version2));
|
|
35298
35565
|
if (missing.length > 0) server._supportedProtocolVersions = [...server._supportedProtocolVersions, ...missing];
|
|
35299
35566
|
server.setRequestHandler("server/discover", () => server._ondiscover());
|
|
35300
35567
|
};
|
|
@@ -36852,8 +37119,8 @@ var init_stdio = __esm({
|
|
|
36852
37119
|
if (this._outboundIntercept?.(message) === "handled") return;
|
|
36853
37120
|
return this._wire.send(message, options);
|
|
36854
37121
|
}
|
|
36855
|
-
setProtocolVersion = (
|
|
36856
|
-
this._wire.setProtocolVersion?.(
|
|
37122
|
+
setProtocolVersion = (version2) => {
|
|
37123
|
+
this._wire.setProtocolVersion?.(version2);
|
|
36857
37124
|
};
|
|
36858
37125
|
/** Forwards one inbound message to the connected instance. */
|
|
36859
37126
|
deliver(message, extra) {
|
|
@@ -37642,7 +37909,7 @@ function localScriptPath(cwd = process.cwd()) {
|
|
|
37642
37909
|
}
|
|
37643
37910
|
function runScript(env, ctx) {
|
|
37644
37911
|
return new Promise((resolve6) => {
|
|
37645
|
-
const p3 = spawn2("bash", [localScriptPath(ctx.cwd)], { env: { ...
|
|
37912
|
+
const p3 = spawn2("bash", [localScriptPath(ctx.cwd)], { env: { ...agentEnvironment(null, ctx.env), ...env } });
|
|
37646
37913
|
p3.stdout.on("data", (d) => ctx.stdout(String(d)));
|
|
37647
37914
|
p3.stderr.on("data", (d) => ctx.stderr(String(d)));
|
|
37648
37915
|
p3.on("close", (code) => resolve6(code ?? 1));
|
|
@@ -37677,6 +37944,7 @@ var PROFILES, flag;
|
|
|
37677
37944
|
var init_provision = __esm({
|
|
37678
37945
|
"src/commands/provision.ts"() {
|
|
37679
37946
|
"use strict";
|
|
37947
|
+
init_src2();
|
|
37680
37948
|
PROFILES = ["lab", "production"];
|
|
37681
37949
|
flag = (args, name) => args.find((a) => a.startsWith(`--${name}=`))?.split("=").slice(1).join("=");
|
|
37682
37950
|
}
|
|
@@ -37920,7 +38188,9 @@ var init_migrate_pg = __esm({
|
|
|
37920
38188
|
"QaReport",
|
|
37921
38189
|
"QaCase",
|
|
37922
38190
|
"QaFinding",
|
|
37923
|
-
"QaAttachment"
|
|
38191
|
+
"QaAttachment",
|
|
38192
|
+
// ADR-0222 · CronReport sesudah Project (FK projectId, cascade); tak ada di sumber Postgres lama.
|
|
38193
|
+
"CronReport"
|
|
37924
38194
|
];
|
|
37925
38195
|
CHUNK = 200;
|
|
37926
38196
|
INT8_OID = 20;
|
|
@@ -38164,10 +38434,10 @@ var init_docs_link = __esm({
|
|
|
38164
38434
|
|
|
38165
38435
|
// src/release/pack.ts
|
|
38166
38436
|
import { join as join15 } from "node:path";
|
|
38167
|
-
function packageJsonFor(
|
|
38437
|
+
function packageJsonFor(version2, deps) {
|
|
38168
38438
|
return {
|
|
38169
38439
|
name: PKG_NAME,
|
|
38170
|
-
version:
|
|
38440
|
+
version: version2,
|
|
38171
38441
|
description: "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
|
|
38172
38442
|
type: "module",
|
|
38173
38443
|
repository: { type: "git", url: REPO_URL },
|
|
@@ -38297,8 +38567,8 @@ async function pack(argv, ctx) {
|
|
|
38297
38567
|
}
|
|
38298
38568
|
const outIdx = argv.indexOf("--out");
|
|
38299
38569
|
const out = outIdx === -1 ? join16(repo, "dist-npm") : join16(repo, argv[outIdx + 1] ?? "dist-npm");
|
|
38300
|
-
const
|
|
38301
|
-
if (!
|
|
38570
|
+
const version2 = JSON.parse(readFileSync9(join16(repo, "package.json"), "utf8")).version;
|
|
38571
|
+
if (!version2) {
|
|
38302
38572
|
ctx.stderr("pack: root package.json tanpa field version\n");
|
|
38303
38573
|
return 1;
|
|
38304
38574
|
}
|
|
@@ -38323,14 +38593,14 @@ async function pack(argv, ctx) {
|
|
|
38323
38593
|
cpSync(item.from, dest, item.dir ? { recursive: true } : {});
|
|
38324
38594
|
}
|
|
38325
38595
|
writeFileSync3(join16(out, "bin/hanoman.mjs"), BIN_SHIM);
|
|
38326
|
-
writeFileSync3(join16(out, "package.json"), JSON.stringify(packageJsonFor(
|
|
38596
|
+
writeFileSync3(join16(out, "package.json"), JSON.stringify(packageJsonFor(version2, deps), null, 2) + "\n");
|
|
38327
38597
|
const missing = REQUIRED_ARTIFACTS.filter((a) => !existsSync10(join16(out, a)));
|
|
38328
38598
|
if (missing.length) {
|
|
38329
38599
|
ctx.stderr(`pack: artefak wajib hilang: ${missing.join(", ")}
|
|
38330
38600
|
`);
|
|
38331
38601
|
return 1;
|
|
38332
38602
|
}
|
|
38333
|
-
ctx.stdout(`pack \xB7 ${out} \xB7 hanoman@${
|
|
38603
|
+
ctx.stdout(`pack \xB7 ${out} \xB7 hanoman@${version2} \xB7 ${REQUIRED_ARTIFACTS.length} artefak wajib ada
|
|
38334
38604
|
`);
|
|
38335
38605
|
ctx.stdout("terbitkan MANUAL: cd dist-npm && npm publish --otp <kode>\n");
|
|
38336
38606
|
return 0;
|
|
@@ -38439,10 +38709,10 @@ var init_router = __esm({
|
|
|
38439
38709
|
doctor periksa prasyarat: node, git, tmux, CLI agen, data dir
|
|
38440
38710
|
update [--check] bandingkan versi dengan registry npm; pasang yang terbaru
|
|
38441
38711
|
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.
|
|
38712
|
+
[--profile=lab|production] codex, antigravity (host/lab), gh, \u2026). --probe hanya melaporkan apa yang ada.
|
|
38443
38713
|
[--domain=<d>] [--dry-run] [--yes]
|
|
38444
38714
|
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.
|
|
38715
|
+
[--max-bytes <n>] Codex, Antigravity, Cursor, Copilot). Token dari HANOMAN_AGENT_TOKEN.
|
|
38446
38716
|
[--transfer-dir <d>] direktori tambahan untuk unggah/unduh berkas (ADR-0183)
|
|
38447
38717
|
migrate-from-postgres --from <url> pindahkan data Postgres lama ke SQLite
|
|
38448
38718
|
[--to <file>] [--dry-run] [--force]
|