github-router 0.3.295 → 0.3.302
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/dist/{attribution-settings-pkIop1NU.js → attribution-settings-B1xutIts.js} +153 -16
- package/dist/attribution-settings-B1xutIts.js.map +1 -0
- package/dist/{auth-CluG5e-l.js → auth-CpjOjoUG.js} +4 -3
- package/dist/{auth-CluG5e-l.js.map → auth-CpjOjoUG.js.map} +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/{check-usage-iOzfnKJe.js → check-usage-BsN3S4Fu.js} +4 -4
- package/dist/{check-usage-iOzfnKJe.js.map → check-usage-BsN3S4Fu.js.map} +1 -1
- package/dist/{claude-DNmxk-Rm.js → claude-uRuzEH0W.js} +216 -112
- package/dist/claude-uRuzEH0W.js.map +1 -0
- package/dist/{codex-Dl4gpHn-.js → codex-D5ag-liR.js} +6 -5
- package/dist/{codex-Dl4gpHn-.js.map → codex-D5ag-liR.js.map} +1 -1
- package/dist/{debug-DsEwleGg.js → debug-BXRPyeqO.js} +2 -2
- package/dist/{debug-DsEwleGg.js.map → debug-BXRPyeqO.js.map} +1 -1
- package/dist/engine-2uMJ4Isk.js +2 -0
- package/dist/fast-profile-contract-K3P58nj3.js +57 -0
- package/dist/fast-profile-contract-K3P58nj3.js.map +1 -0
- package/dist/{gate-discovery-WcduofL4.js → gate-discovery-BTRVyKWu.js} +5 -5
- package/dist/{gate-discovery-WcduofL4.js.map → gate-discovery-BTRVyKWu.js.map} +1 -1
- package/dist/{get-copilot-usage-B7Z4XVWj.js → get-copilot-usage-ByjQqhdi.js} +3 -2
- package/dist/{get-copilot-usage-B7Z4XVWj.js.map → get-copilot-usage-ByjQqhdi.js.map} +1 -1
- package/dist/hooks.mjs +351 -21
- package/dist/hooks.sha256 +1 -1
- package/dist/{internal-artifact-open-D6tKMg8v.js → internal-artifact-open-DRSxShAW.js} +2 -2
- package/dist/{internal-artifact-open-D6tKMg8v.js.map → internal-artifact-open-DRSxShAW.js.map} +1 -1
- package/dist/{internal-fast-dispatch-guard-CPlCrTlU.js → internal-fast-dispatch-guard-CYOWbxjX.js} +1 -1
- package/dist/{internal-fast-dispatch-guard-Xyu17k9X.js → internal-fast-dispatch-guard-D2HcfXZv.js} +22 -18
- package/dist/internal-fast-dispatch-guard-D2HcfXZv.js.map +1 -0
- package/dist/{internal-first-mate-guard-C9BV7J4U.js → internal-first-mate-guard-Bcb5JwiO.js} +3 -3
- package/dist/{internal-first-mate-guard-C9BV7J4U.js.map → internal-first-mate-guard-Bcb5JwiO.js.map} +1 -1
- package/dist/{internal-first-mate-guard-WJApyc8j.js → internal-first-mate-guard-Brh_uois.js} +1 -1
- package/dist/internal-max-dispatch-guard-Bcjavapx.js +2 -0
- package/dist/internal-max-dispatch-guard-BjSVXMvC.js +198 -0
- package/dist/internal-max-dispatch-guard-BjSVXMvC.js.map +1 -0
- package/dist/{internal-plan-review-t3PuNfuL.js → internal-plan-review-DVY-iV2x.js} +3 -3
- package/dist/{internal-plan-review-t3PuNfuL.js.map → internal-plan-review-DVY-iV2x.js.map} +1 -1
- package/dist/{internal-prompt-submit-C3KovHQG.js → internal-prompt-submit-BTqRn4FW.js} +4 -4
- package/dist/{internal-prompt-submit-C3KovHQG.js.map → internal-prompt-submit-BTqRn4FW.js.map} +1 -1
- package/dist/{internal-session-bind-d2uoja8I.js → internal-session-bind-YfH656lt.js} +2 -2
- package/dist/{internal-session-bind-d2uoja8I.js.map → internal-session-bind-YfH656lt.js.map} +1 -1
- package/dist/{internal-stop-hook-DJFtGCsE.js → internal-stop-hook-BZg__ab6.js} +5 -5
- package/dist/{internal-stop-hook-DJFtGCsE.js.map → internal-stop-hook-BZg__ab6.js.map} +1 -1
- package/dist/{internal-stop-review-YtDUGXpX.js → internal-stop-review-B8MmEyQ1.js} +2 -2
- package/dist/{internal-stop-review-YtDUGXpX.js.map → internal-stop-review-B8MmEyQ1.js.map} +1 -1
- package/dist/{internal-worker-guard-CdkeS9PN.js → internal-worker-guard-Dr6W83TC.js} +2 -2
- package/dist/{internal-worker-guard-CdkeS9PN.js.map → internal-worker-guard-Dr6W83TC.js.map} +1 -1
- package/dist/{internal-workspace-header-tuBXJV22.js → internal-workspace-header-Cep0WSIb.js} +2 -2
- package/dist/{internal-workspace-header-tuBXJV22.js.map → internal-workspace-header-Cep0WSIb.js.map} +1 -1
- package/dist/lifecycle-4TZrJuAa.js +2 -0
- package/dist/{lifecycle-CM9eTzvk.js → lifecycle-CmPJ6e_6.js} +2 -2
- package/dist/{lifecycle-CM9eTzvk.js.map → lifecycle-CmPJ6e_6.js.map} +1 -1
- package/dist/{lifecycle-Bg6doY3-.js → lifecycle-DgsJ_8Am.js} +2 -2
- package/dist/{lifecycle-Bg6doY3-.js.map → lifecycle-DgsJ_8Am.js.map} +1 -1
- package/dist/lifecycle-O91Vzzb-.js +2 -0
- package/dist/main.js +19 -18
- package/dist/main.js.map +1 -1
- package/dist/max-profile-contract-BTXowh6k.js +264 -0
- package/dist/max-profile-contract-BTXowh6k.js.map +1 -0
- package/dist/{mcp-workspace-header-dERl2YTT.js → mcp-workspace-header-NzFD0Wgd.js} +2 -2
- package/dist/{mcp-workspace-header-dERl2YTT.js.map → mcp-workspace-header-NzFD0Wgd.js.map} +1 -1
- package/dist/{models-DZ4hYsR7.js → models-1KwEUgzd.js} +3 -3
- package/dist/{models-DZ4hYsR7.js.map → models-1KwEUgzd.js.map} +1 -1
- package/dist/{orchestration-BiGCEwbH.js → orchestration-CYyp9w-t.js} +2 -2
- package/dist/{orchestration-BiGCEwbH.js.map → orchestration-CYyp9w-t.js.map} +1 -1
- package/dist/paths-DDAiPVto.js +2 -0
- package/dist/{paths-Ci485qSJ.js → paths-IcZW8gZx.js} +4 -4
- package/dist/{paths-Ci485qSJ.js.map → paths-IcZW8gZx.js.map} +1 -1
- package/dist/{peer-mcp-personas-BwNtC8jt.js → peer-mcp-personas-DwEiYeJS.js} +498 -260
- package/dist/peer-mcp-personas-DwEiYeJS.js.map +1 -0
- package/dist/{plan-review-hook-DuW0pSoM.js → plan-review-hook-szSNt6uU.js} +3 -3
- package/dist/{plan-review-hook-DuW0pSoM.js.map → plan-review-hook-szSNt6uU.js.map} +1 -1
- package/dist/{prompt-submit-hook-IMl7ssfr.js → prompt-submit-hook-ZUxo_jEl.js} +3 -3
- package/dist/{prompt-submit-hook-IMl7ssfr.js.map → prompt-submit-hook-ZUxo_jEl.js.map} +1 -1
- package/dist/{provision-DeNqzvSM.js → provision-BLT1pCFy.js} +4 -4
- package/dist/{provision-DeNqzvSM.js.map → provision-BLT1pCFy.js.map} +1 -1
- package/dist/{self-invocation-DAB_od0C.js → self-invocation-BJWbA8ka.js} +2 -2
- package/dist/{self-invocation-DAB_od0C.js.map → self-invocation-BJWbA8ka.js.map} +1 -1
- package/dist/{serve-BS5EmCpM.js → serve-wEZoOijw.js} +13 -12
- package/dist/{serve-BS5EmCpM.js.map → serve-wEZoOijw.js.map} +1 -1
- package/dist/{server-setup-DsGJnJ_O.js → server-setup-Zn5wkosb.js} +268 -41
- package/dist/server-setup-Zn5wkosb.js.map +1 -0
- package/dist/{start-vJdt2MiM.js → start-DSqU8d8h.js} +3 -3
- package/dist/{start-vJdt2MiM.js.map → start-DSqU8d8h.js.map} +1 -1
- package/dist/state-B8adscCv.js +51 -0
- package/dist/state-B8adscCv.js.map +1 -0
- package/dist/{stop-gate-hook-DQnh_KfI.js → stop-gate-hook-CJOk28zd.js} +3 -3
- package/dist/{stop-gate-hook-DQnh_KfI.js.map → stop-gate-hook-CJOk28zd.js.map} +1 -1
- package/dist/{stop-gate-policy-DMr3KVmw.js → stop-gate-policy-zhzRIj6G.js} +2 -2
- package/dist/{stop-gate-policy-DMr3KVmw.js.map → stop-gate-policy-zhzRIj6G.js.map} +1 -1
- package/dist/{token-BtJhjXXu.js → token-CbuFyx-B.js} +4 -50
- package/dist/token-CbuFyx-B.js.map +1 -0
- package/dist/{worker-dispatch-BEHkTbnH.js → worker-dispatch-DgP5yT26.js} +2 -2
- package/dist/{worker-dispatch-BEHkTbnH.js.map → worker-dispatch-DgP5yT26.js.map} +1 -1
- package/package.json +1 -1
- package/dist/attribution-settings-pkIop1NU.js.map +0 -1
- package/dist/claude-DNmxk-Rm.js.map +0 -1
- package/dist/engine-XnluJUs6.js +0 -2
- package/dist/internal-fast-dispatch-guard-Xyu17k9X.js.map +0 -1
- package/dist/lifecycle-CGLt1cJQ.js +0 -2
- package/dist/lifecycle-DoUwpVDB.js +0 -2
- package/dist/paths-GD7bgGGy.js +0 -2
- package/dist/peer-mcp-personas-BwNtC8jt.js.map +0 -1
- package/dist/server-setup-DsGJnJ_O.js.map +0 -1
- package/dist/token-BtJhjXXu.js.map +0 -1
package/dist/hooks.mjs
CHANGED
|
@@ -10921,6 +10921,145 @@ var init_harness_parse = __esmMin((() => {
|
|
|
10921
10921
|
STATIC_IDS = /* @__PURE__ */ new Set(["typecheck", "lint"]);
|
|
10922
10922
|
}));
|
|
10923
10923
|
//#endregion
|
|
10924
|
+
//#region src/lib/state.ts
|
|
10925
|
+
var DEFAULT_LAUNCH_ID, state;
|
|
10926
|
+
var init_state = __esmMin((() => {
|
|
10927
|
+
DEFAULT_LAUNCH_ID = "__default__";
|
|
10928
|
+
state = {
|
|
10929
|
+
accountType: "enterprise",
|
|
10930
|
+
copilotTokenGeneration: 0,
|
|
10931
|
+
manualApprove: false,
|
|
10932
|
+
rateLimitWait: false,
|
|
10933
|
+
showToken: false,
|
|
10934
|
+
extendedBetas: false,
|
|
10935
|
+
browseEnabled: false,
|
|
10936
|
+
fleetEnabled: false,
|
|
10937
|
+
agentsEnabled: false,
|
|
10938
|
+
powerBrowseEnabled: false,
|
|
10939
|
+
humanlikeForce: "auto",
|
|
10940
|
+
sessionId: randomUUID(),
|
|
10941
|
+
machineId: randomBytes(32).toString("hex"),
|
|
10942
|
+
launchRegistry: /* @__PURE__ */ new Map()
|
|
10943
|
+
};
|
|
10944
|
+
Object.defineProperty(state, "peerMcpNonce", {
|
|
10945
|
+
enumerable: true,
|
|
10946
|
+
configurable: true,
|
|
10947
|
+
get() {
|
|
10948
|
+
return state.launchRegistry.get(DEFAULT_LAUNCH_ID)?.nonce;
|
|
10949
|
+
},
|
|
10950
|
+
set(value) {
|
|
10951
|
+
if (value === void 0) {
|
|
10952
|
+
state.launchRegistry.delete(DEFAULT_LAUNCH_ID);
|
|
10953
|
+
return;
|
|
10954
|
+
}
|
|
10955
|
+
const existing = state.launchRegistry.get(DEFAULT_LAUNCH_ID);
|
|
10956
|
+
state.launchRegistry.set(DEFAULT_LAUNCH_ID, {
|
|
10957
|
+
launchId: DEFAULT_LAUNCH_ID,
|
|
10958
|
+
nonce: value,
|
|
10959
|
+
secret: existing?.secret ?? "",
|
|
10960
|
+
profileId: existing?.profileId ?? "standard",
|
|
10961
|
+
allowedGroups: existing?.allowedGroups,
|
|
10962
|
+
allowedPersonas: existing?.allowedPersonas,
|
|
10963
|
+
createdAt: existing?.createdAt ?? Date.now()
|
|
10964
|
+
});
|
|
10965
|
+
}
|
|
10966
|
+
});
|
|
10967
|
+
})), FAST_PROFILE_MODELS, FAST_PROFILE_NATIVE_AGENT_NAMES, FAST_PROFILE_ADVISOR_MODEL, FAST_PROFILE_DELEGATION_GRAPH;
|
|
10968
|
+
var init_fast_profile_contract = __esmMin((() => {
|
|
10969
|
+
FAST_PROFILE_MODELS = Object.freeze({
|
|
10970
|
+
luna: "gpt-5.6-luna",
|
|
10971
|
+
reviewer: "grok-4.6",
|
|
10972
|
+
planner: "gpt-5.6-sol",
|
|
10973
|
+
critic: "gemini-3.7-flash",
|
|
10974
|
+
oracle: "claude-opus-5"
|
|
10975
|
+
});
|
|
10976
|
+
FAST_PROFILE_NATIVE_AGENT_NAMES = [
|
|
10977
|
+
"Explore",
|
|
10978
|
+
"implementer",
|
|
10979
|
+
"reviewer",
|
|
10980
|
+
"planner",
|
|
10981
|
+
"critic"
|
|
10982
|
+
];
|
|
10983
|
+
Object.freeze({
|
|
10984
|
+
Explore: FAST_PROFILE_MODELS.luna,
|
|
10985
|
+
implementer: FAST_PROFILE_MODELS.luna,
|
|
10986
|
+
reviewer: FAST_PROFILE_MODELS.reviewer,
|
|
10987
|
+
planner: FAST_PROFILE_MODELS.planner,
|
|
10988
|
+
critic: FAST_PROFILE_MODELS.critic
|
|
10989
|
+
});
|
|
10990
|
+
Object.freeze({
|
|
10991
|
+
Explore: "high",
|
|
10992
|
+
implementer: "max",
|
|
10993
|
+
reviewer: "medium",
|
|
10994
|
+
planner: "high",
|
|
10995
|
+
critic: "medium"
|
|
10996
|
+
});
|
|
10997
|
+
FAST_PROFILE_ADVISOR_MODEL = FAST_PROFILE_MODELS.critic;
|
|
10998
|
+
`${FAST_PROFILE_ADVISOR_MODEL}`;
|
|
10999
|
+
FAST_PROFILE_MODELS.oracle;
|
|
11000
|
+
FAST_PROFILE_DELEGATION_GRAPH = Object.freeze({
|
|
11001
|
+
Explore: Object.freeze([]),
|
|
11002
|
+
implementer: Object.freeze(["reviewer", "critic"]),
|
|
11003
|
+
reviewer: Object.freeze([]),
|
|
11004
|
+
planner: Object.freeze([
|
|
11005
|
+
"reviewer",
|
|
11006
|
+
"Explore",
|
|
11007
|
+
"critic"
|
|
11008
|
+
]),
|
|
11009
|
+
critic: Object.freeze([])
|
|
11010
|
+
});
|
|
11011
|
+
})), MAX_PROFILE_MODELS, MAX_PROFILE_NATIVE_AGENT_NAMES, MAX_PROFILE_NATIVE_MODELS;
|
|
11012
|
+
var init_max_profile_contract = __esmMin((() => {
|
|
11013
|
+
init_state();
|
|
11014
|
+
MAX_PROFILE_MODELS = Object.freeze({
|
|
11015
|
+
sol: "gpt-5.6-sol",
|
|
11016
|
+
luna: "gpt-5.6-luna",
|
|
11017
|
+
gemini: "gemini-3.7-flash",
|
|
11018
|
+
grok: "grok-4.6",
|
|
11019
|
+
opus: "claude-opus-5"
|
|
11020
|
+
});
|
|
11021
|
+
MAX_PROFILE_NATIVE_AGENT_NAMES = [
|
|
11022
|
+
"Explore",
|
|
11023
|
+
"Plan",
|
|
11024
|
+
"general-purpose",
|
|
11025
|
+
"implementer",
|
|
11026
|
+
"reviewer",
|
|
11027
|
+
"brainstorm",
|
|
11028
|
+
"peer-review-coordinator"
|
|
11029
|
+
];
|
|
11030
|
+
Object.freeze({
|
|
11031
|
+
Explore: "high",
|
|
11032
|
+
Plan: "high",
|
|
11033
|
+
"general-purpose": "max",
|
|
11034
|
+
implementer: "high",
|
|
11035
|
+
reviewer: "high",
|
|
11036
|
+
brainstorm: "medium",
|
|
11037
|
+
"peer-review-coordinator": "max"
|
|
11038
|
+
});
|
|
11039
|
+
MAX_PROFILE_NATIVE_MODELS = Object.freeze({
|
|
11040
|
+
Explore: MAX_PROFILE_MODELS.luna,
|
|
11041
|
+
Plan: MAX_PROFILE_MODELS.sol,
|
|
11042
|
+
"general-purpose": MAX_PROFILE_MODELS.luna,
|
|
11043
|
+
implementer: MAX_PROFILE_MODELS.gemini,
|
|
11044
|
+
reviewer: MAX_PROFILE_MODELS.gemini,
|
|
11045
|
+
brainstorm: MAX_PROFILE_MODELS.grok,
|
|
11046
|
+
"peer-review-coordinator": MAX_PROFILE_MODELS.luna
|
|
11047
|
+
});
|
|
11048
|
+
MAX_PROFILE_MODELS.sol;
|
|
11049
|
+
MAX_PROFILE_MODELS.opus;
|
|
11050
|
+
Object.freeze([
|
|
11051
|
+
MAX_PROFILE_MODELS.luna,
|
|
11052
|
+
MAX_PROFILE_MODELS.gemini,
|
|
11053
|
+
MAX_PROFILE_MODELS.grok
|
|
11054
|
+
]);
|
|
11055
|
+
Object.freeze([
|
|
11056
|
+
MAX_PROFILE_MODELS.sol,
|
|
11057
|
+
MAX_PROFILE_MODELS.luna,
|
|
11058
|
+
MAX_PROFILE_MODELS.gemini,
|
|
11059
|
+
MAX_PROFILE_MODELS.opus
|
|
11060
|
+
]);
|
|
11061
|
+
}));
|
|
11062
|
+
//#endregion
|
|
10924
11063
|
//#region node_modules/undici/lib/core/symbols.js
|
|
10925
11064
|
var require_symbols = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
10926
11065
|
module.exports = {
|
|
@@ -37729,7 +37868,7 @@ var internal_first_mate_guard_exports = /* @__PURE__ */ __exportAll({
|
|
|
37729
37868
|
buildFirstMateGuardHookCommand: () => buildFirstMateGuardHookCommand,
|
|
37730
37869
|
internalFirstMateGuard: () => internalFirstMateGuard
|
|
37731
37870
|
});
|
|
37732
|
-
function readStdinSync$
|
|
37871
|
+
function readStdinSync$2() {
|
|
37733
37872
|
try {
|
|
37734
37873
|
return readFileSync(0, "utf8");
|
|
37735
37874
|
} catch {
|
|
@@ -37755,7 +37894,7 @@ var init_internal_first_mate_guard = __esmMin((() => {
|
|
|
37755
37894
|
let hookInput;
|
|
37756
37895
|
let parsed;
|
|
37757
37896
|
try {
|
|
37758
|
-
const payload = JSON.parse(readStdinSync$
|
|
37897
|
+
const payload = JSON.parse(readStdinSync$2());
|
|
37759
37898
|
if (typeof payload.tool_name === "string") toolName = payload.tool_name;
|
|
37760
37899
|
if (typeof payload.agent_type === "string") hookInput = { agent_type: payload.agent_type };
|
|
37761
37900
|
parsed = true;
|
|
@@ -37910,6 +38049,8 @@ function decideFastDispatchGuard(stdin) {
|
|
|
37910
38049
|
const targetValue = targetResult.value;
|
|
37911
38050
|
if (!targetValue || !FAST_NATIVE_AGENT_SET.has(targetValue)) return deny(`fast dispatch denied: ${toolName} target must be one of ${FAST_NATIVE_AGENT_NAMES.join(", ")}`);
|
|
37912
38051
|
const target = targetValue;
|
|
38052
|
+
const updatedInput = { ...payload.tool_input };
|
|
38053
|
+
delete updatedInput.model;
|
|
37913
38054
|
const callerType = resolveAliasedString(payload, ["agent_type", "agentType"]);
|
|
37914
38055
|
const callerId = resolveAliasedString(payload, ["agent_id", "agentId"]);
|
|
37915
38056
|
const parentMarker = resolveAliasedString(payload, ["parent_tool_use_id", "parentToolUseId"]);
|
|
@@ -37932,6 +38073,7 @@ function decideFastDispatchGuard(stdin) {
|
|
|
37932
38073
|
allowed: true,
|
|
37933
38074
|
caller: "lead",
|
|
37934
38075
|
target,
|
|
38076
|
+
updatedInput,
|
|
37935
38077
|
verdict: "allow"
|
|
37936
38078
|
};
|
|
37937
38079
|
}
|
|
@@ -37942,9 +38084,18 @@ function decideFastDispatchGuard(stdin) {
|
|
|
37942
38084
|
allowed: true,
|
|
37943
38085
|
caller,
|
|
37944
38086
|
target,
|
|
38087
|
+
updatedInput,
|
|
37945
38088
|
verdict: "allow"
|
|
37946
38089
|
};
|
|
37947
38090
|
}
|
|
38091
|
+
/** JSON response consumed by Claude Code for an allowed, model-pinned dispatch. */
|
|
38092
|
+
function fastDispatchAllowOutput(updatedInput) {
|
|
38093
|
+
return JSON.stringify({ hookSpecificOutput: {
|
|
38094
|
+
hookEventName: "PreToolUse",
|
|
38095
|
+
permissionDecision: "allow",
|
|
38096
|
+
updatedInput
|
|
38097
|
+
} });
|
|
38098
|
+
}
|
|
37948
38099
|
/** JSON response consumed by Claude Code's PreToolUse hook protocol. */
|
|
37949
38100
|
function fastDispatchDenyOutput(reason) {
|
|
37950
38101
|
return JSON.stringify({ hookSpecificOutput: {
|
|
@@ -37955,24 +38106,15 @@ function fastDispatchDenyOutput(reason) {
|
|
|
37955
38106
|
}
|
|
37956
38107
|
var FAST_NATIVE_AGENT_NAMES, FAST_NATIVE_AGENT_SET, FAST_DISPATCH_GRAPH;
|
|
37957
38108
|
var init_fast_dispatch_acl = __esmMin((() => {
|
|
37958
|
-
|
|
37959
|
-
|
|
37960
|
-
"implementer",
|
|
37961
|
-
"reviewer",
|
|
37962
|
-
"planner",
|
|
37963
|
-
"critic"
|
|
37964
|
-
];
|
|
38109
|
+
init_fast_profile_contract();
|
|
38110
|
+
FAST_NATIVE_AGENT_NAMES = FAST_PROFILE_NATIVE_AGENT_NAMES;
|
|
37965
38111
|
FAST_NATIVE_AGENT_SET = new Set(FAST_NATIVE_AGENT_NAMES);
|
|
37966
38112
|
FAST_DISPATCH_GRAPH = Object.freeze({
|
|
37967
|
-
|
|
37968
|
-
implementer:
|
|
37969
|
-
reviewer:
|
|
37970
|
-
planner:
|
|
37971
|
-
|
|
37972
|
-
"scout",
|
|
37973
|
-
"critic"
|
|
37974
|
-
]),
|
|
37975
|
-
critic: /* @__PURE__ */ new Set()
|
|
38113
|
+
Explore: new Set(FAST_PROFILE_DELEGATION_GRAPH.Explore),
|
|
38114
|
+
implementer: new Set(FAST_PROFILE_DELEGATION_GRAPH.implementer),
|
|
38115
|
+
reviewer: new Set(FAST_PROFILE_DELEGATION_GRAPH.reviewer),
|
|
38116
|
+
planner: new Set(FAST_PROFILE_DELEGATION_GRAPH.planner),
|
|
38117
|
+
critic: new Set(FAST_PROFILE_DELEGATION_GRAPH.critic)
|
|
37976
38118
|
});
|
|
37977
38119
|
}));
|
|
37978
38120
|
//#endregion
|
|
@@ -37981,7 +38123,7 @@ var internal_fast_dispatch_guard_exports = /* @__PURE__ */ __exportAll({
|
|
|
37981
38123
|
buildFastDispatchGuardHookCommand: () => buildFastDispatchGuardHookCommand,
|
|
37982
38124
|
internalFastDispatchGuard: () => internalFastDispatchGuard
|
|
37983
38125
|
});
|
|
37984
|
-
function readStdinSync() {
|
|
38126
|
+
function readStdinSync$1() {
|
|
37985
38127
|
try {
|
|
37986
38128
|
if (process.stdin.isTTY) return "";
|
|
37987
38129
|
return readFileSync(0, "utf8");
|
|
@@ -38004,8 +38146,195 @@ var init_internal_fast_dispatch_guard = __esmMin((() => {
|
|
|
38004
38146
|
description: "Internal: PreToolUse guard enforcing the fast-profile native Task/Agent ACL."
|
|
38005
38147
|
},
|
|
38006
38148
|
run() {
|
|
38007
|
-
const decision = decideFastDispatchGuard(readStdinSync());
|
|
38149
|
+
const decision = decideFastDispatchGuard(readStdinSync$1());
|
|
38008
38150
|
if (!decision.allowed && decision.reason) process.stdout.write(fastDispatchDenyOutput(decision.reason));
|
|
38151
|
+
else if (decision.verdict === "allow" && decision.updatedInput) process.stdout.write(fastDispatchAllowOutput(decision.updatedInput));
|
|
38152
|
+
process.exitCode = 0;
|
|
38153
|
+
}
|
|
38154
|
+
});
|
|
38155
|
+
}));
|
|
38156
|
+
//#endregion
|
|
38157
|
+
//#region src/lib/max-dispatch-acl.ts
|
|
38158
|
+
function isMaxAgentSchemaModelAlias(model) {
|
|
38159
|
+
if (typeof model !== "string") return false;
|
|
38160
|
+
return MAX_AGENT_SCHEMA_MODEL_ALIAS_SET.has(baseModel(model.trim()).toLowerCase());
|
|
38161
|
+
}
|
|
38162
|
+
function stringField(input, ...keys) {
|
|
38163
|
+
const values = keys.filter((key) => Object.prototype.hasOwnProperty.call(input, key)).map((key) => input[key]).filter((value) => value !== void 0 && value !== null);
|
|
38164
|
+
if (values.length === 0) return void 0;
|
|
38165
|
+
if (values.some((value) => typeof value !== "string" || value.trim().length === 0)) return void 0;
|
|
38166
|
+
const distinct = [...new Set(values.map((value) => value.trim()))];
|
|
38167
|
+
return distinct.length === 1 ? distinct[0] : void 0;
|
|
38168
|
+
}
|
|
38169
|
+
function baseModel(model) {
|
|
38170
|
+
return model.replace(/(?:\[1m\])+$/i, "");
|
|
38171
|
+
}
|
|
38172
|
+
function normalizeMaxDispatchModel(model) {
|
|
38173
|
+
if (typeof model !== "string" || model.trim().length === 0) return void 0;
|
|
38174
|
+
const base = baseModel(model.trim());
|
|
38175
|
+
return MAX_ALLOWED_MODEL_BASES.has(base) ? base === "grok-4.6" ? base : `${base}[1m]` : void 0;
|
|
38176
|
+
}
|
|
38177
|
+
function normalizeMaxDispatchEffort(model, effort) {
|
|
38178
|
+
if (effort === void 0 || effort === null) return void 0;
|
|
38179
|
+
if (typeof effort !== "string") return void 0;
|
|
38180
|
+
if ((model === "gpt-5.6-sol" ? [
|
|
38181
|
+
"high",
|
|
38182
|
+
"xhigh",
|
|
38183
|
+
"max"
|
|
38184
|
+
] : model === "gpt-5.6-luna" ? [
|
|
38185
|
+
"none",
|
|
38186
|
+
"low",
|
|
38187
|
+
"medium",
|
|
38188
|
+
"high",
|
|
38189
|
+
"xhigh",
|
|
38190
|
+
"max"
|
|
38191
|
+
] : model === "grok-4.6" || model === "gemini-3.7-flash" ? [
|
|
38192
|
+
"low",
|
|
38193
|
+
"medium",
|
|
38194
|
+
"high"
|
|
38195
|
+
] : []).includes(effort)) return effort;
|
|
38196
|
+
}
|
|
38197
|
+
/**
|
|
38198
|
+
* Native max Task/Agent ACL. Role frontmatter owns the fixed model. Required
|
|
38199
|
+
* public-schema aliases are stripped as transport placeholders; a client that
|
|
38200
|
+
* can express custom ids may override only to Luna, Gemini, or Grok with a
|
|
38201
|
+
* live-ladder effort. Sol/Codex/unknown/private ids are rejected. The lead may
|
|
38202
|
+
* target any emitted max role; role-to-role edges are unrestricted here.
|
|
38203
|
+
*/
|
|
38204
|
+
function decideMaxDispatchGuard(stdin) {
|
|
38205
|
+
let parsed;
|
|
38206
|
+
try {
|
|
38207
|
+
parsed = typeof stdin === "string" ? JSON.parse(stdin) : stdin;
|
|
38208
|
+
} catch {
|
|
38209
|
+
return {
|
|
38210
|
+
allowed: false,
|
|
38211
|
+
reason: "max dispatch denied: malformed hook payload",
|
|
38212
|
+
verdict: "deny"
|
|
38213
|
+
};
|
|
38214
|
+
}
|
|
38215
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {
|
|
38216
|
+
allowed: false,
|
|
38217
|
+
reason: "max dispatch denied: hook payload must be an object",
|
|
38218
|
+
verdict: "deny"
|
|
38219
|
+
};
|
|
38220
|
+
const payload = parsed;
|
|
38221
|
+
if (typeof payload.tool_name !== "string") return {
|
|
38222
|
+
allowed: false,
|
|
38223
|
+
reason: "max dispatch denied: hook payload has no tool_name",
|
|
38224
|
+
verdict: "deny"
|
|
38225
|
+
};
|
|
38226
|
+
if (!/^(Task|Agent)$/.test(payload.tool_name)) return {
|
|
38227
|
+
allowed: true,
|
|
38228
|
+
verdict: "allow-non-dispatch"
|
|
38229
|
+
};
|
|
38230
|
+
if (!payload.tool_input || typeof payload.tool_input !== "object" || Array.isArray(payload.tool_input)) return {
|
|
38231
|
+
allowed: false,
|
|
38232
|
+
reason: `max dispatch denied: ${payload.tool_name} payload has malformed tool_input`,
|
|
38233
|
+
verdict: "deny"
|
|
38234
|
+
};
|
|
38235
|
+
const toolInput = payload.tool_input;
|
|
38236
|
+
const target = stringField(toolInput, "subagent_type", "subagentType");
|
|
38237
|
+
if (!target || !MAX_NATIVE_AGENT_SET.has(target)) return {
|
|
38238
|
+
allowed: false,
|
|
38239
|
+
reason: `max dispatch denied: target must be one of ${[...MAX_PROFILE_NATIVE_AGENT_NAMES, MAX_BROWSE_DISPATCH_AGENT].join(", ")}`,
|
|
38240
|
+
verdict: "deny"
|
|
38241
|
+
};
|
|
38242
|
+
const nativeTarget = target;
|
|
38243
|
+
const modelValue = toolInput.model;
|
|
38244
|
+
const schemaAlias = isMaxAgentSchemaModelAlias(modelValue);
|
|
38245
|
+
const normalizedModel = modelValue === void 0 || schemaAlias ? void 0 : normalizeMaxDispatchModel(modelValue);
|
|
38246
|
+
if (modelValue !== void 0 && !schemaAlias && !normalizedModel) return {
|
|
38247
|
+
allowed: false,
|
|
38248
|
+
reason: "max dispatch denied: model must be a Claude Code Agent schema alias, Luna[1m], Gemini 3.7 Flash[1m], or bare Grok 4.6",
|
|
38249
|
+
target,
|
|
38250
|
+
verdict: "deny"
|
|
38251
|
+
};
|
|
38252
|
+
const requestedEffort = toolInput.thinking ?? toolInput.effort;
|
|
38253
|
+
const effort = normalizeMaxDispatchEffort(normalizedModel ? baseModel(normalizedModel) : nativeTarget === "worker-browse" ? "gpt-5.6-luna" : MAX_PROFILE_NATIVE_MODELS[nativeTarget], requestedEffort);
|
|
38254
|
+
if ((toolInput.thinking !== void 0 || toolInput.effort !== void 0) && !effort) return {
|
|
38255
|
+
allowed: false,
|
|
38256
|
+
reason: "max dispatch denied: reasoning override is not supported by the selected model",
|
|
38257
|
+
target,
|
|
38258
|
+
verdict: "deny"
|
|
38259
|
+
};
|
|
38260
|
+
const updatedInput = { ...toolInput };
|
|
38261
|
+
if (normalizedModel) updatedInput.model = normalizedModel;
|
|
38262
|
+
else delete updatedInput.model;
|
|
38263
|
+
if (effort) if (toolInput.thinking !== void 0) updatedInput.thinking = effort;
|
|
38264
|
+
else updatedInput.effort = effort;
|
|
38265
|
+
if (toolInput.thinking !== void 0 && toolInput.effort !== void 0) delete updatedInput.effort;
|
|
38266
|
+
if (toolInput.model === void 0 && normalizedModel === void 0) delete updatedInput.model;
|
|
38267
|
+
return {
|
|
38268
|
+
allowed: true,
|
|
38269
|
+
target,
|
|
38270
|
+
effort,
|
|
38271
|
+
updatedInput,
|
|
38272
|
+
verdict: "allow"
|
|
38273
|
+
};
|
|
38274
|
+
}
|
|
38275
|
+
function maxDispatchAllowOutput(updatedInput) {
|
|
38276
|
+
return JSON.stringify({ hookSpecificOutput: {
|
|
38277
|
+
hookEventName: "PreToolUse",
|
|
38278
|
+
permissionDecision: "allow",
|
|
38279
|
+
updatedInput
|
|
38280
|
+
} });
|
|
38281
|
+
}
|
|
38282
|
+
function maxDispatchDenyOutput(reason) {
|
|
38283
|
+
return JSON.stringify({ hookSpecificOutput: {
|
|
38284
|
+
hookEventName: "PreToolUse",
|
|
38285
|
+
permissionDecision: "deny",
|
|
38286
|
+
permissionDecisionReason: reason
|
|
38287
|
+
} });
|
|
38288
|
+
}
|
|
38289
|
+
var MAX_BROWSE_DISPATCH_AGENT, MAX_NATIVE_AGENT_SET, MAX_ALLOWED_MODEL_BASES, MAX_AGENT_SCHEMA_MODEL_ALIASES, MAX_AGENT_SCHEMA_MODEL_ALIAS_SET;
|
|
38290
|
+
var init_max_dispatch_acl = __esmMin((() => {
|
|
38291
|
+
init_max_profile_contract();
|
|
38292
|
+
MAX_BROWSE_DISPATCH_AGENT = "worker-browse";
|
|
38293
|
+
MAX_NATIVE_AGENT_SET = /* @__PURE__ */ new Set([...MAX_PROFILE_NATIVE_AGENT_NAMES, MAX_BROWSE_DISPATCH_AGENT]);
|
|
38294
|
+
MAX_ALLOWED_MODEL_BASES = /* @__PURE__ */ new Set([
|
|
38295
|
+
"gpt-5.6-luna",
|
|
38296
|
+
"gemini-3.7-flash",
|
|
38297
|
+
"grok-4.6"
|
|
38298
|
+
]);
|
|
38299
|
+
MAX_AGENT_SCHEMA_MODEL_ALIASES = Object.freeze([
|
|
38300
|
+
"sonnet",
|
|
38301
|
+
"opus",
|
|
38302
|
+
"haiku",
|
|
38303
|
+
"fable"
|
|
38304
|
+
]);
|
|
38305
|
+
MAX_AGENT_SCHEMA_MODEL_ALIAS_SET = new Set(MAX_AGENT_SCHEMA_MODEL_ALIASES);
|
|
38306
|
+
}));
|
|
38307
|
+
//#endregion
|
|
38308
|
+
//#region src/internal-max-dispatch-guard.ts
|
|
38309
|
+
var internal_max_dispatch_guard_exports = /* @__PURE__ */ __exportAll({
|
|
38310
|
+
buildMaxDispatchGuardHookCommand: () => buildMaxDispatchGuardHookCommand,
|
|
38311
|
+
internalMaxDispatchGuard: () => internalMaxDispatchGuard
|
|
38312
|
+
});
|
|
38313
|
+
function readStdinSync() {
|
|
38314
|
+
try {
|
|
38315
|
+
if (process.stdin.isTTY) return "";
|
|
38316
|
+
return readFileSync(0, "utf8");
|
|
38317
|
+
} catch {
|
|
38318
|
+
return "";
|
|
38319
|
+
}
|
|
38320
|
+
}
|
|
38321
|
+
function buildMaxDispatchGuardHookCommand(invocation) {
|
|
38322
|
+
return buildSelfCommand(invocation, "internal-max-dispatch-guard");
|
|
38323
|
+
}
|
|
38324
|
+
var internalMaxDispatchGuard;
|
|
38325
|
+
var init_internal_max_dispatch_guard = __esmMin((() => {
|
|
38326
|
+
init_dist$1();
|
|
38327
|
+
init_max_dispatch_acl();
|
|
38328
|
+
init_self_invocation();
|
|
38329
|
+
internalMaxDispatchGuard = defineCommand({
|
|
38330
|
+
meta: {
|
|
38331
|
+
name: "internal-max-dispatch-guard",
|
|
38332
|
+
description: "Internal: PreToolUse guard enforcing the max-profile native Task/Agent policy."
|
|
38333
|
+
},
|
|
38334
|
+
run() {
|
|
38335
|
+
const decision = decideMaxDispatchGuard(readStdinSync());
|
|
38336
|
+
if (!decision.allowed && decision.reason) process.stdout.write(maxDispatchDenyOutput(decision.reason));
|
|
38337
|
+
else if (decision.verdict === "allow" && decision.updatedInput) process.stdout.write(maxDispatchAllowOutput(decision.updatedInput));
|
|
38009
38338
|
process.exitCode = 0;
|
|
38010
38339
|
}
|
|
38011
38340
|
});
|
|
@@ -38040,7 +38369,8 @@ await runMain(defineCommand({
|
|
|
38040
38369
|
"internal-artifact-open": () => Promise.resolve().then(() => (init_internal_artifact_open(), internal_artifact_open_exports)).then((m) => m.internalArtifactOpen),
|
|
38041
38370
|
"internal-first-mate-guard": () => Promise.resolve().then(() => (init_internal_first_mate_guard(), internal_first_mate_guard_exports)).then((m) => m.internalFirstMateGuard),
|
|
38042
38371
|
"internal-worker-guard": () => Promise.resolve().then(() => (init_internal_worker_guard(), internal_worker_guard_exports)).then((m) => m.internalWorkerGuard),
|
|
38043
|
-
"internal-fast-dispatch-guard": () => Promise.resolve().then(() => (init_internal_fast_dispatch_guard(), internal_fast_dispatch_guard_exports)).then((m) => m.internalFastDispatchGuard)
|
|
38372
|
+
"internal-fast-dispatch-guard": () => Promise.resolve().then(() => (init_internal_fast_dispatch_guard(), internal_fast_dispatch_guard_exports)).then((m) => m.internalFastDispatchGuard),
|
|
38373
|
+
"internal-max-dispatch-guard": () => Promise.resolve().then(() => (init_internal_max_dispatch_guard(), internal_max_dispatch_guard_exports)).then((m) => m.internalMaxDispatchGuard)
|
|
38044
38374
|
}
|
|
38045
38375
|
}), { rawArgs: argv });
|
|
38046
38376
|
//#endregion
|
package/dist/hooks.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
a55923869f120eca4478614839bc65955717b68820314ab228c3e0082cf77e9c
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as ArtifactClient } from "./client-CQMfroGV.js";
|
|
2
|
-
import { a as isSubagentContext } from "./stop-gate-policy-
|
|
2
|
+
import { a as isSubagentContext } from "./stop-gate-policy-zhzRIj6G.js";
|
|
3
3
|
import { defineCommand } from "citty";
|
|
4
4
|
import { readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
@@ -316,4 +316,4 @@ const internalArtifactOpen = defineCommand({
|
|
|
316
316
|
//#endregion
|
|
317
317
|
export { internalArtifactOpen };
|
|
318
318
|
|
|
319
|
-
//# sourceMappingURL=internal-artifact-open-
|
|
319
|
+
//# sourceMappingURL=internal-artifact-open-DRSxShAW.js.map
|
package/dist/{internal-artifact-open-D6tKMg8v.js.map → internal-artifact-open-DRSxShAW.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-artifact-open-D6tKMg8v.js","names":[],"sources":["../src/lib/artifact/plan-html.ts","../src/internal-artifact-open.ts"],"sourcesContent":["/**\n * Render a plan's markdown into a self-contained, styled HTML document for the\n * ai-or-die Artifact panel. HTML is the canonical review artifact (lavish's\n * model); converting here means the hands-off auto-open shows a formatted,\n * annotatable page instead of raw markdown.\n *\n * Security: the iframe ai-or-die serves this into runs with\n * `allow-scripts allow-same-origin`, so a `<script>` smuggled into the plan\n * markdown could read the per-session asset token. Two defenses:\n * 1. marked is configured to ESCAPE raw HTML tokens (render as visible text).\n * 2. `link`/`image` hrefs with script-bearing schemes (javascript:, vbscript:,\n * non-image data:) are neutralised before rendering.\n * No separate sanitizer/dep needed.\n */\nimport { Marked } from \"marked\"\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n}\n\n/** Decode the HTML character references a browser would resolve in an attribute\n * value, so an entity-obfuscated scheme (`javascript:`, `javascript:`)\n * cannot slip past the scheme check below. Numeric refs cover any letter; the\n * small named map covers the scheme-relevant punctuation. */\nconst NAMED_REFS: Record<string, string> = {\n colon: \":\", tab: \"\\t\", newline: \"\\n\", sol: \"/\", semi: \";\", amp: \"&\", lpar: \"(\", rpar: \")\",\n}\nfunction decodeEntities(s: string): string {\n return s.replace(/&(#[xX][0-9a-fA-F]+|#[0-9]+|[a-zA-Z]+);?/g, (m, body: string) => {\n if (body[0] === \"#\") {\n const code = body[1] === \"x\" || body[1] === \"X\"\n ? Number.parseInt(body.slice(2), 16)\n : Number.parseInt(body.slice(1), 10)\n return Number.isFinite(code) && code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : m\n }\n return NAMED_REFS[body.toLowerCase()] ?? m\n })\n}\n\n/** Block script-bearing URL schemes (defense-in-depth on top of HTML escaping). */\nfunction isDangerousUrl(url: string, isImage: boolean): boolean {\n // Decode entities first (a browser resolves them in href), then drop ASCII\n // control chars + spaces (code <= 0x20) a browser ignores inside a scheme.\n const v = Array.from(decodeEntities(url)).filter((c) => c.charCodeAt(0) > 0x20).join(\"\").toLowerCase()\n if (v.startsWith(\"javascript:\") || v.startsWith(\"vbscript:\")) return true\n if (v.startsWith(\"data:\")) {\n // Allow only raster image data URIs (and only for <img>); SVG can script.\n return !(isImage && v.startsWith(\"data:image/\") && !v.startsWith(\"data:image/svg\"))\n }\n return false\n}\n\n/** A marked instance that escapes raw HTML (raw markup never becomes live). */\nfunction makeMarked(): Marked {\n const m = new Marked({ gfm: true, breaks: false })\n m.use({\n renderer: {\n // Raw HTML in the source is rendered as escaped text, never live markup.\n html(token: unknown): string {\n const text = typeof token === \"string\" ? token : ((token as { text?: string }).text ?? \"\")\n return escapeHtml(text)\n },\n },\n })\n return m\n}\n\ninterface MdToken {\n type?: string\n href?: string\n tokens?: MdToken[]\n items?: MdToken[]\n header?: Array<{ tokens?: MdToken[] }>\n rows?: Array<Array<{ tokens?: MdToken[] }>>\n}\n\n/**\n * Recursively neutralise script-bearing link/image hrefs in the lexed token tree.\n * Done as an explicit walk (not marked's `walkTokens` hook) because we render via\n * the low-level `lexer`+`parser` split, which does not run registered walkTokens.\n */\nfunction neutralizeUrls(tokens: MdToken[]): void {\n for (const t of tokens) {\n if ((t.type === \"link\" || t.type === \"image\") && typeof t.href === \"string\") {\n if (isDangerousUrl(t.href, t.type === \"image\")) t.href = \"#\"\n }\n if (t.tokens) neutralizeUrls(t.tokens)\n if (t.items) neutralizeUrls(t.items)\n if (t.header) for (const cell of t.header) if (cell.tokens) neutralizeUrls(cell.tokens)\n if (t.rows) for (const row of t.rows) for (const cell of row) if (cell.tokens) neutralizeUrls(cell.tokens)\n }\n}\n\n/** Add `data-source-line=\"N\"` to the first opening tag of a rendered block. */\nfunction tagSourceLine(html: string, line: number): string {\n return html.replace(/^(\\s*)<([a-zA-Z][\\w-]*)/, `$1<$2 data-source-line=\"${line}\"`)\n}\n\n/**\n * Render markdown to inner HTML, tagging each top-level block with its 1-based\n * source line so an annotation in the panel can map back to a plan line.\n */\nexport function renderMarkdownBody(source: string): string {\n const m = makeMarked()\n let tokens: Array<{ raw?: string }>\n try {\n tokens = m.lexer(source) as Array<{ raw?: string }>\n } catch {\n // Lexing should not fail, but never throw out of the hook path.\n return `<pre>${escapeHtml(source)}</pre>`\n }\n neutralizeUrls(tokens as MdToken[])\n let line = 1\n let out = \"\"\n for (const tok of tokens) {\n let html: string\n try {\n html = m.parser([tok] as Parameters<typeof m.parser>[0])\n } catch {\n html = \"\"\n }\n if (html.trim()) out += tagSourceLine(html, line)\n line += (tok.raw?.match(/\\n/g)?.length ?? 0)\n }\n return out || `<pre>${escapeHtml(source)}</pre>`\n}\n\n/**\n * Wrap rendered markdown in a complete, self-contained HTML document with\n * readable typography (works even before ai-or-die injects its annotation SDK).\n */\nexport function renderPlanHtml(source: string, title = \"Plan\"): string {\n return wrapArtifactDocument(renderMarkdownBody(source), title)\n}\n\nconst BASE_STYLE = ` :root {\n --bg: #0f1115; --fg: #f7f3ea; --muted: #aeb6c6; --border: #2a2f3a;\n --accent: #f4c95d; --code-bg: #171a21;\n --serif: 'Iowan Old Style', Georgia, 'Times New Roman', serif;\n --sans: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;\n --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n }\n * { box-sizing: border-box; }\n html, body { margin: 0; background: var(--bg); color: var(--fg); }\n body { font-family: var(--serif); font-size: 16px; line-height: 1.6;\n padding: 32px clamp(16px, 5vw, 56px); }\n main { max-width: 78ch; margin: 0 auto; }\n h1, h2, h3, h4 { font-family: var(--sans); line-height: 1.25; margin: 1.6em 0 0.5em; }\n h1 { font-size: 1.9em; } h2 { font-size: 1.45em; padding-bottom: 0.2em;\n border-bottom: 1px solid var(--border); } h3 { font-size: 1.2em; }\n p, li { color: var(--fg); }\n a { color: var(--accent); }\n code { font-family: var(--mono); font-size: 0.9em; background: var(--code-bg);\n padding: 0.12em 0.35em; border-radius: 5px; }\n pre { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px;\n padding: 12px 14px; overflow: auto; }\n pre code { background: none; padding: 0; }\n blockquote { margin: 1em 0; padding: 0.2em 1em; border-left: 3px solid var(--accent);\n color: var(--muted); }\n table { border-collapse: collapse; width: 100%; margin: 1em 0; font-family: var(--sans);\n font-size: 0.95em; }\n th, td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }\n th { background: var(--code-bg); }\n hr { border: 0; border-top: 1px solid var(--border); margin: 1.5em 0; }\n ul, ol { padding-left: 1.4em; }`\n\nconst INTERACTIVE_STYLE = `\n .aod-group { margin: 1.4em 0; padding: 14px 16px; border: 1px solid var(--border);\n border-radius: 10px; background: var(--code-bg); }\n .aod-prompt { font-family: var(--sans); font-weight: 600; margin: 0 0 0.6em; }\n .aod-options { display: flex; flex-wrap: wrap; gap: 8px; }\n .aod-multi-select .aod-options { flex-direction: column; gap: 6px; }\n .aod-action, .aod-submit { font-family: var(--sans); font-size: 0.95em; font-weight: 600;\n cursor: pointer; border: 1px solid var(--border); border-radius: 8px;\n padding: 8px 12px; background: var(--bg); color: var(--fg); }\n .aod-action:hover, .aod-submit:hover { border-color: var(--accent); }\n .aod-submit { margin-top: 10px; background: var(--accent); color: #17130a; border-color: var(--accent); }\n .aod-check { display: flex; align-items: center; gap: 8px; font-family: var(--sans); cursor: pointer; }\n .aod-steps { list-style: decimal; }\n .aod-step { margin: 0.5em 0; }\n .aod-step-actions { display: inline-flex; gap: 6px; margin-left: 8px; }`\n\n/**\n * Wrap rendered inner HTML in the self-contained document shell. `extraStyle` is\n * appended to the inline stylesheet so the interactive variant can add its own\n * rules without a second `<style>` block. Static callers pass \"\" (default), so\n * the static document is byte-identical to the pre-refactor output.\n */\nfunction wrapArtifactDocument(body: string, title: string, extraStyle = \"\"): string {\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${escapeHtml(title)}</title>\n<style>\n${BASE_STYLE}${extraStyle}\n</style>\n</head>\n<body>\n<main>\n${body}\n</main>\n</body>\n</html>\n`\n}\n\n/* -------------------------------------------------------------------------- */\n/* Interactive artifacts (contract v2.2 §4: declarative data-aod-* vocab) */\n/* -------------------------------------------------------------------------- */\n\nexport interface InteractiveOption {\n /** Stable id echoed back as `elementId` in the action event. Required. */\n elementId: string\n /** Human-visible label. */\n label: string\n /** Optional value echoed as `data-aod-value` (checkbox submits use \"true\"/\"false\"). */\n value?: string\n}\n\n/** One immediate-fire choice group: each option posts an action the instant it is clicked. */\nexport interface ChooseOneBlock {\n kind: \"choose-one\"\n /** `data-aod-group` shared by the options (marks them as one decision). */\n group: string\n prompt?: string\n /** `data-aod-action` verb for every option (default \"choose\"). */\n action?: string\n options: InteractiveOption[]\n}\n\n/** A multi-select group: checkbox toggles plus one submit that carries {group, selected}. */\nexport interface MultiSelectBlock {\n kind: \"multi-select\"\n group: string\n prompt?: string\n submitLabel?: string\n submitElementId?: string\n options: InteractiveOption[]\n}\n\nexport interface StepAction {\n /** `data-aod-action` verb (e.g. \"approve\", \"skip\"). */\n action: string\n label: string\n value?: string\n}\n\nexport interface StepItem {\n /** Stable `data-aod-id` echoed as `elementId`. */\n elementId: string\n label: string\n sourceLine?: number\n actions: StepAction[]\n}\n\n/** An ordered list of plan steps, each with its own inline action buttons. */\nexport interface StepsBlock {\n kind: \"steps\"\n steps: StepItem[]\n}\n\nexport type InteractiveBlock = ChooseOneBlock | MultiSelectBlock | StepsBlock\n\nexport interface InteractivePlanModel {\n /** Optional prose rendered above the interactive blocks (same escaping as static). */\n markdown?: string\n blocks: InteractiveBlock[]\n}\n\n/** Build a ` data-x=\"y\"` attribute string, dropping undefined values, all escaped. */\nfunction dataAttrs(pairs: Array<[string, string | undefined]>): string {\n let out = \"\"\n for (const [name, value] of pairs) {\n if (value === undefined) continue\n out += ` ${name}=\"${escapeHtml(value)}\"`\n }\n return out\n}\n\nfunction renderChooseOne(block: ChooseOneBlock): string {\n const action = block.action && block.action.trim() ? block.action : \"choose\"\n const prompt = block.prompt ? `<p class=\"aod-prompt\">${escapeHtml(block.prompt)}</p>` : \"\"\n const options = block.options\n .filter((o) => o.elementId.trim() !== \"\")\n .map((o) => {\n const attrs = dataAttrs([\n [\"data-aod-action\", action],\n [\"data-aod-group\", block.group],\n [\"data-aod-id\", o.elementId],\n [\"data-aod-value\", o.value],\n ])\n return `<button type=\"button\" class=\"aod-action\"${attrs}>${escapeHtml(o.label)}</button>`\n })\n .join(\"\\n\")\n return `<div class=\"aod-group aod-choose-one\"${dataAttrs([[\"data-aod-group\", block.group]])}>\n${prompt}<div class=\"aod-options\">\n${options}\n</div>\n</div>`\n}\n\nfunction renderMultiSelect(block: MultiSelectBlock): string {\n const prompt = block.prompt ? `<p class=\"aod-prompt\">${escapeHtml(block.prompt)}</p>` : \"\"\n const options = block.options\n .filter((o) => o.elementId.trim() !== \"\")\n .map((o) => {\n const attrs = dataAttrs([\n [\"data-aod-action\", \"check\"],\n [\"data-aod-group\", block.group],\n [\"data-aod-id\", o.elementId],\n [\"data-aod-value\", o.value],\n ])\n return `<label class=\"aod-check\"><input type=\"checkbox\"${attrs}> <span>${escapeHtml(o.label)}</span></label>`\n })\n .join(\"\\n\")\n const submitId = block.submitElementId && block.submitElementId.trim()\n ? block.submitElementId\n : `${block.group}-submit`\n const submitAttrs = dataAttrs([\n [\"data-aod-action\", \"submit\"],\n [\"data-aod-group\", block.group],\n [\"data-aod-id\", submitId],\n ])\n const submitLabel = block.submitLabel && block.submitLabel.trim() ? block.submitLabel : \"Submit\"\n return `<div class=\"aod-group aod-multi-select\"${dataAttrs([[\"data-aod-group\", block.group]])}>\n${prompt}<div class=\"aod-options\">\n${options}\n</div>\n<button type=\"button\" class=\"aod-submit\"${submitAttrs}>${escapeHtml(submitLabel)}</button>\n</div>`\n}\n\nfunction renderSteps(block: StepsBlock): string {\n const items = block.steps\n .filter((s) => s.elementId.trim() !== \"\")\n .map((s) => {\n const liAttrs = dataAttrs([\n [\"data-aod-id\", s.elementId],\n [\"data-source-line\", s.sourceLine === undefined ? undefined : String(s.sourceLine)],\n ])\n const actions = s.actions\n .map((a) => {\n const attrs = dataAttrs([\n [\"data-aod-action\", a.action],\n [\"data-aod-id\", s.elementId],\n [\"data-aod-value\", a.value],\n ])\n return `<button type=\"button\" class=\"aod-action\"${attrs}>${escapeHtml(a.label)}</button>`\n })\n .join(\"\")\n return `<li class=\"aod-step\"${liAttrs}><span class=\"aod-step-label\">${escapeHtml(s.label)}</span><span class=\"aod-step-actions\">${actions}</span></li>`\n })\n .join(\"\\n\")\n return `<ol class=\"aod-steps\">\n${items}\n</ol>`\n}\n\nfunction renderInteractiveBlock(block: InteractiveBlock): string {\n switch (block.kind) {\n case \"choose-one\":\n return renderChooseOne(block)\n case \"multi-select\":\n return renderMultiSelect(block)\n case \"steps\":\n return renderSteps(block)\n default:\n return \"\"\n }\n}\n\n/**\n * Render a typed interactive plan model into a self-contained HTML document that\n * carries the declarative `data-aod-*` action vocabulary the ai-or-die panel SDK\n * wires (contract v2.2 §4). Optional prose (`markdown`) is rendered with the SAME\n * escaping + dangerous-URL neutralization as the static path; all control\n * attributes and labels are HTML-escaped, so no author string can break out of an\n * attribute or inject live markup.\n */\nexport function renderInteractivePlanHtml(model: InteractivePlanModel, title = \"Plan\"): string {\n const prose = model.markdown && model.markdown.trim() ? renderMarkdownBody(model.markdown) : \"\"\n const blocks = model.blocks.map(renderInteractiveBlock).filter((h) => h.trim() !== \"\").join(\"\\n\")\n const body = [prose, blocks].filter((s) => s.trim() !== \"\").join(\"\\n\")\n return wrapArtifactDocument(body || `<pre>${escapeHtml(JSON.stringify(model))}</pre>`, title, INTERACTIVE_STYLE)\n}\n","/**\n * The internal `internal-artifact-open` subcommand: invoked by a spawned Claude\n * Code session's `PostToolUse` hook (matcher `ExitPlanMode`), registered into the\n * mirrored settings.json by the launcher when running inside an ai-or-die tab\n * (`AIORDIE_SESSION_ID` set). It auto-opens the just-finalized plan in the\n * ai-or-die Artifact review panel so the human reviews it WITHOUT the model\n * having to call artifact_open itself.\n *\n * Auth: AIORDIE_TOKEN is stripped from the child env, so the token can't come via\n * env or argv (argv leaks to `ps`). The launcher writes a mode-600\n * `.aiordie-artifact.json` into CLAUDE_CONFIG_DIR; this hook reads it.\n *\n * Plan: the EXACT plan for THIS session comes from the ExitPlanMode payload —\n * `tool_input.planFilePath` (per-session; never the globally-newest file in the\n * shared plans dir) with `tool_input.plan` as the markdown fallback. The plan\n * markdown is rendered to a self-contained styled HTML file (HTML is the\n * canonical artifact, lavish's model — formatted + annotatable, not raw md), and\n * THAT `.html` is opened.\n *\n * Side-effect only: never writes stdout, never throws, always exits 0. Skips\n * subagent payloads (agent_id/agent_type) like the other hooks.\n */\n\nimport { defineCommand } from \"citty\"\n\nimport { readFileSync, realpathSync, writeFileSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport path from \"node:path\"\n\nimport { ArtifactClient } from \"./lib/artifact/client\"\nimport { renderPlanHtml } from \"./lib/artifact/plan-html\"\nimport { isSubagentContext } from \"./lib/orchestration/stop-gate-policy\"\n\ninterface ArtifactCreds {\n baseUrl: string\n token: string\n sessionId: string\n insecureTLS: boolean\n}\n\ninterface ExitPlanPayload {\n planFilePath?: string\n planMarkdown?: string\n}\n\nfunction readStdin(): string {\n try {\n if (process.stdin.isTTY) return \"\"\n return readFileSync(0, \"utf8\")\n } catch {\n return \"\"\n }\n}\n\nfunction credsPath(): string {\n const dir = process.env.CLAUDE_CONFIG_DIR || path.join(homedir(), \".claude\")\n return path.join(dir, \".aiordie-artifact.json\")\n}\n\nfunction isSubagent(payload: unknown): boolean {\n try {\n return isSubagentContext(payload as Parameters<typeof isSubagentContext>[0])\n } catch {\n return false\n }\n}\n\n/** Pull the per-session plan path + markdown content out of the hook payload. */\nexport function parseExitPlanPayload(raw: string): ExitPlanPayload {\n try {\n const obj = JSON.parse(raw) as { tool_input?: { planFilePath?: unknown; plan?: unknown } }\n const ti = obj.tool_input ?? {}\n const planFilePath = typeof ti.planFilePath === \"string\" && ti.planFilePath.trim() ? ti.planFilePath : undefined\n const planMarkdown = typeof ti.plan === \"string\" && ti.plan.trim() ? ti.plan : undefined\n return { planFilePath, planMarkdown }\n } catch {\n return {}\n }\n}\n\nfunction readCreds(): ArtifactCreds | undefined {\n try {\n const parsed = JSON.parse(readFileSync(credsPath(), \"utf8\")) as Partial<ArtifactCreds>\n if (!parsed.baseUrl || !parsed.token || !parsed.sessionId) return undefined\n return {\n baseUrl: parsed.baseUrl,\n token: parsed.token,\n sessionId: parsed.sessionId,\n insecureTLS: parsed.insecureTLS === true,\n }\n } catch {\n return undefined\n }\n}\n\n/**\n * Resolve the plan markdown + a title, preferring the file at `planFilePath`\n * (the source of truth, may be newer than the payload's snapshot), falling back\n * to the inline `tool_input.plan` content.\n */\nfunction resolvePlanMarkdown(p: ExitPlanPayload): { markdown: string; title: string; nearPath?: string } | undefined {\n if (p.planFilePath) {\n try {\n const md = readFileSync(p.planFilePath, \"utf8\")\n if (md.trim()) return { markdown: md, title: path.basename(p.planFilePath, path.extname(p.planFilePath)), nearPath: p.planFilePath }\n } catch {\n /* fall through to inline content */\n }\n }\n if (p.planMarkdown) return { markdown: p.planMarkdown, title: \"Plan\" }\n return undefined\n}\n\n/**\n * Write the rendered HTML next to the plan (an allowed root) when we have a real\n * path, else into the plans dir under CLAUDE_CONFIG_DIR. Returns the realpath of\n * the written `.html`, or undefined on failure.\n */\nfunction writePlanHtml(html: string, nearPath: string | undefined): string | undefined {\n let target: string\n if (nearPath) {\n // `<plan>.md` -> `<plan>.aiordie.html` (or append when there is no .md ext).\n const base = nearPath.replace(/\\.(md|markdown)$/i, \"\")\n target = `${base}.aiordie.html`\n } else {\n const dir = path.join(process.env.CLAUDE_CONFIG_DIR || path.join(homedir(), \".claude\"), \"plans\")\n target = path.join(dir, `aiordie-plan-${process.pid}.html`)\n }\n try {\n writeFileSync(target, html, \"utf8\")\n try {\n return realpathSync.native(target)\n } catch {\n return target\n }\n } catch {\n return undefined\n }\n}\n\nexport const internalArtifactOpen = defineCommand({\n meta: { name: \"internal-artifact-open\", description: \"Open the finalized plan in the ai-or-die panel\" },\n async run() {\n try {\n const raw = readStdin()\n let payload: unknown\n try {\n payload = JSON.parse(raw)\n } catch {\n payload = undefined\n }\n if (isSubagent(payload)) return\n const creds = readCreds()\n if (!creds) return\n const plan = resolvePlanMarkdown(parseExitPlanPayload(raw))\n if (!plan) return\n const htmlPath = writePlanHtml(renderPlanHtml(plan.markdown, plan.title), plan.nearPath)\n if (!htmlPath) return\n const client = new ArtifactClient(creds)\n await client.open(htmlPath)\n } catch {\n /* side-effect only: never block, never throw */\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal-artifact-open-DRSxShAW.js","names":[],"sources":["../src/lib/artifact/plan-html.ts","../src/internal-artifact-open.ts"],"sourcesContent":["/**\n * Render a plan's markdown into a self-contained, styled HTML document for the\n * ai-or-die Artifact panel. HTML is the canonical review artifact (lavish's\n * model); converting here means the hands-off auto-open shows a formatted,\n * annotatable page instead of raw markdown.\n *\n * Security: the iframe ai-or-die serves this into runs with\n * `allow-scripts allow-same-origin`, so a `<script>` smuggled into the plan\n * markdown could read the per-session asset token. Two defenses:\n * 1. marked is configured to ESCAPE raw HTML tokens (render as visible text).\n * 2. `link`/`image` hrefs with script-bearing schemes (javascript:, vbscript:,\n * non-image data:) are neutralised before rendering.\n * No separate sanitizer/dep needed.\n */\nimport { Marked } from \"marked\"\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\")\n}\n\n/** Decode the HTML character references a browser would resolve in an attribute\n * value, so an entity-obfuscated scheme (`javascript:`, `javascript:`)\n * cannot slip past the scheme check below. Numeric refs cover any letter; the\n * small named map covers the scheme-relevant punctuation. */\nconst NAMED_REFS: Record<string, string> = {\n colon: \":\", tab: \"\\t\", newline: \"\\n\", sol: \"/\", semi: \";\", amp: \"&\", lpar: \"(\", rpar: \")\",\n}\nfunction decodeEntities(s: string): string {\n return s.replace(/&(#[xX][0-9a-fA-F]+|#[0-9]+|[a-zA-Z]+);?/g, (m, body: string) => {\n if (body[0] === \"#\") {\n const code = body[1] === \"x\" || body[1] === \"X\"\n ? Number.parseInt(body.slice(2), 16)\n : Number.parseInt(body.slice(1), 10)\n return Number.isFinite(code) && code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : m\n }\n return NAMED_REFS[body.toLowerCase()] ?? m\n })\n}\n\n/** Block script-bearing URL schemes (defense-in-depth on top of HTML escaping). */\nfunction isDangerousUrl(url: string, isImage: boolean): boolean {\n // Decode entities first (a browser resolves them in href), then drop ASCII\n // control chars + spaces (code <= 0x20) a browser ignores inside a scheme.\n const v = Array.from(decodeEntities(url)).filter((c) => c.charCodeAt(0) > 0x20).join(\"\").toLowerCase()\n if (v.startsWith(\"javascript:\") || v.startsWith(\"vbscript:\")) return true\n if (v.startsWith(\"data:\")) {\n // Allow only raster image data URIs (and only for <img>); SVG can script.\n return !(isImage && v.startsWith(\"data:image/\") && !v.startsWith(\"data:image/svg\"))\n }\n return false\n}\n\n/** A marked instance that escapes raw HTML (raw markup never becomes live). */\nfunction makeMarked(): Marked {\n const m = new Marked({ gfm: true, breaks: false })\n m.use({\n renderer: {\n // Raw HTML in the source is rendered as escaped text, never live markup.\n html(token: unknown): string {\n const text = typeof token === \"string\" ? token : ((token as { text?: string }).text ?? \"\")\n return escapeHtml(text)\n },\n },\n })\n return m\n}\n\ninterface MdToken {\n type?: string\n href?: string\n tokens?: MdToken[]\n items?: MdToken[]\n header?: Array<{ tokens?: MdToken[] }>\n rows?: Array<Array<{ tokens?: MdToken[] }>>\n}\n\n/**\n * Recursively neutralise script-bearing link/image hrefs in the lexed token tree.\n * Done as an explicit walk (not marked's `walkTokens` hook) because we render via\n * the low-level `lexer`+`parser` split, which does not run registered walkTokens.\n */\nfunction neutralizeUrls(tokens: MdToken[]): void {\n for (const t of tokens) {\n if ((t.type === \"link\" || t.type === \"image\") && typeof t.href === \"string\") {\n if (isDangerousUrl(t.href, t.type === \"image\")) t.href = \"#\"\n }\n if (t.tokens) neutralizeUrls(t.tokens)\n if (t.items) neutralizeUrls(t.items)\n if (t.header) for (const cell of t.header) if (cell.tokens) neutralizeUrls(cell.tokens)\n if (t.rows) for (const row of t.rows) for (const cell of row) if (cell.tokens) neutralizeUrls(cell.tokens)\n }\n}\n\n/** Add `data-source-line=\"N\"` to the first opening tag of a rendered block. */\nfunction tagSourceLine(html: string, line: number): string {\n return html.replace(/^(\\s*)<([a-zA-Z][\\w-]*)/, `$1<$2 data-source-line=\"${line}\"`)\n}\n\n/**\n * Render markdown to inner HTML, tagging each top-level block with its 1-based\n * source line so an annotation in the panel can map back to a plan line.\n */\nexport function renderMarkdownBody(source: string): string {\n const m = makeMarked()\n let tokens: Array<{ raw?: string }>\n try {\n tokens = m.lexer(source) as Array<{ raw?: string }>\n } catch {\n // Lexing should not fail, but never throw out of the hook path.\n return `<pre>${escapeHtml(source)}</pre>`\n }\n neutralizeUrls(tokens as MdToken[])\n let line = 1\n let out = \"\"\n for (const tok of tokens) {\n let html: string\n try {\n html = m.parser([tok] as Parameters<typeof m.parser>[0])\n } catch {\n html = \"\"\n }\n if (html.trim()) out += tagSourceLine(html, line)\n line += (tok.raw?.match(/\\n/g)?.length ?? 0)\n }\n return out || `<pre>${escapeHtml(source)}</pre>`\n}\n\n/**\n * Wrap rendered markdown in a complete, self-contained HTML document with\n * readable typography (works even before ai-or-die injects its annotation SDK).\n */\nexport function renderPlanHtml(source: string, title = \"Plan\"): string {\n return wrapArtifactDocument(renderMarkdownBody(source), title)\n}\n\nconst BASE_STYLE = ` :root {\n --bg: #0f1115; --fg: #f7f3ea; --muted: #aeb6c6; --border: #2a2f3a;\n --accent: #f4c95d; --code-bg: #171a21;\n --serif: 'Iowan Old Style', Georgia, 'Times New Roman', serif;\n --sans: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;\n --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n }\n * { box-sizing: border-box; }\n html, body { margin: 0; background: var(--bg); color: var(--fg); }\n body { font-family: var(--serif); font-size: 16px; line-height: 1.6;\n padding: 32px clamp(16px, 5vw, 56px); }\n main { max-width: 78ch; margin: 0 auto; }\n h1, h2, h3, h4 { font-family: var(--sans); line-height: 1.25; margin: 1.6em 0 0.5em; }\n h1 { font-size: 1.9em; } h2 { font-size: 1.45em; padding-bottom: 0.2em;\n border-bottom: 1px solid var(--border); } h3 { font-size: 1.2em; }\n p, li { color: var(--fg); }\n a { color: var(--accent); }\n code { font-family: var(--mono); font-size: 0.9em; background: var(--code-bg);\n padding: 0.12em 0.35em; border-radius: 5px; }\n pre { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px;\n padding: 12px 14px; overflow: auto; }\n pre code { background: none; padding: 0; }\n blockquote { margin: 1em 0; padding: 0.2em 1em; border-left: 3px solid var(--accent);\n color: var(--muted); }\n table { border-collapse: collapse; width: 100%; margin: 1em 0; font-family: var(--sans);\n font-size: 0.95em; }\n th, td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }\n th { background: var(--code-bg); }\n hr { border: 0; border-top: 1px solid var(--border); margin: 1.5em 0; }\n ul, ol { padding-left: 1.4em; }`\n\nconst INTERACTIVE_STYLE = `\n .aod-group { margin: 1.4em 0; padding: 14px 16px; border: 1px solid var(--border);\n border-radius: 10px; background: var(--code-bg); }\n .aod-prompt { font-family: var(--sans); font-weight: 600; margin: 0 0 0.6em; }\n .aod-options { display: flex; flex-wrap: wrap; gap: 8px; }\n .aod-multi-select .aod-options { flex-direction: column; gap: 6px; }\n .aod-action, .aod-submit { font-family: var(--sans); font-size: 0.95em; font-weight: 600;\n cursor: pointer; border: 1px solid var(--border); border-radius: 8px;\n padding: 8px 12px; background: var(--bg); color: var(--fg); }\n .aod-action:hover, .aod-submit:hover { border-color: var(--accent); }\n .aod-submit { margin-top: 10px; background: var(--accent); color: #17130a; border-color: var(--accent); }\n .aod-check { display: flex; align-items: center; gap: 8px; font-family: var(--sans); cursor: pointer; }\n .aod-steps { list-style: decimal; }\n .aod-step { margin: 0.5em 0; }\n .aod-step-actions { display: inline-flex; gap: 6px; margin-left: 8px; }`\n\n/**\n * Wrap rendered inner HTML in the self-contained document shell. `extraStyle` is\n * appended to the inline stylesheet so the interactive variant can add its own\n * rules without a second `<style>` block. Static callers pass \"\" (default), so\n * the static document is byte-identical to the pre-refactor output.\n */\nfunction wrapArtifactDocument(body: string, title: string, extraStyle = \"\"): string {\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${escapeHtml(title)}</title>\n<style>\n${BASE_STYLE}${extraStyle}\n</style>\n</head>\n<body>\n<main>\n${body}\n</main>\n</body>\n</html>\n`\n}\n\n/* -------------------------------------------------------------------------- */\n/* Interactive artifacts (contract v2.2 §4: declarative data-aod-* vocab) */\n/* -------------------------------------------------------------------------- */\n\nexport interface InteractiveOption {\n /** Stable id echoed back as `elementId` in the action event. Required. */\n elementId: string\n /** Human-visible label. */\n label: string\n /** Optional value echoed as `data-aod-value` (checkbox submits use \"true\"/\"false\"). */\n value?: string\n}\n\n/** One immediate-fire choice group: each option posts an action the instant it is clicked. */\nexport interface ChooseOneBlock {\n kind: \"choose-one\"\n /** `data-aod-group` shared by the options (marks them as one decision). */\n group: string\n prompt?: string\n /** `data-aod-action` verb for every option (default \"choose\"). */\n action?: string\n options: InteractiveOption[]\n}\n\n/** A multi-select group: checkbox toggles plus one submit that carries {group, selected}. */\nexport interface MultiSelectBlock {\n kind: \"multi-select\"\n group: string\n prompt?: string\n submitLabel?: string\n submitElementId?: string\n options: InteractiveOption[]\n}\n\nexport interface StepAction {\n /** `data-aod-action` verb (e.g. \"approve\", \"skip\"). */\n action: string\n label: string\n value?: string\n}\n\nexport interface StepItem {\n /** Stable `data-aod-id` echoed as `elementId`. */\n elementId: string\n label: string\n sourceLine?: number\n actions: StepAction[]\n}\n\n/** An ordered list of plan steps, each with its own inline action buttons. */\nexport interface StepsBlock {\n kind: \"steps\"\n steps: StepItem[]\n}\n\nexport type InteractiveBlock = ChooseOneBlock | MultiSelectBlock | StepsBlock\n\nexport interface InteractivePlanModel {\n /** Optional prose rendered above the interactive blocks (same escaping as static). */\n markdown?: string\n blocks: InteractiveBlock[]\n}\n\n/** Build a ` data-x=\"y\"` attribute string, dropping undefined values, all escaped. */\nfunction dataAttrs(pairs: Array<[string, string | undefined]>): string {\n let out = \"\"\n for (const [name, value] of pairs) {\n if (value === undefined) continue\n out += ` ${name}=\"${escapeHtml(value)}\"`\n }\n return out\n}\n\nfunction renderChooseOne(block: ChooseOneBlock): string {\n const action = block.action && block.action.trim() ? block.action : \"choose\"\n const prompt = block.prompt ? `<p class=\"aod-prompt\">${escapeHtml(block.prompt)}</p>` : \"\"\n const options = block.options\n .filter((o) => o.elementId.trim() !== \"\")\n .map((o) => {\n const attrs = dataAttrs([\n [\"data-aod-action\", action],\n [\"data-aod-group\", block.group],\n [\"data-aod-id\", o.elementId],\n [\"data-aod-value\", o.value],\n ])\n return `<button type=\"button\" class=\"aod-action\"${attrs}>${escapeHtml(o.label)}</button>`\n })\n .join(\"\\n\")\n return `<div class=\"aod-group aod-choose-one\"${dataAttrs([[\"data-aod-group\", block.group]])}>\n${prompt}<div class=\"aod-options\">\n${options}\n</div>\n</div>`\n}\n\nfunction renderMultiSelect(block: MultiSelectBlock): string {\n const prompt = block.prompt ? `<p class=\"aod-prompt\">${escapeHtml(block.prompt)}</p>` : \"\"\n const options = block.options\n .filter((o) => o.elementId.trim() !== \"\")\n .map((o) => {\n const attrs = dataAttrs([\n [\"data-aod-action\", \"check\"],\n [\"data-aod-group\", block.group],\n [\"data-aod-id\", o.elementId],\n [\"data-aod-value\", o.value],\n ])\n return `<label class=\"aod-check\"><input type=\"checkbox\"${attrs}> <span>${escapeHtml(o.label)}</span></label>`\n })\n .join(\"\\n\")\n const submitId = block.submitElementId && block.submitElementId.trim()\n ? block.submitElementId\n : `${block.group}-submit`\n const submitAttrs = dataAttrs([\n [\"data-aod-action\", \"submit\"],\n [\"data-aod-group\", block.group],\n [\"data-aod-id\", submitId],\n ])\n const submitLabel = block.submitLabel && block.submitLabel.trim() ? block.submitLabel : \"Submit\"\n return `<div class=\"aod-group aod-multi-select\"${dataAttrs([[\"data-aod-group\", block.group]])}>\n${prompt}<div class=\"aod-options\">\n${options}\n</div>\n<button type=\"button\" class=\"aod-submit\"${submitAttrs}>${escapeHtml(submitLabel)}</button>\n</div>`\n}\n\nfunction renderSteps(block: StepsBlock): string {\n const items = block.steps\n .filter((s) => s.elementId.trim() !== \"\")\n .map((s) => {\n const liAttrs = dataAttrs([\n [\"data-aod-id\", s.elementId],\n [\"data-source-line\", s.sourceLine === undefined ? undefined : String(s.sourceLine)],\n ])\n const actions = s.actions\n .map((a) => {\n const attrs = dataAttrs([\n [\"data-aod-action\", a.action],\n [\"data-aod-id\", s.elementId],\n [\"data-aod-value\", a.value],\n ])\n return `<button type=\"button\" class=\"aod-action\"${attrs}>${escapeHtml(a.label)}</button>`\n })\n .join(\"\")\n return `<li class=\"aod-step\"${liAttrs}><span class=\"aod-step-label\">${escapeHtml(s.label)}</span><span class=\"aod-step-actions\">${actions}</span></li>`\n })\n .join(\"\\n\")\n return `<ol class=\"aod-steps\">\n${items}\n</ol>`\n}\n\nfunction renderInteractiveBlock(block: InteractiveBlock): string {\n switch (block.kind) {\n case \"choose-one\":\n return renderChooseOne(block)\n case \"multi-select\":\n return renderMultiSelect(block)\n case \"steps\":\n return renderSteps(block)\n default:\n return \"\"\n }\n}\n\n/**\n * Render a typed interactive plan model into a self-contained HTML document that\n * carries the declarative `data-aod-*` action vocabulary the ai-or-die panel SDK\n * wires (contract v2.2 §4). Optional prose (`markdown`) is rendered with the SAME\n * escaping + dangerous-URL neutralization as the static path; all control\n * attributes and labels are HTML-escaped, so no author string can break out of an\n * attribute or inject live markup.\n */\nexport function renderInteractivePlanHtml(model: InteractivePlanModel, title = \"Plan\"): string {\n const prose = model.markdown && model.markdown.trim() ? renderMarkdownBody(model.markdown) : \"\"\n const blocks = model.blocks.map(renderInteractiveBlock).filter((h) => h.trim() !== \"\").join(\"\\n\")\n const body = [prose, blocks].filter((s) => s.trim() !== \"\").join(\"\\n\")\n return wrapArtifactDocument(body || `<pre>${escapeHtml(JSON.stringify(model))}</pre>`, title, INTERACTIVE_STYLE)\n}\n","/**\n * The internal `internal-artifact-open` subcommand: invoked by a spawned Claude\n * Code session's `PostToolUse` hook (matcher `ExitPlanMode`), registered into the\n * mirrored settings.json by the launcher when running inside an ai-or-die tab\n * (`AIORDIE_SESSION_ID` set). It auto-opens the just-finalized plan in the\n * ai-or-die Artifact review panel so the human reviews it WITHOUT the model\n * having to call artifact_open itself.\n *\n * Auth: AIORDIE_TOKEN is stripped from the child env, so the token can't come via\n * env or argv (argv leaks to `ps`). The launcher writes a mode-600\n * `.aiordie-artifact.json` into CLAUDE_CONFIG_DIR; this hook reads it.\n *\n * Plan: the EXACT plan for THIS session comes from the ExitPlanMode payload —\n * `tool_input.planFilePath` (per-session; never the globally-newest file in the\n * shared plans dir) with `tool_input.plan` as the markdown fallback. The plan\n * markdown is rendered to a self-contained styled HTML file (HTML is the\n * canonical artifact, lavish's model — formatted + annotatable, not raw md), and\n * THAT `.html` is opened.\n *\n * Side-effect only: never writes stdout, never throws, always exits 0. Skips\n * subagent payloads (agent_id/agent_type) like the other hooks.\n */\n\nimport { defineCommand } from \"citty\"\n\nimport { readFileSync, realpathSync, writeFileSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport path from \"node:path\"\n\nimport { ArtifactClient } from \"./lib/artifact/client\"\nimport { renderPlanHtml } from \"./lib/artifact/plan-html\"\nimport { isSubagentContext } from \"./lib/orchestration/stop-gate-policy\"\n\ninterface ArtifactCreds {\n baseUrl: string\n token: string\n sessionId: string\n insecureTLS: boolean\n}\n\ninterface ExitPlanPayload {\n planFilePath?: string\n planMarkdown?: string\n}\n\nfunction readStdin(): string {\n try {\n if (process.stdin.isTTY) return \"\"\n return readFileSync(0, \"utf8\")\n } catch {\n return \"\"\n }\n}\n\nfunction credsPath(): string {\n const dir = process.env.CLAUDE_CONFIG_DIR || path.join(homedir(), \".claude\")\n return path.join(dir, \".aiordie-artifact.json\")\n}\n\nfunction isSubagent(payload: unknown): boolean {\n try {\n return isSubagentContext(payload as Parameters<typeof isSubagentContext>[0])\n } catch {\n return false\n }\n}\n\n/** Pull the per-session plan path + markdown content out of the hook payload. */\nexport function parseExitPlanPayload(raw: string): ExitPlanPayload {\n try {\n const obj = JSON.parse(raw) as { tool_input?: { planFilePath?: unknown; plan?: unknown } }\n const ti = obj.tool_input ?? {}\n const planFilePath = typeof ti.planFilePath === \"string\" && ti.planFilePath.trim() ? ti.planFilePath : undefined\n const planMarkdown = typeof ti.plan === \"string\" && ti.plan.trim() ? ti.plan : undefined\n return { planFilePath, planMarkdown }\n } catch {\n return {}\n }\n}\n\nfunction readCreds(): ArtifactCreds | undefined {\n try {\n const parsed = JSON.parse(readFileSync(credsPath(), \"utf8\")) as Partial<ArtifactCreds>\n if (!parsed.baseUrl || !parsed.token || !parsed.sessionId) return undefined\n return {\n baseUrl: parsed.baseUrl,\n token: parsed.token,\n sessionId: parsed.sessionId,\n insecureTLS: parsed.insecureTLS === true,\n }\n } catch {\n return undefined\n }\n}\n\n/**\n * Resolve the plan markdown + a title, preferring the file at `planFilePath`\n * (the source of truth, may be newer than the payload's snapshot), falling back\n * to the inline `tool_input.plan` content.\n */\nfunction resolvePlanMarkdown(p: ExitPlanPayload): { markdown: string; title: string; nearPath?: string } | undefined {\n if (p.planFilePath) {\n try {\n const md = readFileSync(p.planFilePath, \"utf8\")\n if (md.trim()) return { markdown: md, title: path.basename(p.planFilePath, path.extname(p.planFilePath)), nearPath: p.planFilePath }\n } catch {\n /* fall through to inline content */\n }\n }\n if (p.planMarkdown) return { markdown: p.planMarkdown, title: \"Plan\" }\n return undefined\n}\n\n/**\n * Write the rendered HTML next to the plan (an allowed root) when we have a real\n * path, else into the plans dir under CLAUDE_CONFIG_DIR. Returns the realpath of\n * the written `.html`, or undefined on failure.\n */\nfunction writePlanHtml(html: string, nearPath: string | undefined): string | undefined {\n let target: string\n if (nearPath) {\n // `<plan>.md` -> `<plan>.aiordie.html` (or append when there is no .md ext).\n const base = nearPath.replace(/\\.(md|markdown)$/i, \"\")\n target = `${base}.aiordie.html`\n } else {\n const dir = path.join(process.env.CLAUDE_CONFIG_DIR || path.join(homedir(), \".claude\"), \"plans\")\n target = path.join(dir, `aiordie-plan-${process.pid}.html`)\n }\n try {\n writeFileSync(target, html, \"utf8\")\n try {\n return realpathSync.native(target)\n } catch {\n return target\n }\n } catch {\n return undefined\n }\n}\n\nexport const internalArtifactOpen = defineCommand({\n meta: { name: \"internal-artifact-open\", description: \"Open the finalized plan in the ai-or-die panel\" },\n async run() {\n try {\n const raw = readStdin()\n let payload: unknown\n try {\n payload = JSON.parse(raw)\n } catch {\n payload = undefined\n }\n if (isSubagent(payload)) return\n const creds = readCreds()\n if (!creds) return\n const plan = resolvePlanMarkdown(parseExitPlanPayload(raw))\n if (!plan) return\n const htmlPath = writePlanHtml(renderPlanHtml(plan.markdown, plan.title), plan.nearPath)\n if (!htmlPath) return\n const client = new ArtifactClient(creds)\n await client.open(htmlPath)\n } catch {\n /* side-effect only: never block, never throw */\n }\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAgBA,SAAS,WAAW,GAAmB;CACrC,OAAO,EACJ,QAAQ,MAAM,OAAO,CAAC,CACtB,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,QAAQ,CAAC,CACvB,QAAQ,MAAM,OAAO;AAC1B;;;;;AAMA,MAAM,aAAqC;CACzC,OAAO;CAAK,KAAK;CAAM,SAAS;CAAM,KAAK;CAAK,MAAM;CAAK,KAAK;CAAK,MAAM;CAAK,MAAM;AACxF;AACA,SAAS,eAAe,GAAmB;CACzC,OAAO,EAAE,QAAQ,8CAA8C,GAAG,SAAiB;EACjF,IAAI,KAAK,OAAO,KAAK;GACnB,MAAM,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,MACxC,OAAO,SAAS,KAAK,MAAM,CAAC,GAAG,EAAE,IACjC,OAAO,SAAS,KAAK,MAAM,CAAC,GAAG,EAAE;GACrC,OAAO,OAAO,SAAS,IAAI,KAAK,OAAO,KAAK,QAAQ,UAAW,OAAO,cAAc,IAAI,IAAI;EAC9F;EACA,OAAO,WAAW,KAAK,YAAY,MAAM;CAC3C,CAAC;AACH;;AAGA,SAAS,eAAe,KAAa,SAA2B;CAG9D,MAAM,IAAI,MAAM,KAAK,eAAe,GAAG,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,WAAW,CAAC,IAAI,EAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,YAAY;CACrG,IAAI,EAAE,WAAW,aAAa,KAAK,EAAE,WAAW,WAAW,GAAG,OAAO;CACrE,IAAI,EAAE,WAAW,OAAO,GAEtB,OAAO,EAAE,WAAW,EAAE,WAAW,aAAa,KAAK,CAAC,EAAE,WAAW,gBAAgB;CAEnF,OAAO;AACT;;AAGA,SAAS,aAAqB;CAC5B,MAAM,IAAI,IAAI,OAAO;EAAE,KAAK;EAAM,QAAQ;CAAM,CAAC;CACjD,EAAE,IAAI,EACJ,UAAU,EAER,KAAK,OAAwB;EAE3B,OAAO,WADM,OAAO,UAAU,WAAW,QAAU,MAA4B,QAAQ,EACjE;CACxB,EACF,EACF,CAAC;CACD,OAAO;AACT;;;;;;AAgBA,SAAS,eAAe,QAAyB;CAC/C,KAAK,MAAM,KAAK,QAAQ;EACtB,KAAK,EAAE,SAAS,UAAU,EAAE,SAAS,YAAY,OAAO,EAAE,SAAS,UAC7D;OAAA,eAAe,EAAE,MAAM,EAAE,SAAS,OAAO,GAAG,EAAE,OAAO;EAAA;EAE3D,IAAI,EAAE,QAAQ,eAAe,EAAE,MAAM;EACrC,IAAI,EAAE,OAAO,eAAe,EAAE,KAAK;EACnC,IAAI,EAAE,QAAa;QAAA,MAAM,QAAQ,EAAE,QAAQ,IAAI,KAAK,QAAQ,eAAe,KAAK,MAAM;EAAA;EACtF,IAAI,EAAE,MAAW;QAAA,MAAM,OAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,KAAK,IAAI,KAAK,QAAQ,eAAe,KAAK,MAAM;EAAA;CAC3G;AACF;;AAGA,SAAS,cAAc,MAAc,MAAsB;CACzD,OAAO,KAAK,QAAQ,2BAA2B,2BAA2B,KAAK,EAAE;AACnF;;;;;AAMA,SAAgB,mBAAmB,QAAwB;CACzD,MAAM,IAAI,WAAW;CACrB,IAAI;CACJ,IAAI;EACF,SAAS,EAAE,MAAM,MAAM;CACzB,QAAQ;EAEN,OAAO,QAAQ,WAAW,MAAM,EAAE;CACpC;CACA,eAAe,MAAmB;CAClC,IAAI,OAAO;CACX,IAAI,MAAM;CACV,KAAK,MAAM,OAAO,QAAQ;EACxB,IAAI;EACJ,IAAI;GACF,OAAO,EAAE,OAAO,CAAC,GAAG,CAAmC;EACzD,QAAQ;GACN,OAAO;EACT;EACA,IAAI,KAAK,KAAK,GAAG,OAAO,cAAc,MAAM,IAAI;EAChD,QAAS,IAAI,KAAK,MAAM,KAAK,CAAC,EAAE,UAAU;CAC5C;CACA,OAAO,OAAO,QAAQ,WAAW,MAAM,EAAE;AAC3C;;;;;AAMA,SAAgB,eAAe,QAAgB,QAAQ,QAAgB;CACrE,OAAO,qBAAqB,mBAAmB,MAAM,GAAG,KAAK;AAC/D;AAEA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDnB,SAAS,qBAAqB,MAAc,OAAe,aAAa,IAAY;CAClF,OAAO;;;;;SAKA,WAAW,KAAK,EAAE;;EAEzB,aAAa,WAAW;;;;;EAKxB,KAAK;;;;;AAKP;;;;;;;;;;;;;;;;;;;;;;;;;ACtKA,SAAS,YAAoB;CAC3B,IAAI;EACF,IAAI,QAAQ,MAAM,OAAO,OAAO;EAChC,OAAO,aAAa,GAAG,MAAM;CAC/B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,YAAoB;CAC3B,MAAM,MAAM,QAAQ,IAAI,qBAAqB,KAAK,KAAK,QAAQ,GAAG,SAAS;CAC3E,OAAO,KAAK,KAAK,KAAK,wBAAwB;AAChD;AAEA,SAAS,WAAW,SAA2B;CAC7C,IAAI;EACF,OAAO,kBAAkB,OAAkD;CAC7E,QAAQ;EACN,OAAO;CACT;AACF;;AAGA,SAAgB,qBAAqB,KAA8B;CACjE,IAAI;EAEF,MAAM,KADM,KAAK,MAAM,GACV,CAAC,CAAC,cAAc,CAAC;EAG9B,OAAO;GAAE,cAFY,OAAO,GAAG,iBAAiB,YAAY,GAAG,aAAa,KAAK,IAAI,GAAG,eAAe,KAAA;GAEhF,cADF,OAAO,GAAG,SAAS,YAAY,GAAG,KAAK,KAAK,IAAI,GAAG,OAAO,KAAA;EAC3C;CACtC,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,YAAuC;CAC9C,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,aAAa,UAAU,GAAG,MAAM,CAAC;EAC3D,IAAI,CAAC,OAAO,WAAW,CAAC,OAAO,SAAS,CAAC,OAAO,WAAW,OAAO,KAAA;EAClE,OAAO;GACL,SAAS,OAAO;GAChB,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,aAAa,OAAO,gBAAgB;EACtC;CACF,QAAQ;EACN;CACF;AACF;;;;;;AAOA,SAAS,oBAAoB,GAAwF;CACnH,IAAI,EAAE,cACJ,IAAI;EACF,MAAM,KAAK,aAAa,EAAE,cAAc,MAAM;EAC9C,IAAI,GAAG,KAAK,GAAG,OAAO;GAAE,UAAU;GAAI,OAAO,KAAK,SAAS,EAAE,cAAc,KAAK,QAAQ,EAAE,YAAY,CAAC;GAAG,UAAU,EAAE;EAAa;CACrI,QAAQ,CAER;CAEF,IAAI,EAAE,cAAc,OAAO;EAAE,UAAU,EAAE;EAAc,OAAO;CAAO;AAEvE;;;;;;AAOA,SAAS,cAAc,MAAc,UAAkD;CACrF,IAAI;CACJ,IAAI,UAGF,SAAS,GADI,SAAS,QAAQ,qBAAqB,EACpC,EAAE;MACZ;EACL,MAAM,MAAM,KAAK,KAAK,QAAQ,IAAI,qBAAqB,KAAK,KAAK,QAAQ,GAAG,SAAS,GAAG,OAAO;EAC/F,SAAS,KAAK,KAAK,KAAK,gBAAgB,QAAQ,IAAI,MAAM;CAC5D;CACA,IAAI;EACF,cAAc,QAAQ,MAAM,MAAM;EAClC,IAAI;GACF,OAAO,aAAa,OAAO,MAAM;EACnC,QAAQ;GACN,OAAO;EACT;CACF,QAAQ;EACN;CACF;AACF;AAEA,MAAa,uBAAuB,cAAc;CAChD,MAAM;EAAE,MAAM;EAA0B,aAAa;CAAiD;CACtG,MAAM,MAAM;EACV,IAAI;GACF,MAAM,MAAM,UAAU;GACtB,IAAI;GACJ,IAAI;IACF,UAAU,KAAK,MAAM,GAAG;GAC1B,QAAQ;IACN,UAAU,KAAA;GACZ;GACA,IAAI,WAAW,OAAO,GAAG;GACzB,MAAM,QAAQ,UAAU;GACxB,IAAI,CAAC,OAAO;GACZ,MAAM,OAAO,oBAAoB,qBAAqB,GAAG,CAAC;GAC1D,IAAI,CAAC,MAAM;GACX,MAAM,WAAW,cAAc,eAAe,KAAK,UAAU,KAAK,KAAK,GAAG,KAAK,QAAQ;GACvF,IAAI,CAAC,UAAU;GAEf,MAAM,IADa,eAAe,KACvB,CAAC,CAAC,KAAK,QAAQ;EAC5B,QAAQ,CAER;CACF;AACF,CAAC"}
|
package/dist/{internal-fast-dispatch-guard-CPlCrTlU.js → internal-fast-dispatch-guard-CYOWbxjX.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as internalFastDispatchGuard } from "./internal-fast-dispatch-guard-
|
|
1
|
+
import { n as internalFastDispatchGuard } from "./internal-fast-dispatch-guard-D2HcfXZv.js";
|
|
2
2
|
export { internalFastDispatchGuard };
|