frizz 0.7.8 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/claude-agent-broker.js +7 -4
- package/dist/dev-child.js +225 -214
- package/dist/frizz.js +92 -7
- package/package.json +1 -1
- package/runtime/cc-worker/.claude-plugin/plugin.json +1 -1
- package/runtime/cc-worker/DECISIONS.md +29 -1
- package/runtime/cc-worker/agents/high.md +7 -0
- package/runtime/cc-worker/agents/low.md +7 -0
- package/runtime/cc-worker/agents/max.md +7 -0
- package/runtime/cc-worker/agents/medium.md +7 -0
- package/runtime/cc-worker/agents/xhigh.md +7 -0
- package/runtime/cc-worker/hooks/agent-dispatch.mjs +7 -6
- package/runtime/cc-worker/hooks/hooks.json +0 -2
- package/runtime/cc-worker/hooks/scratchpad.mjs +5 -3
- package/runtime/cc-worker/hooks/session-seed.mjs +17 -17
- package/runtime/cc-worker/skills/gh/SKILL.md +5 -19
- package/web-dist/assets/{TerminalPane-ubcEP7X3.js → TerminalPane-BIBHC61j.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-0brfnieb.js → abnfDiagram-VRR7QNED-CcFQGFPf.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-BZEZt7jZ.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-Dji-XBdF.js → architectureDiagram-ZJ3FMSHR-DErIQOIs.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-BQMyz3Q9.js → blockDiagram-677ZJIJ3-CpsUqur1.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-BMNws0Oi.js → c4Diagram-LMCZKHZV-D2dHmCEJ.js} +1 -1
- package/web-dist/assets/channel-DdFRPviT.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-CVv1ae7n.js → chunk-32BRIVSS-aOCEfxRW.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-BYhPlKCT.js → chunk-52WLFC77-2iw4nJPC.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-Cn4HhNwb.js → chunk-C7G6YPKG-BPD3iHVE.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-P3ZYFC1W.js → chunk-EX3LRPZG-DrefHift.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-Ba3NpEQa.js → chunk-FWX5IMBZ-By940EHT.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-BCWyMhwJ.js → chunk-HOUHSVGY-B1Cqvz7e.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-DWAAqHL7.js → chunk-ICXQ74PX-1LkVpWuI.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-pc5VJ4Nq.js → chunk-MOJQB5TN-Ip1cy64r.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-DUxmbiuX.js → chunk-OGEWGWER-CNjVyu8F.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-DRdZWzxX.js → chunk-PUDLZKDR-9HZR6DAU.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-Bafzu7s-.js → chunk-Q4XR5HBZ-vtWwOCuQ.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-Bj0A8ftW.js → chunk-V7JOEXUC-DC6YaHG0.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-DBgVQKIO.js → chunk-VAUOI2AC-CP-xe7SD.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-DU-1KtuM.js → chunk-VR4S4FIN-wbxDFptH.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-DzVb3-Rj.js → chunk-WYO6CB5R-dibXmwpK.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-BPKQvduj.js → chunk-ZGVPDNZ5-_y_itJHG.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-Bf3duLb8.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-Bf3duLb8.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-lo8PqVCk.js → cynefin-VYW2F7L2-D1RYokZP.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-BtQLaDV0.js → cynefinDiagram-TSTJHNR4-qofqoy3T.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-BJ2-f-A0.js → dagre-VKFMJZFB-CgHLoGFk.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-CLM-8r74.js → diagram-FQU43EPY-JEAs4LOb.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-CfuoJGpN.js → diagram-G47NLZAW--tLd4Lf7.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-DfxxRwH8.js → diagram-NH7WQ7WH-DPbw9CJU.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-D7knxZee.js → diagram-OA4YK3LP-CDrb7nWs.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-C2WfMXWl.js → diagram-WEI45ONY-DJswZe3f.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-DRSZ24tF.js → ebnfDiagram-CCIWWBDH-BP8-PZMF.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-DXe0OrbY.js → erDiagram-Q63AITRT-BQXuebf5.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-DOLxRQQ5.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-DoK1yb0H.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-wGqOgjvs.js → ganttDiagram-NO4QXBWP-DotMb935.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-BygokG6y.js → gitGraph-TEB2WS4Q-B1vbYyKQ.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-CV1933_M.js → gitGraphDiagram-IHSO6WYX-BjDXKk4m.js} +1 -1
- package/web-dist/assets/{index-DB1d3eMJ.js → index-Cs0TDGMu.js} +124 -124
- package/web-dist/assets/{info-DKCQHKI2-DLavbzui.js → info-DKCQHKI2-xLTLqQju.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-Biouxd9G.js → infoDiagram-FWYZ7A6U-BFfYUsrC.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-DJxwwS3R.js → ishikawaDiagram-FXEZZL3T-45a7VMwm.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-Clx_WkdW.js → journeyDiagram-5HDEW3XC-CEBUpu59.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-Bf7bX_96.js → kanban-definition-HUTT4EX6-RwKtDFzG.js} +1 -1
- package/web-dist/assets/{line-CV2v49IN.js → line-DStcMIry.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-BPsFhEi6.js → mermaid-parser.core-B0ekgQMA.js} +3 -3
- package/web-dist/assets/{mermaid.core-0EWDNL_R.js → mermaid.core-w1hcQaPy.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-C1y4yy3Z.js → mindmap-definition-LN4V7U3C-D_n38Imb.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-CpcpxruB.js → packet-7NZHBO7P-CstGeBOX.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-CVlVP4cH.js → pegDiagram-2B236MQR-DvowVyTO.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-BcVPOhTZ.js → pie-RZYD4A2V-BOP2j_HH.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-DZv4Tfae.js → pieDiagram-ENE6RG2P-CKRqu_2f.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-DOzS_U_a.js → quadrantDiagram-ABIIQ3AL-zSArSS8R.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-8YADxkdT.js → radar-I7S5WNFK-BqRdNIBw.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-DzndPrRy.js → railroad-3IZDKUUU-BaKcl_LU.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-itqDLg1p.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-ze7rLVCi.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-DKsYkEuG.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-CPJAH-r7.js → railroadDiagram-RFXS5EU6-BrXTQge9.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-BVFJZfwl.js → requirementDiagram-TGXJPOKE-DBBNi_SS.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-CUhvFPmE.js → sankeyDiagram-HTMAVEWB-BwFi7xFy.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-Cy9CGhNq.js → sequenceDiagram-DBY2YBRQ-CeivqMeT.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-CqOnmPLp.js → stateDiagram-2N3HPSRC-C6NZsnFm.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-B3YRnI4W.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-c_zBqkb9.js → swimlanes-5IMT3BWC-C0MubXTG.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-CXva4Ic9.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-y_QM62SK.js → timeline-definition-FHXFAJF6-CtxwSvFu.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-T3y_1KXV.js → treeView-QDETBFTQ-CXcwSjey.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-CzvqucqY.js → treemap-6X3UGDF4-Uspgr-d1.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-6-HNOpN0.js → vennDiagram-L72KCM5P-tZamQQAQ.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-BrsaqsLL.js → wardley-OPB4EBWU-0_79c19P.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-Cr_rCzwd.js → wardleyDiagram-EHGQE667-uYmUsP66.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-BnX6ccx4.js → xychartDiagram-FW5EYKEG-BsOU7Wf7.js} +1 -1
- package/web-dist/index.html +1 -1
- package/runtime/cc-worker/agents/fable-high.md +0 -8
- package/runtime/cc-worker/agents/fable-low.md +0 -8
- package/runtime/cc-worker/agents/fable-max.md +0 -8
- package/runtime/cc-worker/agents/fable-medium.md +0 -8
- package/runtime/cc-worker/agents/fable-xhigh.md +0 -8
- package/runtime/cc-worker/agents/haiku.md +0 -7
- package/runtime/cc-worker/agents/opus-high.md +0 -8
- package/runtime/cc-worker/agents/opus-low.md +0 -8
- package/runtime/cc-worker/agents/opus-max.md +0 -8
- package/runtime/cc-worker/agents/opus-medium.md +0 -8
- package/runtime/cc-worker/agents/opus-xhigh.md +0 -8
- package/runtime/cc-worker/agents/sonnet-high.md +0 -8
- package/runtime/cc-worker/agents/sonnet-low.md +0 -8
- package/runtime/cc-worker/agents/sonnet-max.md +0 -8
- package/runtime/cc-worker/agents/sonnet-medium.md +0 -8
- package/runtime/cc-worker/agents/sonnet-xhigh.md +0 -8
- package/runtime/cc-worker/bin/browser-mcp-tools.json +0 -1192
- package/runtime/cc-worker/bin/browser-mcp.mjs +0 -730
- package/runtime/cc-worker/hooks/precompact-instructions.mjs +0 -133
- package/runtime/cc-worker/skills/waits/SKILL.md +0 -84
- package/web-dist/assets/architecture-TIHT7OUA-DksosNDW.js +0 -1
- package/web-dist/assets/channel-DqoPvfQz.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-DwUs74RB.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-DwUs74RB.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-CUIjQ7kE.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-Dka-3F3n.js +0 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-CCnWa6K9.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-jtVdzv7e.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-B8D6TyEe.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-DWKW-4qu.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-DZKoB7ae.js +0 -8
package/dist/dev-child.js
CHANGED
|
@@ -12938,6 +12938,13 @@ function retiredAwaitingKindsIn(body) {
|
|
|
12938
12938
|
}
|
|
12939
12939
|
return found;
|
|
12940
12940
|
}
|
|
12941
|
+
function trimAwaitingTitle(raw2) {
|
|
12942
|
+
const flat = raw2.replace(/\s+/g, " ").trim();
|
|
12943
|
+
if (flat.length <= AWAITING_TITLE_MAX) return flat;
|
|
12944
|
+
const cut = flat.slice(0, AWAITING_TITLE_MAX);
|
|
12945
|
+
const space = cut.lastIndexOf(" ");
|
|
12946
|
+
return `${(space > AWAITING_TITLE_MAX / 2 ? cut.slice(0, space) : cut).replace(/[.,;:–—-]$/, "").trimEnd()}\u2026`;
|
|
12947
|
+
}
|
|
12941
12948
|
function splitAwaitingFrontmatter(raw2) {
|
|
12942
12949
|
const lines = raw2.split("\n").map((l) => l.replace(/\r$/, ""));
|
|
12943
12950
|
const delimiter2 = lines.findIndex((l) => /^\s*---+\s*$/.test(l));
|
|
@@ -12981,6 +12988,8 @@ function parseAwaitingYaml(text) {
|
|
|
12981
12988
|
for (const entry of Array.isArray(raw2) ? raw2 : [raw2]) push(itemKind, entry);
|
|
12982
12989
|
} else if (key === "for") {
|
|
12983
12990
|
push("for", raw2);
|
|
12991
|
+
} else if (key === "title") {
|
|
12992
|
+
if (typeof raw2 === "string" || typeof raw2 === "number") push("title", trimAwaitingTitle(String(raw2)));
|
|
12984
12993
|
}
|
|
12985
12994
|
}
|
|
12986
12995
|
return { ok: true, hints };
|
|
@@ -13263,7 +13272,7 @@ function parseGithubWakeSteer(text) {
|
|
|
13263
13272
|
function frizzRoute(path) {
|
|
13264
13273
|
return `${FRIZZ_ROUTE_PREFIX}${path.startsWith("/") ? path : `/${path}`}`;
|
|
13265
13274
|
}
|
|
13266
|
-
var import_yaml, ATTACHMENT_IMAGE_EXTENSIONS, ATTACHMENT_DOC_EXTENSIONS, ATTACHMENT_EXTENSIONS, ATTACHMENT_MAX_BASE64_CHARS, ATTACHMENT_MAX_BYTES, ATTACHMENT_EXT_SET, ATTACHMENT_ACCEPT, FrizzStatus, BlockMechanism, RuntimeState, Backend, CodexModel, ThreadProfileOption, ThreadAgent, SubAgentView, BgShellView, CompletionHoldOp, CompletionHold, AskOption, AskQuestion, PendingAsk, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, RETIRED_AWAITING_REPLACEMENT, AWAITING_KEY_RE, AWAITING_YAML_KEYS, AWAITING_SEQUENCE_KEYS, AWAITING_HINT_MAX, AWAITING_HINT_VALUE_MAX, AWAITING_ITEM_KINDS, AWAITING_DURATION_RE, DURATION_UNIT_MS, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, INTERRUPT_MARKERS, ALLDONE_SENTINEL, OPT_OUT_NOTE, OVER_QUESTION_NOTE, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TIMER_MAX_ARMED, TimerPromptText, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, PARK_CORRECTION_NAMES_LEAD, PARK_CORRECTION_RETIRED_LEAD, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PR_WATCH_MAX_ARMED, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ThreadView, BoardErrorItem, BoardSnapshot, QuotaWindow, ProviderQuota, QuotaSnapshot, ProviderAuth, AccountEmails, AuthSnapshot, AccountLogoutInput, AccountLogoutResult, AccountLoginStartInput, AccountLoginStartResult, AccountLoginStatusInput, AccountLoginStatusResult, PermissionMode, LocalFileOpener, Settings, DispatchProviderPreferences, DispatchPreferences, DispatchProfileSnapshot, SetDispatchPreferenceInput, DispatchInput, ADOPT_THREAD_MESSAGE_MAX_CHARS, AdoptThreadInput, AdoptThreadResult, AdoptSessionInput, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GITHUB_DISPATCH_UI_BOUNDARY, HUMAN_GAP_FLOOR_MS, HUMAN_GAP_NOTE_TAIL, WAKE_DELIVERY_TOKEN_TAIL, WAKE_DELIVERY_TOKEN_LINE, NOISE_PREFIXES, AGENT_MESSAGE_WRAPPER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REVIEW_LEAD, WAKE_BACKLOG_TAIL, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, WAKE_ITEM, WAKE_MORE, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketClientMsg, ProjectCard, PROJECT_ICON_EXTENSIONS, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT, threadIdentityName;
|
|
13275
|
+
var import_yaml, ATTACHMENT_IMAGE_EXTENSIONS, ATTACHMENT_DOC_EXTENSIONS, ATTACHMENT_EXTENSIONS, ATTACHMENT_MAX_BASE64_CHARS, ATTACHMENT_MAX_BYTES, ATTACHMENT_EXT_SET, ATTACHMENT_ACCEPT, FrizzStatus, BlockMechanism, RuntimeState, Backend, CodexModel, ThreadProfileOption, ThreadAgent, SubAgentView, BgShellView, CompletionHoldOp, CompletionHold, AskOption, AskQuestion, PendingAsk, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, RETIRED_AWAITING_REPLACEMENT, AWAITING_KEY_RE, AWAITING_YAML_KEYS, AWAITING_SEQUENCE_KEYS, AWAITING_HINT_MAX, AWAITING_HINT_VALUE_MAX, AWAITING_TITLE_MAX, AWAITING_ITEM_KINDS, AWAITING_DURATION_RE, DURATION_UNIT_MS, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, INTERRUPT_MARKERS, ALLDONE_SENTINEL, OPT_OUT_NOTE, OVER_QUESTION_NOTE, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TIMER_MAX_ARMED, TimerPromptText, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, PARK_CORRECTION_NAMES_LEAD, PARK_CORRECTION_RETIRED_LEAD, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PR_WATCH_MAX_ARMED, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ThreadView, BoardErrorItem, BoardSnapshot, QuotaWindow, ProviderQuota, QuotaSnapshot, ProviderAuth, AccountEmails, AuthSnapshot, AccountLogoutInput, AccountLogoutResult, AccountLoginStartInput, AccountLoginStartResult, AccountLoginStatusInput, AccountLoginStatusResult, PermissionMode, LocalFileOpener, Settings, DispatchProviderPreferences, DispatchPreferences, DispatchProfileSnapshot, SetDispatchPreferenceInput, DispatchInput, ADOPT_THREAD_MESSAGE_MAX_CHARS, AdoptThreadInput, AdoptThreadResult, AdoptSessionInput, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GITHUB_DISPATCH_UI_BOUNDARY, HUMAN_GAP_FLOOR_MS, HUMAN_GAP_NOTE_TAIL, WAKE_DELIVERY_TOKEN_TAIL, WAKE_DELIVERY_TOKEN_LINE, NOISE_PREFIXES, AGENT_MESSAGE_WRAPPER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REVIEW_LEAD, WAKE_BACKLOG_TAIL, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, WAKE_ITEM, WAKE_MORE, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketClientMsg, ProjectCard, PROJECT_ICON_EXTENSIONS, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT, threadIdentityName;
|
|
13267
13276
|
var init_src = __esm({
|
|
13268
13277
|
"packages/shared/src/index.ts"() {
|
|
13269
13278
|
"use strict";
|
|
@@ -13519,7 +13528,7 @@ var init_src = __esm({
|
|
|
13519
13528
|
questions: external_exports.array(AskQuestion)
|
|
13520
13529
|
});
|
|
13521
13530
|
AwaitingHint = external_exports.object({
|
|
13522
|
-
kind: external_exports.enum(["shell", "agent", "timer", "pr", "for"]),
|
|
13531
|
+
kind: external_exports.enum(["shell", "agent", "timer", "pr", "for", "title"]),
|
|
13523
13532
|
value: external_exports.string()
|
|
13524
13533
|
});
|
|
13525
13534
|
RETIRED_AWAITING_KINDS = ["watch", "pr-watch", "human", "ci", "session", "shell", "agent", "timer", "pr", "reason"];
|
|
@@ -13541,7 +13550,7 @@ var init_src = __esm({
|
|
|
13541
13550
|
"reason": "put it below the `---` as ordinary Markdown \u2014 the frontmatter is YAML now and takes no prose"
|
|
13542
13551
|
};
|
|
13543
13552
|
AWAITING_KEY_RE = /^([a-z][a-z-]*):\s*(\S.*)?$/i;
|
|
13544
|
-
AWAITING_YAML_KEYS = /* @__PURE__ */ new Set(["shells", "agents", "timers", "prs", "for"]);
|
|
13553
|
+
AWAITING_YAML_KEYS = /* @__PURE__ */ new Set(["shells", "agents", "timers", "prs", "for", "title"]);
|
|
13545
13554
|
AWAITING_SEQUENCE_KEYS = {
|
|
13546
13555
|
shells: "shell",
|
|
13547
13556
|
agents: "agent",
|
|
@@ -13550,6 +13559,7 @@ var init_src = __esm({
|
|
|
13550
13559
|
};
|
|
13551
13560
|
AWAITING_HINT_MAX = 8;
|
|
13552
13561
|
AWAITING_HINT_VALUE_MAX = 200;
|
|
13562
|
+
AWAITING_TITLE_MAX = 40;
|
|
13553
13563
|
AWAITING_ITEM_KINDS = ["shell", "agent", "timer", "pr"];
|
|
13554
13564
|
AWAITING_DURATION_RE = /^(\d{1,5})(s|m|h|d)$/;
|
|
13555
13565
|
DURATION_UNIT_MS = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 };
|
|
@@ -14133,6 +14143,14 @@ var init_src = __esm({
|
|
|
14133
14143
|
// Default action for a vetted non-image local path in agent markdown. Image clicks always use the
|
|
14134
14144
|
// OS default viewer so screenshots retain their expected behavior.
|
|
14135
14145
|
localFileOpener: LocalFileOpener.optional(),
|
|
14146
|
+
// The token count at which a NEW Claude worker auto-compacts its conversation. Frizz requests the
|
|
14147
|
+
// 1M context window on every dispatch (resolveClaudeLaunchModel), so without this a worker grows
|
|
14148
|
+
// toward 1M before it ever compacts — and every turn past 200K re-sends up to 5x the conversation a
|
|
14149
|
+
// 200K TUI session would, which is the single largest reason a Frizz thread spends quota faster than
|
|
14150
|
+
// the TUI (measured 2026-08-26). Reaches the worker as CLAUDE_CODE_AUTO_COMPACT_WINDOW, which Claude
|
|
14151
|
+
// Code caps to the model's real window. Optional so an old blob parses; defaultSettings pins 500_000
|
|
14152
|
+
// (maintainer 2026-08-26: "a default compaction window of 500k by default").
|
|
14153
|
+
autoCompactWindow: external_exports.number().int().positive().optional(),
|
|
14136
14154
|
// The GitHub batch-dispatch prompt template (the picker's per-item worker prompt). Optional: when
|
|
14137
14155
|
// unset OR blank the server falls back to its exported DEFAULT_GITHUB_PROMPT. Substitution tokens
|
|
14138
14156
|
// the server fills: {repo} {n} {title} {url} {labels} {body}. The leading `THREAD: <slug>` tag is
|
|
@@ -19652,6 +19670,9 @@ var init_settings = __esm({
|
|
|
19652
19670
|
notifications: true,
|
|
19653
19671
|
font: "sans",
|
|
19654
19672
|
localFileOpener: "system",
|
|
19673
|
+
// 500K tokens: half the 1M window every Claude worker is dispatched with. See the schema for why a
|
|
19674
|
+
// worker left to compact at 1M is the biggest single reason a Frizz thread out-spends the TUI.
|
|
19675
|
+
autoCompactWindow: 5e5,
|
|
19655
19676
|
// Hidden until asked for — see the schema for why.
|
|
19656
19677
|
projectRail: false
|
|
19657
19678
|
});
|
|
@@ -28586,32 +28607,7 @@ var init_wrapper = __esm({
|
|
|
28586
28607
|
}
|
|
28587
28608
|
});
|
|
28588
28609
|
|
|
28589
|
-
// packages/server/src/worker-plugin-dir.ts
|
|
28590
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
28591
|
-
import { dirname as dirname9, join as join20 } from "node:path";
|
|
28592
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
28593
|
-
function resolveWorkerPluginDir(moduleUrl = import.meta.url, env = process.env) {
|
|
28594
|
-
const override = env.FRIZZ_WORKER_PLUGIN_DIR;
|
|
28595
|
-
if (override && existsSync6(join20(override, ".claude-plugin", "plugin.json")))
|
|
28596
|
-
return override;
|
|
28597
|
-
let current = dirname9(fileURLToPath2(moduleUrl));
|
|
28598
|
-
for (; ; ) {
|
|
28599
|
-
const candidate = join20(current, "cc-worker");
|
|
28600
|
-
if (existsSync6(join20(candidate, ".claude-plugin", "plugin.json"))) return candidate;
|
|
28601
|
-
const parent = dirname9(current);
|
|
28602
|
-
if (parent === current) return void 0;
|
|
28603
|
-
current = parent;
|
|
28604
|
-
}
|
|
28605
|
-
}
|
|
28606
|
-
var init_worker_plugin_dir = __esm({
|
|
28607
|
-
"packages/server/src/worker-plugin-dir.ts"() {
|
|
28608
|
-
"use strict";
|
|
28609
|
-
}
|
|
28610
|
-
});
|
|
28611
|
-
|
|
28612
28610
|
// packages/server/src/backend/types.ts
|
|
28613
|
-
import { existsSync as existsSync7 } from "node:fs";
|
|
28614
|
-
import { join as join21 } from "node:path";
|
|
28615
28611
|
function frizzMcpEnv(mcp) {
|
|
28616
28612
|
return {
|
|
28617
28613
|
FRIZZ_STATE_DIR: mcp.stateDir,
|
|
@@ -28620,24 +28616,6 @@ function frizzMcpEnv(mcp) {
|
|
|
28620
28616
|
...mcp.slug ? { FRIZZ_THREAD_SLUG: mcp.slug } : {}
|
|
28621
28617
|
};
|
|
28622
28618
|
}
|
|
28623
|
-
function chromeDevtoolsMcpSpec(scriptPath, nodeBin) {
|
|
28624
|
-
const args = [...CHROME_DEVTOOLS_MCP.args];
|
|
28625
|
-
if (!scriptPath) return { command: "npx", args: ["-y", `${CHROME_DEVTOOLS_MCP.package}@${CHROME_DEVTOOLS_MCP.version}`, ...args] };
|
|
28626
|
-
return {
|
|
28627
|
-
command: nodeBin,
|
|
28628
|
-
args: [scriptPath, ...args],
|
|
28629
|
-
env: { FRIZZ_BROWSER_MCP_PACKAGE: `${CHROME_DEVTOOLS_MCP.package}@${CHROME_DEVTOOLS_MCP.version}` }
|
|
28630
|
-
};
|
|
28631
|
-
}
|
|
28632
|
-
function chromeDevtoolsMcpMount() {
|
|
28633
|
-
return chromeDevtoolsMcpSpec(resolveBrowserMcpScript(), process.execPath);
|
|
28634
|
-
}
|
|
28635
|
-
function resolveBrowserMcpScript(moduleUrl = import.meta.url, env = process.env) {
|
|
28636
|
-
const pluginDir = resolveWorkerPluginDir(moduleUrl, env);
|
|
28637
|
-
if (!pluginDir) return void 0;
|
|
28638
|
-
const scriptPath = join21(pluginDir, "bin", CHROME_DEVTOOLS_MCP.script);
|
|
28639
|
-
return existsSync7(scriptPath) ? scriptPath : void 0;
|
|
28640
|
-
}
|
|
28641
28619
|
function workerCap(name, lifted, env) {
|
|
28642
28620
|
const override = env[name];
|
|
28643
28621
|
if (override !== void 0 && /^[1-9][0-9]*$/.test(override)) return override;
|
|
@@ -28651,29 +28629,20 @@ function claudeWorkerEnv(env = process.env) {
|
|
|
28651
28629
|
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS: workerCap("CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS", WORKER_MAX_CONCURRENT_SUBAGENTS, env)
|
|
28652
28630
|
};
|
|
28653
28631
|
}
|
|
28654
|
-
|
|
28632
|
+
function claudeCompactionEnv(settings) {
|
|
28633
|
+
const window = settings?.autoCompactWindow;
|
|
28634
|
+
if (window === void 0 || !Number.isInteger(window) || window <= 0) return {};
|
|
28635
|
+
return { CLAUDE_CODE_AUTO_COMPACT_WINDOW: String(window) };
|
|
28636
|
+
}
|
|
28637
|
+
var FRIZZ_MCP, WORKER_MAX_WEB_SEARCHES, WORKER_MAX_SUBAGENTS, WORKER_MAX_CONCURRENT_SUBAGENTS, CLAUDE_WORKER_ENV, WORKER_DISALLOWED_TOOLS;
|
|
28655
28638
|
var init_types2 = __esm({
|
|
28656
28639
|
"packages/server/src/backend/types.ts"() {
|
|
28657
28640
|
"use strict";
|
|
28658
|
-
init_worker_plugin_dir();
|
|
28659
28641
|
FRIZZ_MCP = {
|
|
28660
28642
|
name: "frizz",
|
|
28661
28643
|
script: "frizz-mcp.mjs"
|
|
28662
28644
|
// resolved under <worker plugin dir>/bin/
|
|
28663
28645
|
};
|
|
28664
|
-
CHROME_DEVTOOLS_MCP = {
|
|
28665
|
-
name: "chrome-devtools",
|
|
28666
|
-
// Resolved under <worker plugin dir>/bin/, exactly like FRIZZ_MCP.script.
|
|
28667
|
-
script: "browser-mcp.mjs",
|
|
28668
|
-
package: "chrome-devtools-mcp",
|
|
28669
|
-
version: "1.7.0",
|
|
28670
|
-
args: [
|
|
28671
|
-
"--experimentalPageIdRouting",
|
|
28672
|
-
"--headless",
|
|
28673
|
-
"--isolated",
|
|
28674
|
-
"--no-usage-statistics"
|
|
28675
|
-
]
|
|
28676
|
-
};
|
|
28677
28646
|
WORKER_MAX_WEB_SEARCHES = 1e4;
|
|
28678
28647
|
WORKER_MAX_SUBAGENTS = 1e4;
|
|
28679
28648
|
WORKER_MAX_CONCURRENT_SUBAGENTS = 100;
|
|
@@ -28703,12 +28672,8 @@ function serverTable(command, args, env) {
|
|
|
28703
28672
|
}
|
|
28704
28673
|
return inlineTable(entries);
|
|
28705
28674
|
}
|
|
28706
|
-
function codexMcpConfigArgs(frizzMcp, nodeBin = process.execPath
|
|
28707
|
-
const
|
|
28708
|
-
const args = [
|
|
28709
|
-
"-c",
|
|
28710
|
-
`mcp_servers.${CHROME_DEVTOOLS_MCP.name}=${serverTable(chrome.command, chrome.args, chrome.env)}`
|
|
28711
|
-
];
|
|
28675
|
+
function codexMcpConfigArgs(frizzMcp, nodeBin = process.execPath) {
|
|
28676
|
+
const args = [];
|
|
28712
28677
|
if (frizzMcp) {
|
|
28713
28678
|
args.push(
|
|
28714
28679
|
"-c",
|
|
@@ -28733,15 +28698,15 @@ import { spawn as spawn2 } from "node:child_process";
|
|
|
28733
28698
|
import { connect } from "node:net";
|
|
28734
28699
|
import { Agent as HttpAgent } from "node:http";
|
|
28735
28700
|
import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
|
|
28736
|
-
import { existsSync as
|
|
28737
|
-
import { join as
|
|
28701
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync11, readFileSync as readFileSync14, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28702
|
+
import { join as join20 } from "node:path";
|
|
28738
28703
|
import { PassThrough, Writable } from "node:stream";
|
|
28739
28704
|
import { StringDecoder } from "node:string_decoder";
|
|
28740
28705
|
function nativeDir(stateDir) {
|
|
28741
|
-
return
|
|
28706
|
+
return join20(stateDir, "codex-app-server-native");
|
|
28742
28707
|
}
|
|
28743
28708
|
function nativeRecordPath(stateDir, projectId) {
|
|
28744
|
-
return
|
|
28709
|
+
return join20(nativeDir(stateDir), `${projectId}.json`);
|
|
28745
28710
|
}
|
|
28746
28711
|
function nativeListenSocketPath(stateDir, projectId) {
|
|
28747
28712
|
const key = createHash7("sha256").update(stateDir).update("\0").update(projectId).digest("hex").slice(0, 16);
|
|
@@ -28773,7 +28738,7 @@ function readNativeRecord(stateDir, projectId) {
|
|
|
28773
28738
|
function liveNativeRecord(stateDir, projectId) {
|
|
28774
28739
|
const record = readNativeRecord(stateDir, projectId);
|
|
28775
28740
|
if (!record) return null;
|
|
28776
|
-
if (pidAlive2(record.listenerPid) &&
|
|
28741
|
+
if (pidAlive2(record.listenerPid) && existsSync6(record.socketPath)) return record;
|
|
28777
28742
|
try {
|
|
28778
28743
|
unlinkSync2(nativeRecordPath(stateDir, projectId));
|
|
28779
28744
|
} catch {
|
|
@@ -28915,7 +28880,7 @@ async function startListener(options) {
|
|
|
28915
28880
|
const { stateDir, projectId } = options;
|
|
28916
28881
|
mkdirSync11(nativeDir(stateDir), { recursive: true });
|
|
28917
28882
|
const socketPath = nativeListenSocketPath(stateDir, projectId);
|
|
28918
|
-
if (
|
|
28883
|
+
if (existsSync6(socketPath) && !await socketAccepting(socketPath)) {
|
|
28919
28884
|
try {
|
|
28920
28885
|
unlinkSync2(socketPath);
|
|
28921
28886
|
} catch {
|
|
@@ -28939,7 +28904,7 @@ async function startListener(options) {
|
|
|
28939
28904
|
writeFileSync9(nativeRecordPath(stateDir, projectId), JSON.stringify(record));
|
|
28940
28905
|
const deadline = Date.now() + (options.timeoutMs ?? 3e4);
|
|
28941
28906
|
for (; ; ) {
|
|
28942
|
-
if (
|
|
28907
|
+
if (existsSync6(socketPath) && await socketAccepting(socketPath)) return record;
|
|
28943
28908
|
if (!pidAlive2(record.listenerPid)) throw new Error("codex app-server listener exited before it became ready");
|
|
28944
28909
|
if (Date.now() > deadline) throw new Error("codex app-server listener did not become ready");
|
|
28945
28910
|
await new Promise((resolve10) => setTimeout(resolve10, 50));
|
|
@@ -29005,15 +28970,15 @@ var init_codex_app_server_native = __esm({
|
|
|
29005
28970
|
import { spawn as spawn3, spawnSync } from "node:child_process";
|
|
29006
28971
|
import { createConnection } from "node:net";
|
|
29007
28972
|
import { createHash as createHash8, randomUUID as randomUUID10 } from "node:crypto";
|
|
29008
|
-
import { existsSync as
|
|
29009
|
-
import { join as
|
|
28973
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync12, readFileSync as readFileSync15, unlinkSync as unlinkSync3 } from "node:fs";
|
|
28974
|
+
import { join as join21 } from "node:path";
|
|
29010
28975
|
import { PassThrough as PassThrough2, Writable as Writable2 } from "node:stream";
|
|
29011
28976
|
import { StringDecoder as StringDecoder2 } from "node:string_decoder";
|
|
29012
28977
|
function daemonDir(stateDir) {
|
|
29013
|
-
return
|
|
28978
|
+
return join21(stateDir, "codex-app-server");
|
|
29014
28979
|
}
|
|
29015
28980
|
function recordPath(stateDir, projectId) {
|
|
29016
|
-
return
|
|
28981
|
+
return join21(daemonDir(stateDir), `${projectId}.json`);
|
|
29017
28982
|
}
|
|
29018
28983
|
function codexAppServerSocketPath(stateDir, projectId) {
|
|
29019
28984
|
const key = createHash8("sha256").update(stateDir).update("\0").update(projectId).digest("hex").slice(0, 16);
|
|
@@ -29295,7 +29260,7 @@ var init_codex_app_server_host = __esm({
|
|
|
29295
29260
|
}
|
|
29296
29261
|
if (process.platform !== "win32") {
|
|
29297
29262
|
const stale = codexAppServerSocketPath(options.stateDir, options.projectId);
|
|
29298
|
-
if (
|
|
29263
|
+
if (existsSync7(stale) && !liveDaemonRecord(options.stateDir, options.projectId)) {
|
|
29299
29264
|
try {
|
|
29300
29265
|
unlinkSync3(stale);
|
|
29301
29266
|
} catch {
|
|
@@ -32241,11 +32206,11 @@ var init_codex_app_server = __esm({
|
|
|
32241
32206
|
});
|
|
32242
32207
|
|
|
32243
32208
|
// packages/server/src/backend/codex-quota.ts
|
|
32244
|
-
import { join as
|
|
32209
|
+
import { join as join22 } from "node:path";
|
|
32245
32210
|
import { readdirSync as readdirSync7, statSync as statSync10, openSync as openSync12, readSync as readSync6, fstatSync, closeSync as closeSync11 } from "node:fs";
|
|
32246
32211
|
import { spawn as spawn4 } from "node:child_process";
|
|
32247
32212
|
function sessionsDir2(codexHome) {
|
|
32248
|
-
return
|
|
32213
|
+
return join22(codexHome, "sessions");
|
|
32249
32214
|
}
|
|
32250
32215
|
function newestRollouts(dir, out, budget) {
|
|
32251
32216
|
if (budget.n <= 0) return;
|
|
@@ -32259,11 +32224,11 @@ function newestRollouts(dir, out, budget) {
|
|
|
32259
32224
|
const files = entries.filter((e) => e.isFile() && e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")).map((e) => e.name).sort(descByName2);
|
|
32260
32225
|
for (const d of dirs) {
|
|
32261
32226
|
if (budget.n <= 0) return;
|
|
32262
|
-
newestRollouts(
|
|
32227
|
+
newestRollouts(join22(dir, d), out, budget);
|
|
32263
32228
|
}
|
|
32264
32229
|
for (const f of files) {
|
|
32265
32230
|
if (budget.n <= 0) return;
|
|
32266
|
-
out.push(
|
|
32231
|
+
out.push(join22(dir, f));
|
|
32267
32232
|
budget.n--;
|
|
32268
32233
|
}
|
|
32269
32234
|
}
|
|
@@ -32463,7 +32428,7 @@ var init_codex_quota = __esm({
|
|
|
32463
32428
|
});
|
|
32464
32429
|
|
|
32465
32430
|
// packages/server/src/backend/claude-quota.ts
|
|
32466
|
-
import { join as
|
|
32431
|
+
import { join as join23 } from "node:path";
|
|
32467
32432
|
import { homedir as homedir9, platform } from "node:os";
|
|
32468
32433
|
import { createHash as createHash10 } from "node:crypto";
|
|
32469
32434
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -32471,7 +32436,7 @@ import { execFile as execFile2 } from "node:child_process";
|
|
|
32471
32436
|
import { promisify as promisify2 } from "node:util";
|
|
32472
32437
|
function claudeConfigDir() {
|
|
32473
32438
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
32474
|
-
return override && override.trim() ? override :
|
|
32439
|
+
return override && override.trim() ? override : join23(homedir9(), ".claude");
|
|
32475
32440
|
}
|
|
32476
32441
|
function tokenFromCredentialsJson(raw2) {
|
|
32477
32442
|
let doc;
|
|
@@ -32500,7 +32465,7 @@ async function readKeychainToken() {
|
|
|
32500
32465
|
}
|
|
32501
32466
|
async function readAccessToken(configDir) {
|
|
32502
32467
|
try {
|
|
32503
|
-
const fromFile = tokenFromCredentialsJson(await readFile(
|
|
32468
|
+
const fromFile = tokenFromCredentialsJson(await readFile(join23(configDir, ".credentials.json"), "utf8"));
|
|
32504
32469
|
if (fromFile) return fromFile;
|
|
32505
32470
|
} catch {
|
|
32506
32471
|
}
|
|
@@ -32569,8 +32534,8 @@ function parseClaudeUsage(body, planType) {
|
|
|
32569
32534
|
function cachePaths(cacheDir, configDir) {
|
|
32570
32535
|
const profile = createHash10("sha256").update(configDir).digest("hex").slice(0, 12);
|
|
32571
32536
|
return {
|
|
32572
|
-
data:
|
|
32573
|
-
lock:
|
|
32537
|
+
data: join23(cacheDir, `claude-${profile}.json`),
|
|
32538
|
+
lock: join23(cacheDir, `claude-${profile}.lock`)
|
|
32574
32539
|
};
|
|
32575
32540
|
}
|
|
32576
32541
|
async function readShared(path) {
|
|
@@ -32766,7 +32731,7 @@ function refreshSharedInBackground(paths, claudeBin, deps, now) {
|
|
|
32766
32731
|
async function refreshClaudeQuotaInBackground(claudeBin = "claude", deps = {}) {
|
|
32767
32732
|
const now = (deps.now ?? Date.now)();
|
|
32768
32733
|
const configDir = claudeConfigDir();
|
|
32769
|
-
const cacheDir = deps.cacheDir ??
|
|
32734
|
+
const cacheDir = deps.cacheDir ?? join23(frizzRoots().cache, "quota-cache");
|
|
32770
32735
|
try {
|
|
32771
32736
|
await mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
32772
32737
|
} catch {
|
|
@@ -32777,7 +32742,7 @@ async function refreshClaudeQuotaInBackground(claudeBin = "claude", deps = {}) {
|
|
|
32777
32742
|
async function readClaudeQuota(claudeBin = "claude", deps = {}, options = {}) {
|
|
32778
32743
|
const now = (deps.now ?? Date.now)();
|
|
32779
32744
|
const configDir = claudeConfigDir();
|
|
32780
|
-
const cacheDir = deps.cacheDir ??
|
|
32745
|
+
const cacheDir = deps.cacheDir ?? join23(frizzRoots().cache, "quota-cache");
|
|
32781
32746
|
const paths = cachePaths(cacheDir, configDir);
|
|
32782
32747
|
try {
|
|
32783
32748
|
await mkdir(cacheDir, { recursive: true, mode: 448 });
|
|
@@ -32937,7 +32902,7 @@ var init_quota = __esm({
|
|
|
32937
32902
|
// packages/server/src/frizz.ts
|
|
32938
32903
|
import { execFile as execFile3 } from "node:child_process";
|
|
32939
32904
|
import { lstatSync as lstatSync2, realpathSync as realpathSync6 } from "node:fs";
|
|
32940
|
-
import { basename as basename5, dirname as
|
|
32905
|
+
import { basename as basename5, dirname as dirname9, join as join24, resolve as resolve4 } from "node:path";
|
|
32941
32906
|
import { promisify as promisify3 } from "node:util";
|
|
32942
32907
|
function frizzScriptsDir() {
|
|
32943
32908
|
if (process.env.FRIZZ_SCRIPTS_DIR) return process.env.FRIZZ_SCRIPTS_DIR;
|
|
@@ -32946,11 +32911,11 @@ function frizzScriptsDir() {
|
|
|
32946
32911
|
function directFrizzRoot(projectDir) {
|
|
32947
32912
|
try {
|
|
32948
32913
|
const projectRoot = realpathSync6(projectDir);
|
|
32949
|
-
const path =
|
|
32914
|
+
const path = join24(projectRoot, ".frizz");
|
|
32950
32915
|
const stat2 = lstatSync2(path);
|
|
32951
32916
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) return null;
|
|
32952
32917
|
const real = realpathSync6(path);
|
|
32953
|
-
return
|
|
32918
|
+
return dirname9(real) === projectRoot && basename5(real) === ".frizz" ? real : null;
|
|
32954
32919
|
} catch {
|
|
32955
32920
|
return null;
|
|
32956
32921
|
}
|
|
@@ -32960,7 +32925,7 @@ function frizzDirExists(projectDir) {
|
|
|
32960
32925
|
}
|
|
32961
32926
|
async function readBoard(projectDir, scriptsDir = frizzScriptsDir()) {
|
|
32962
32927
|
if (!directFrizzRoot(projectDir)) throw new Error("unsafe or missing .frizz directory");
|
|
32963
|
-
const { stdout } = await execFileP("node", [
|
|
32928
|
+
const { stdout } = await execFileP("node", [join24(scriptsDir, "index.mjs"), "--json"], {
|
|
32964
32929
|
cwd: projectDir,
|
|
32965
32930
|
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
|
|
32966
32931
|
maxBuffer: 32 * 1024 * 1024
|
|
@@ -32985,7 +32950,7 @@ async function readBoard(projectDir, scriptsDir = frizzScriptsDir()) {
|
|
|
32985
32950
|
};
|
|
32986
32951
|
}
|
|
32987
32952
|
async function runThreadUpdate(projectDir, slug, args, scriptsDir = frizzScriptsDir()) {
|
|
32988
|
-
await execFileP("node", [
|
|
32953
|
+
await execFileP("node", [join24(scriptsDir, "thread-update.mjs"), slug, ...args], {
|
|
32989
32954
|
cwd: projectDir,
|
|
32990
32955
|
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir }
|
|
32991
32956
|
});
|
|
@@ -33021,7 +32986,12 @@ function readAwaitingPark(hints) {
|
|
|
33021
32986
|
return { items, forMs };
|
|
33022
32987
|
}
|
|
33023
32988
|
function unaccountedItems(items, live) {
|
|
33024
|
-
return items.filter((i) => !live[LIVE_SET[i.kind]].has(i
|
|
32989
|
+
return items.filter((i) => !live[LIVE_SET[i.kind]].has(liveKey(i)));
|
|
32990
|
+
}
|
|
32991
|
+
function liveKey(i) {
|
|
32992
|
+
if (i.kind !== "pr") return i.value;
|
|
32993
|
+
const ref = parsePrRef(i.value);
|
|
32994
|
+
return ref ? githubStatusKey(ref) : i.value;
|
|
33025
32995
|
}
|
|
33026
32996
|
function parkIsHonoured(park, live) {
|
|
33027
32997
|
if (park.items.length === 0) return false;
|
|
@@ -33060,6 +33030,29 @@ var init_awaiting = __esm({
|
|
|
33060
33030
|
}
|
|
33061
33031
|
});
|
|
33062
33032
|
|
|
33033
|
+
// packages/server/src/worker-plugin-dir.ts
|
|
33034
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
33035
|
+
import { dirname as dirname10, join as join25 } from "node:path";
|
|
33036
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
33037
|
+
function resolveWorkerPluginDir(moduleUrl = import.meta.url, env = process.env) {
|
|
33038
|
+
const override = env.FRIZZ_WORKER_PLUGIN_DIR;
|
|
33039
|
+
if (override && existsSync8(join25(override, ".claude-plugin", "plugin.json")))
|
|
33040
|
+
return override;
|
|
33041
|
+
let current = dirname10(fileURLToPath2(moduleUrl));
|
|
33042
|
+
for (; ; ) {
|
|
33043
|
+
const candidate = join25(current, "cc-worker");
|
|
33044
|
+
if (existsSync8(join25(candidate, ".claude-plugin", "plugin.json"))) return candidate;
|
|
33045
|
+
const parent = dirname10(current);
|
|
33046
|
+
if (parent === current) return void 0;
|
|
33047
|
+
current = parent;
|
|
33048
|
+
}
|
|
33049
|
+
}
|
|
33050
|
+
var init_worker_plugin_dir = __esm({
|
|
33051
|
+
"packages/server/src/worker-plugin-dir.ts"() {
|
|
33052
|
+
"use strict";
|
|
33053
|
+
}
|
|
33054
|
+
});
|
|
33055
|
+
|
|
33063
33056
|
// packages/server/src/workerPrompt.ts
|
|
33064
33057
|
function buildWorkerPrompt(kind = "claude", opts = {}) {
|
|
33065
33058
|
const lean = kind === "claude";
|
|
@@ -33264,6 +33257,7 @@ a second read for nothing, and it is the commonest thing wrong with an otherwise
|
|
|
33264
33257
|
timers: [tmr_a1b2c3d4e5f6]
|
|
33265
33258
|
prs: [acme/app#391]
|
|
33266
33259
|
for: 2h
|
|
33260
|
+
title: Three-platform CI run
|
|
33267
33261
|
---
|
|
33268
33262
|
Waiting on the three-platform run before porting the v2 drivers.
|
|
33269
33263
|
|
|
@@ -33272,9 +33266,9 @@ a second read for nothing, and it is the commonest thing wrong with an otherwise
|
|
|
33272
33266
|
\`\`\`
|
|
33273
33267
|
|
|
33274
33268
|
**THE FRONTMATTER IS YAML. THE BODY IS MARKDOWN.** Everything above the \`---\` is a real YAML mapping \u2014
|
|
33275
|
-
four PLURAL keys taking LISTS, plus \`for:\`. Everything after the \`---\` is
|
|
33276
|
-
you want, with paragraphs, lists and links. That prose is what the human
|
|
33277
|
-
write it as a handoff, not as a label.
|
|
33269
|
+
four PLURAL keys taking LISTS, plus the scalars \`for:\` and \`title:\`. Everything after the \`---\` is
|
|
33270
|
+
ordinary Markdown, as much as you want, with paragraphs, lists and links. That prose is what the human
|
|
33271
|
+
reads on your resting card, so write it as a handoff, not as a label.
|
|
33278
33272
|
|
|
33279
33273
|
**NO PROSE ABOVE THE \`---\`, EVER.** A sentence in the frontmatter is what makes it stop being YAML: a
|
|
33280
33274
|
colon inside it, or a \` #\` before an issue ref, and the parse either fails or silently eats half the
|
|
@@ -33303,6 +33297,11 @@ a second read for nothing, and it is the commonest thing wrong with an otherwise
|
|
|
33303
33297
|
and on every later review, approval or comment, human or bot, for as long as the PR lives.
|
|
33304
33298
|
- \`for:\` \u2014 **REQUIRED**, and a DURATION: \`30s\`, \`15m\`, \`2h\`, \`3d\`. Never an instant. When it runs
|
|
33305
33299
|
out frizz brings you back to re-check everything; re-parking is fine and uncapped.
|
|
33300
|
+
- \`title:\` \u2014 OPTIONAL, and the one place your own words reach the top of the resting card. Without it
|
|
33301
|
+
the card is headed "Awaiting", which is true of every park on the board and specific to none. Write a
|
|
33302
|
+
HEADING, not a sentence: **40 characters or fewer**, sentence case, naming THIS wait \u2014 "Three-platform
|
|
33303
|
+
CI run", "Fork-CI approval", "Nightly bench, arm 3 of 3". Anything longer is trimmed on a word
|
|
33304
|
+
boundary, and the detail belongs below the \`---\` where there is room for it.
|
|
33306
33305
|
|
|
33307
33306
|
**THE SINGULAR KEYS ARE GONE** \u2014 \`shell:\`, \`agent:\`, \`timer:\`, \`pr:\` and \`reason:\`, one per line, were
|
|
33308
33307
|
the grammar until 2026-08-24. YAML cannot express a repeated key, so they became the lists above. Write
|
|
@@ -33630,13 +33629,10 @@ see your conversation, so handing over context is always your job. The absence o
|
|
|
33630
33629
|
a blocker to report \u2014 write what the child needs into the prompt or a scratch file you name, or do
|
|
33631
33630
|
the work inline.
|
|
33632
33631
|
|
|
33633
|
-
|
|
33634
|
-
|
|
33635
|
-
|
|
33636
|
-
|
|
33637
|
-
lands, diagnosis, architecture, and any probe whose deliverable is a load-bearing verdict. Effort runs
|
|
33638
|
-
low\u2192medium\u2192high\u2192xhigh\u2192max. Bias toward Opus and buy extra rigor with EFFORT; re-verify any cheap-tier
|
|
33639
|
-
load-bearing claim yourself.
|
|
33632
|
+
Two knobs, one each: the model rides the Agent tool's own \`model\` parameter (omit it and the child
|
|
33633
|
+
inherits yours), and the effort rides \`subagent_type\` as the namespaced string \`frizz:<effort>\` \u2014
|
|
33634
|
+
\`frizz:low\`, \`frizz:medium\`, \`frizz:high\`, \`frizz:xhigh\` or \`frizz:max\` (a bare \`high\` will not
|
|
33635
|
+
resolve). Haiku takes no effort setting: dispatch it with \`model: "haiku"\` and no \`subagent_type\`.
|
|
33640
33636
|
|
|
33641
33637
|
Fan out one sub-agent per prong when work genuinely decomposes and the scale warrants it \u2014 authorized,
|
|
33642
33638
|
never required, and never a substitute for running the thing yourself.
|
|
@@ -34595,6 +34591,9 @@ function createClaudeAgentBrokerBridge(deps) {
|
|
|
34595
34591
|
// claudeWorkerEnv). Spread here rather than inherited, which is what gives these per-thread
|
|
34596
34592
|
// values priority over anything in the environment frizz itself was launched with.
|
|
34597
34593
|
...claudeWorkerEnv(),
|
|
34594
|
+
// The auto-compact ceiling, from Settings (500K by default). Without it a `[1m]` worker compacts
|
|
34595
|
+
// only near 1M, re-sending up to 5x a TUI session's conversation on every turn past 200K.
|
|
34596
|
+
...claudeCompactionEnv(deps.getSettings?.()),
|
|
34598
34597
|
...we?.permDir ? { FRIZZ_PERM_DIR: we.permDir } : {},
|
|
34599
34598
|
// The cc-worker plugin's PreToolUse hook DENIES AskUserQuestion, because without frizz in the
|
|
34600
34599
|
// loop a blocking question freezes a headless worker where nobody can answer it. On the broker path
|
|
@@ -34870,19 +34869,19 @@ var init_claude_agent_broker_bridge = __esm({
|
|
|
34870
34869
|
});
|
|
34871
34870
|
|
|
34872
34871
|
// packages/server/src/backend/auth-status.ts
|
|
34873
|
-
import { join as
|
|
34872
|
+
import { join as join26 } from "node:path";
|
|
34874
34873
|
import { homedir as homedir11, platform as platform2 } from "node:os";
|
|
34875
34874
|
import { readFileSync as readFileSync16, statSync as statSync11 } from "node:fs";
|
|
34876
34875
|
import { execFile as execFile4 } from "node:child_process";
|
|
34877
34876
|
import { promisify as promisify4 } from "node:util";
|
|
34878
34877
|
function claudeConfigDir2() {
|
|
34879
34878
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
34880
|
-
return override && override.trim() ? override :
|
|
34879
|
+
return override && override.trim() ? override : join26(homedir11(), ".claude");
|
|
34881
34880
|
}
|
|
34882
34881
|
function claudeFileState(configDir) {
|
|
34883
34882
|
let raw2;
|
|
34884
34883
|
try {
|
|
34885
|
-
raw2 = readFileSync16(
|
|
34884
|
+
raw2 = readFileSync16(join26(configDir, ".credentials.json"), "utf8");
|
|
34886
34885
|
} catch (err) {
|
|
34887
34886
|
return err.code === "ENOENT" ? "absent" : "error";
|
|
34888
34887
|
}
|
|
@@ -34915,7 +34914,7 @@ function readCodexAuthState(codexHome = defaultCodexHome()) {
|
|
|
34915
34914
|
if (process.env.OPENAI_API_KEY || process.env.CODEX_API_KEY || process.env.CODEX_ACCESS_TOKEN) return "authed";
|
|
34916
34915
|
let raw2;
|
|
34917
34916
|
try {
|
|
34918
|
-
raw2 = readFileSync16(
|
|
34917
|
+
raw2 = readFileSync16(join26(codexHome, "auth.json"), "utf8");
|
|
34919
34918
|
} catch (err) {
|
|
34920
34919
|
return err.code === "ENOENT" ? "signed-out" : "unknown";
|
|
34921
34920
|
}
|
|
@@ -34980,7 +34979,7 @@ function asEmail(value) {
|
|
|
34980
34979
|
}
|
|
34981
34980
|
function claudeAccountFile() {
|
|
34982
34981
|
const override = process.env.CLAUDE_CONFIG_DIR;
|
|
34983
|
-
return override && override.trim() ?
|
|
34982
|
+
return override && override.trim() ? join26(override, ".claude.json") : join26(homedir11(), ".claude.json");
|
|
34984
34983
|
}
|
|
34985
34984
|
function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
34986
34985
|
let stat2;
|
|
@@ -35004,7 +35003,7 @@ function readClaudeAccountEmail(path = claudeAccountFile()) {
|
|
|
35004
35003
|
function readCodexAccountEmail(codexHome = defaultCodexHome()) {
|
|
35005
35004
|
let doc;
|
|
35006
35005
|
try {
|
|
35007
|
-
doc = JSON.parse(readFileSync16(
|
|
35006
|
+
doc = JSON.parse(readFileSync16(join26(codexHome, "auth.json"), "utf8"));
|
|
35008
35007
|
} catch {
|
|
35009
35008
|
return void 0;
|
|
35010
35009
|
}
|
|
@@ -35072,8 +35071,8 @@ var init_auth_status = __esm({
|
|
|
35072
35071
|
});
|
|
35073
35072
|
|
|
35074
35073
|
// packages/server/src/dispatch.ts
|
|
35075
|
-
import { closeSync as closeSync12, constants, existsSync as
|
|
35076
|
-
import { basename as basename6, join as
|
|
35074
|
+
import { closeSync as closeSync12, constants, existsSync as existsSync9, fstatSync as fstatSync2, lstatSync as lstatSync3, openSync as openSync13, readFileSync as readFileSync17, realpathSync as realpathSync7, statSync as statSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync13, rmSync as rmSync9 } from "node:fs";
|
|
35075
|
+
import { basename as basename6, join as join27, dirname as dirname11 } from "node:path";
|
|
35077
35076
|
import { createHash as createHash11, randomUUID as randomUUID13 } from "node:crypto";
|
|
35078
35077
|
function fallbackTitle(prompt) {
|
|
35079
35078
|
const firstLine2 = prompt.trim().split("\n", 1)[0].trim();
|
|
@@ -35092,7 +35091,7 @@ function fallbackTitle(prompt) {
|
|
|
35092
35091
|
}
|
|
35093
35092
|
function resolveSlug(frizzDir, base, taken) {
|
|
35094
35093
|
base = ThreadSlug.parse(base);
|
|
35095
|
-
const isTaken = (slug) =>
|
|
35094
|
+
const isTaken = (slug) => existsSync9(join27(frizzDir, `${slug}.md`)) || (taken?.(slug) ?? false);
|
|
35096
35095
|
if (!isTaken(base)) return base;
|
|
35097
35096
|
for (let n = 2; ; n++) {
|
|
35098
35097
|
const suffix = `-${n}`;
|
|
@@ -35109,12 +35108,12 @@ function resolveLegacyThreadFile(projectDir, value) {
|
|
|
35109
35108
|
if (!parsed.success) return null;
|
|
35110
35109
|
try {
|
|
35111
35110
|
const projectRoot = realpathSync7(projectDir);
|
|
35112
|
-
const frizzPath =
|
|
35111
|
+
const frizzPath = join27(projectRoot, ".frizz");
|
|
35113
35112
|
const frizzStat = lstatSync3(frizzPath);
|
|
35114
35113
|
if (!frizzStat.isDirectory() || frizzStat.isSymbolicLink()) return null;
|
|
35115
35114
|
const realFrizz = realpathSync7(frizzPath);
|
|
35116
35115
|
if (dirname11(realFrizz) !== projectRoot || basename6(realFrizz) !== ".frizz") return null;
|
|
35117
|
-
const path =
|
|
35116
|
+
const path = join27(realFrizz, `${parsed.data}.md`);
|
|
35118
35117
|
const before = lstatSync3(path);
|
|
35119
35118
|
if (!before.isFile() || before.isSymbolicLink()) return null;
|
|
35120
35119
|
const realPath = realpathSync7(path);
|
|
@@ -35158,7 +35157,7 @@ function boardAuthorizesAdoption(board, slug) {
|
|
|
35158
35157
|
return !board.errorItems.some((item) => item.file === `${slug}.md`);
|
|
35159
35158
|
}
|
|
35160
35159
|
function ensureSafeDirectDirectory(parent, name) {
|
|
35161
|
-
const path =
|
|
35160
|
+
const path = join27(parent, name);
|
|
35162
35161
|
try {
|
|
35163
35162
|
mkdirSync13(path);
|
|
35164
35163
|
} catch (error) {
|
|
@@ -35188,8 +35187,8 @@ function loadWorkerPrompt(kind = "claude") {
|
|
|
35188
35187
|
function monitorScriptsDir() {
|
|
35189
35188
|
const plugin = workerPluginDir();
|
|
35190
35189
|
if (!plugin) return void 0;
|
|
35191
|
-
const dir =
|
|
35192
|
-
return
|
|
35190
|
+
const dir = join27(plugin, "skills", "gh", "scripts");
|
|
35191
|
+
return existsSync9(join27(dir, "ci-watch.mjs")) ? dir : void 0;
|
|
35193
35192
|
}
|
|
35194
35193
|
function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
35195
35194
|
if (!hookScript || !sessionId) return {};
|
|
@@ -35201,7 +35200,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
35201
35200
|
}
|
|
35202
35201
|
]
|
|
35203
35202
|
});
|
|
35204
|
-
const bashBackgroundHook =
|
|
35203
|
+
const bashBackgroundHook = join27(dirname11(hookScript), "bash-background.mjs");
|
|
35205
35204
|
return {
|
|
35206
35205
|
bypass_hook_trust: true,
|
|
35207
35206
|
hooks: {
|
|
@@ -35227,7 +35226,7 @@ function codexScratchpadHookConfig(hookScript, sessionId) {
|
|
|
35227
35226
|
}
|
|
35228
35227
|
function scratchpadHookScript() {
|
|
35229
35228
|
const plugin = workerPluginDir();
|
|
35230
|
-
return plugin ?
|
|
35229
|
+
return plugin ? join27(plugin, "hooks", "scratchpad.mjs") : void 0;
|
|
35231
35230
|
}
|
|
35232
35231
|
function composePrompt(sessionId, prompt, kind = "claude") {
|
|
35233
35232
|
const children2 = kind === "codex" ? "Native sub-agents share it \u2014 have each write its OWN file rather than all editing one." : "Name it in a sub-agent's prompt when you want its notes to land somewhere you can read; give each child its OWN file rather than having them all edit one.";
|
|
@@ -35243,7 +35242,7 @@ function scratchpadOrientation(sessionId, kind = "claude") {
|
|
|
35243
35242
|
return `SCRATCH DIRECTORY: .frizz/threads/${sessionId}/ \u2014 yours, free-form, as many files as you like, and nothing is expected in it. A single direct task usually needs none; writing notes is never a substitute for doing the work. On a long effort write the doc you would want if you lost your context (${children2}), then arm mcp__frizz__recurring_prompt with post_compaction: true and a prompt LINKING that file \u2014 frizz hands the link back when your context is compacted. Nothing in this directory is read automatically.`;
|
|
35244
35243
|
}
|
|
35245
35244
|
function frizzConfigBlock(projectDir) {
|
|
35246
|
-
const path =
|
|
35245
|
+
const path = join27(projectDir, "FRIZZ.md");
|
|
35247
35246
|
let body;
|
|
35248
35247
|
try {
|
|
35249
35248
|
const st = statSync12(path);
|
|
@@ -35283,8 +35282,8 @@ function resolveFrizzMcp(target, moduleUrl = import.meta.url, env = process.env,
|
|
|
35283
35282
|
const { stateDir, serverLock, projectId } = typeof target === "string" ? { stateDir: target } : target;
|
|
35284
35283
|
const pluginDir = resolveWorkerPluginDir(moduleUrl, env);
|
|
35285
35284
|
if (!pluginDir) return void 0;
|
|
35286
|
-
const scriptPath =
|
|
35287
|
-
if (!
|
|
35285
|
+
const scriptPath = join27(pluginDir, "bin", FRIZZ_MCP.script);
|
|
35286
|
+
if (!existsSync9(scriptPath)) return void 0;
|
|
35288
35287
|
return {
|
|
35289
35288
|
scriptPath,
|
|
35290
35289
|
stateDir,
|
|
@@ -35294,12 +35293,8 @@ function resolveFrizzMcp(target, moduleUrl = import.meta.url, env = process.env,
|
|
|
35294
35293
|
};
|
|
35295
35294
|
}
|
|
35296
35295
|
function claudeMcpConfig(mcp) {
|
|
35297
|
-
const mcpServers = {
|
|
35298
|
-
|
|
35299
|
-
// is what mounts frizz's lazy proxy instead of the real server (backend/types.ts).
|
|
35300
|
-
[CHROME_DEVTOOLS_MCP.name]: chromeDevtoolsMcpMount()
|
|
35301
|
-
};
|
|
35302
|
-
const allowedTools = [`mcp__${CHROME_DEVTOOLS_MCP.name}`];
|
|
35296
|
+
const mcpServers = {};
|
|
35297
|
+
const allowedTools = [];
|
|
35303
35298
|
if (mcp) {
|
|
35304
35299
|
const env = frizzMcpEnv(mcp);
|
|
35305
35300
|
mcpServers[FRIZZ_MCP.name] = { command: process.execPath, args: [mcp.scriptPath], env };
|
|
@@ -35309,6 +35304,7 @@ function claudeMcpConfig(mcp) {
|
|
|
35309
35304
|
}
|
|
35310
35305
|
function claudeMcpFlags(mcp) {
|
|
35311
35306
|
const { mcpServers, allowedTools } = claudeMcpConfig(mcp);
|
|
35307
|
+
if (Object.keys(mcpServers).length === 0) return [];
|
|
35312
35308
|
const config = JSON.stringify({ mcpServers });
|
|
35313
35309
|
return ["--mcp-config", config, `--allowedTools=${allowedTools.join(",")}`];
|
|
35314
35310
|
}
|
|
@@ -35366,7 +35362,7 @@ function buildClaudeResumeCommand(opts) {
|
|
|
35366
35362
|
}
|
|
35367
35363
|
function createDispatcher(deps) {
|
|
35368
35364
|
const readBoardSource = deps.readBoard ?? readBoard;
|
|
35369
|
-
const frizzDir =
|
|
35365
|
+
const frizzDir = join27(deps.project.dir, ".frizz");
|
|
35370
35366
|
const adoptionRuntime = deps.adoptionRuntime ?? productionRuntime;
|
|
35371
35367
|
function cleanupPrewrites(built) {
|
|
35372
35368
|
for (const path of new Set(built.prewrite.map((file) => file.path))) {
|
|
@@ -35379,7 +35375,7 @@ function createDispatcher(deps) {
|
|
|
35379
35375
|
function cleanupDispatchFiles(scratchRel, built, sessionId) {
|
|
35380
35376
|
cleanupPrewrites(built);
|
|
35381
35377
|
try {
|
|
35382
|
-
rmSync9(
|
|
35378
|
+
rmSync9(join27(deps.project.dir, scratchRel), { force: true, recursive: true });
|
|
35383
35379
|
} catch {
|
|
35384
35380
|
}
|
|
35385
35381
|
cleanupAdoptionSessionFiles(deps.project.dir, sessionId);
|
|
@@ -35812,7 +35808,7 @@ import {
|
|
|
35812
35808
|
watch as fsWatch
|
|
35813
35809
|
} from "node:fs";
|
|
35814
35810
|
import { homedir as homedir12 } from "node:os";
|
|
35815
|
-
import { join as
|
|
35811
|
+
import { join as join28 } from "node:path";
|
|
35816
35812
|
import watcher from "@parcel/watcher";
|
|
35817
35813
|
function appServerTurnStalled(liveness, lastActivityAt, nowMs) {
|
|
35818
35814
|
if (!liveness) return false;
|
|
@@ -35910,9 +35906,9 @@ function hasParkedTimerWatch(tele, armedTimerIds) {
|
|
|
35910
35906
|
if (tele?.lastFence?.kind !== "awaiting") return false;
|
|
35911
35907
|
return tele.lastFence.hints.some((hint) => hint.kind === "timer" && armedTimerIds.has(hint.value.trim()));
|
|
35912
35908
|
}
|
|
35913
|
-
function hasDeclaredWait(tele, nowMs, armedTimerIds = /* @__PURE__ */ new Set()) {
|
|
35909
|
+
function hasDeclaredWait(tele, nowMs, armedTimerIds = /* @__PURE__ */ new Set(), registeredPrWatches = /* @__PURE__ */ new Set()) {
|
|
35914
35910
|
if (hasDeclaredBackgroundPark(tele, nowMs)) return true;
|
|
35915
|
-
if (tele?.lastFence?.kind === "awaiting" && hasParkedPrWatch(tele)) return true;
|
|
35911
|
+
if (tele?.lastFence?.kind === "awaiting" && hasParkedPrWatch(tele, registeredPrWatches)) return true;
|
|
35916
35912
|
if (hasParkedTimerWatch(tele, armedTimerIds)) return true;
|
|
35917
35913
|
return (tele?.subAgents ?? []).some((a) => isDirectSubAgent(a) && a.state === "running");
|
|
35918
35914
|
}
|
|
@@ -35930,7 +35926,7 @@ function heldByRunningChecks(tele, github, registered) {
|
|
|
35930
35926
|
return status?.checks === "running" && status.state === "open";
|
|
35931
35927
|
});
|
|
35932
35928
|
}
|
|
35933
|
-
function hasLiveOwnWork(tele) {
|
|
35929
|
+
function hasLiveOwnWork(tele, registeredPrWatches) {
|
|
35934
35930
|
return Boolean(
|
|
35935
35931
|
tele?.subAgents?.some((agent) => isDirectSubAgent(agent) && agent.state === "running") || tele?.bgShells?.some((shell) => shell.state === "running") || // A PARKED PR WATCHER COUNTS (2026-08-13). It is the same shape of thing as a detached shell: the
|
|
35936
35932
|
// worker left it running, it will re-invoke the thread on its own, and until it does there is
|
|
@@ -35938,12 +35934,16 @@ function hasLiveOwnWork(tele) {
|
|
|
35938
35934
|
// counting it — for that card's event-snooze, which is now the ONE control for hiding a parked
|
|
35939
35935
|
// watcher (maintainer: "the user can just use the generic snooze card… now GitHub watchers can be
|
|
35940
35936
|
// included in the ranks of those").
|
|
35941
|
-
hasParkedPrWatch(tele)
|
|
35937
|
+
hasParkedPrWatch(tele, registeredPrWatches)
|
|
35942
35938
|
);
|
|
35943
35939
|
}
|
|
35944
|
-
function hasParkedPrWatch(tele) {
|
|
35940
|
+
function hasParkedPrWatch(tele, registered) {
|
|
35945
35941
|
if (tele?.lastFence?.kind !== "awaiting") return false;
|
|
35946
|
-
return tele.lastFence.hints.some((hint) =>
|
|
35942
|
+
return tele.lastFence.hints.some((hint) => {
|
|
35943
|
+
if (hint.kind !== "pr") return false;
|
|
35944
|
+
const ref = parsePrRef(hint.value);
|
|
35945
|
+
return ref !== void 0 && registered.has(githubStatusKey(ref));
|
|
35946
|
+
});
|
|
35947
35947
|
}
|
|
35948
35948
|
function bgSnoozeArmed(row) {
|
|
35949
35949
|
return row.bg_snooze_rested_at != null && row.rested_at != null && row.bg_snooze_rested_at === row.rested_at;
|
|
@@ -35985,7 +35985,7 @@ function fenceWatchViews(slug, tele, fenceAt, github = {}, registered = [], arme
|
|
|
35985
35985
|
if (tele?.lastFence?.kind !== "awaiting") return out;
|
|
35986
35986
|
const createdAt = fenceAt ?? tele.lastAssistantAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
35987
35987
|
for (const hint of tele.lastFence.hints) {
|
|
35988
|
-
if (hint.kind !== "shell"
|
|
35988
|
+
if (hint.kind !== "shell") continue;
|
|
35989
35989
|
const target = hint.value.trim();
|
|
35990
35990
|
if (!target || seen.has(`shell:${target}`) || !liveWaitHandles(tele).has(target)) continue;
|
|
35991
35991
|
seen.add(`shell:${target}`);
|
|
@@ -36012,15 +36012,15 @@ function deriveNeedsYou(row, tele, runtime, hasActionableInteraction = false, no
|
|
|
36012
36012
|
if (excuseLiveOwnWork && runtime !== "exited" && hasLiveBackgroundWork(tele) && !tele?.lastFence) return false;
|
|
36013
36013
|
if (excuseLiveOwnWork && runtime !== "exited" && hasDeclaredBackgroundPark(tele, nowMs)) return false;
|
|
36014
36014
|
if (excuseLiveOwnWork && runtime !== "exited" && heldByRunningChecks(tele, github, registeredPrWatches)) return false;
|
|
36015
|
-
if (runtime !== "exited" && (hasLiveOwnWork(tele) || hasParkedTimerWatch(tele, armedTimerIds)) && tele?.lastFence?.kind !== "done") return !bgSnoozeArmed(row);
|
|
36015
|
+
if (runtime !== "exited" && (hasLiveOwnWork(tele, registeredPrWatches) || hasParkedTimerWatch(tele, armedTimerIds)) && tele?.lastFence?.kind !== "done") return !bgSnoozeArmed(row);
|
|
36016
36016
|
if (tele?.lastFence?.kind === "done") return true;
|
|
36017
36017
|
return true;
|
|
36018
36018
|
}
|
|
36019
36019
|
function deriveAwaitingBackground(row, tele, runtime, hasActionableInteraction = false, nowMs = Date.now(), limitPause = void 0, deliveryProcessGone = false, github = {}, registeredPrWatches = /* @__PURE__ */ new Set(), armedTimerIds = /* @__PURE__ */ new Set()) {
|
|
36020
|
-
if (runtime !== "turn-idle" || !hasDeclaredWait(tele, nowMs, armedTimerIds)) return false;
|
|
36020
|
+
if (runtime !== "turn-idle" || !hasDeclaredWait(tele, nowMs, armedTimerIds, registeredPrWatches)) return false;
|
|
36021
36021
|
if (hasActionableInteraction || tele?.pendingAsk || tele?.pendingQuestion) return false;
|
|
36022
36022
|
if (tele?.lastFence?.kind === "done") return false;
|
|
36023
|
-
if (tele?.lastFence?.kind === "awaiting" && !hasParkedPrWatch(tele) && !hasDeclaredBackgroundPark(tele, nowMs) && // A TIMER PARK IS THE SAME EXCEPTION AGAIN (2026-08-24): its fence has no park action either, so
|
|
36023
|
+
if (tele?.lastFence?.kind === "awaiting" && !hasParkedPrWatch(tele, registeredPrWatches) && !hasDeclaredBackgroundPark(tele, nowMs) && // A TIMER PARK IS THE SAME EXCEPTION AGAIN (2026-08-24): its fence has no park action either, so
|
|
36024
36024
|
// suppressing this card left the wait stated nowhere but the fence's own machinery footer.
|
|
36025
36025
|
!hasParkedTimerWatch(tele, armedTimerIds)) return false;
|
|
36026
36026
|
return deriveNeedsYou({ ...row, bg_snooze_rested_at: null }, tele, runtime, hasActionableInteraction, nowMs, limitPause, false, deliveryProcessGone, {}, /* @__PURE__ */ new Set(), armedTimerIds);
|
|
@@ -36497,7 +36497,7 @@ function createBoard(project, storage, bus, tailer, bootId, deps = {}) {
|
|
|
36497
36497
|
if (parcelSub || stopped) return Promise.resolve();
|
|
36498
36498
|
if (watchSetup) return watchSetup;
|
|
36499
36499
|
const setup = (async () => {
|
|
36500
|
-
const next = await subscribe(
|
|
36500
|
+
const next = await subscribe(join28(project.dir, ".frizz"), () => scheduleRebuild());
|
|
36501
36501
|
if (stopped) {
|
|
36502
36502
|
await next.unsubscribe();
|
|
36503
36503
|
return;
|
|
@@ -37724,10 +37724,17 @@ ${wakeTimeHeader(now(), spokeAt)}`;
|
|
|
37724
37724
|
for (const sh of tele.retiredShells ?? []) {
|
|
37725
37725
|
for (const h of [sh.taskId, sh.id, sh.label]) if (h) finishedHandles.add(h);
|
|
37726
37726
|
}
|
|
37727
|
-
const
|
|
37727
|
+
for (const a of tele.subAgents ?? []) {
|
|
37728
|
+
if (a.state !== "rested") continue;
|
|
37729
|
+
for (const h of [a.id, a.label]) if (h) finishedHandles.add(h);
|
|
37730
|
+
}
|
|
37731
|
+
const firedTimers = new Set(
|
|
37732
|
+
deps.storage.listThreadTimers(row.slug).filter((t) => t.state === "fired").map((t) => t.id)
|
|
37733
|
+
);
|
|
37734
|
+
const finishedItem = (i) => finishedHandles.has(i.value) || i.kind === "timer" && firedTimers.has(i.value);
|
|
37728
37735
|
const status = park.items.map((i) => {
|
|
37729
37736
|
const gone = dead.some((d) => d.kind === i.kind && d.value === i.value);
|
|
37730
|
-
const note = !gone ? "still running" : finishedItem(i) ? "FINISHED \u2014 its result is waiting for you" : i.kind === "pr" ? "NOT REGISTERED \u2014 register it with `mcp__frizz__watch_pr` first, then name it here" : "NOT RUNNING (nothing by that name)";
|
|
37737
|
+
const note = !gone ? "still running" : i.kind === "timer" && firedTimers.has(i.value) ? "already FIRED \u2014 its wake was delivered; there is nothing left to wait on" : finishedItem(i) ? "FINISHED \u2014 its result is waiting for you" : i.kind === "pr" ? "NOT REGISTERED \u2014 register it with `mcp__frizz__watch_pr` first, then name it here" : "NOT RUNNING (nothing by that name)";
|
|
37731
37738
|
return `- \`${AWAITING_KEY_OF[i.kind]}: [${i.value}]\` \u2014 ${note}`;
|
|
37732
37739
|
});
|
|
37733
37740
|
const allFinished = dead.length > 0 && dead.every(finishedItem);
|
|
@@ -38523,7 +38530,7 @@ var init_resume = __esm({
|
|
|
38523
38530
|
});
|
|
38524
38531
|
|
|
38525
38532
|
// packages/server/src/backend/claude.ts
|
|
38526
|
-
import { join as
|
|
38533
|
+
import { join as join29 } from "node:path";
|
|
38527
38534
|
function toolResultText2(content) {
|
|
38528
38535
|
if (typeof content === "string") return content;
|
|
38529
38536
|
if (!Array.isArray(content)) return "";
|
|
@@ -38612,7 +38619,7 @@ function createClaudeBackend(opts) {
|
|
|
38612
38619
|
return { argv, env: claudeWorkerEnvironment(), prewrite: [] };
|
|
38613
38620
|
},
|
|
38614
38621
|
transcriptPath(sessionId) {
|
|
38615
|
-
return
|
|
38622
|
+
return join29(opts.logDir, `${sessionId}.jsonl`);
|
|
38616
38623
|
},
|
|
38617
38624
|
parseLine(line) {
|
|
38618
38625
|
return parseClaudeLine(line);
|
|
@@ -38782,12 +38789,12 @@ var init_login_utility = __esm({
|
|
|
38782
38789
|
|
|
38783
38790
|
// packages/server/src/backend/codex-app-server-diagnostics.ts
|
|
38784
38791
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync14, renameSync as renameSync8, statSync as statSync13 } from "node:fs";
|
|
38785
|
-
import { join as
|
|
38792
|
+
import { join as join30 } from "node:path";
|
|
38786
38793
|
function codexDiagnosticLogPath(stateDir, projectId) {
|
|
38787
|
-
return
|
|
38794
|
+
return join30(stateDir, "codex-app-server", `${projectId}.diagnostics.log`);
|
|
38788
38795
|
}
|
|
38789
38796
|
function createCodexDiagnosticSink(stateDir, projectId, now = () => /* @__PURE__ */ new Date()) {
|
|
38790
|
-
const dir =
|
|
38797
|
+
const dir = join30(stateDir, "codex-app-server");
|
|
38791
38798
|
const path = codexDiagnosticLogPath(stateDir, projectId);
|
|
38792
38799
|
let ensured = false;
|
|
38793
38800
|
return (event) => {
|
|
@@ -38819,7 +38826,7 @@ var init_codex_app_server_diagnostics = __esm({
|
|
|
38819
38826
|
import { execFile as execFile7 } from "node:child_process";
|
|
38820
38827
|
import { readdirSync as readdirSync8, unlinkSync as unlinkSync4 } from "node:fs";
|
|
38821
38828
|
import { connect as connectSocket } from "node:net";
|
|
38822
|
-
import { join as
|
|
38829
|
+
import { join as join31 } from "node:path";
|
|
38823
38830
|
function parseLsofSocketNames(stdout) {
|
|
38824
38831
|
const referenced = /* @__PURE__ */ new Set();
|
|
38825
38832
|
for (const line of stdout.split("\n")) {
|
|
@@ -38836,7 +38843,7 @@ function sweepStaleSockets(options, deps = {}) {
|
|
|
38836
38843
|
const keep = new Set(options.keep ?? []);
|
|
38837
38844
|
let candidates;
|
|
38838
38845
|
try {
|
|
38839
|
-
candidates = (deps.readdir ?? readdirSync8)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) =>
|
|
38846
|
+
candidates = (deps.readdir ?? readdirSync8)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) => join31(options.dir, name)).filter((path) => !keep.has(path));
|
|
38840
38847
|
} catch {
|
|
38841
38848
|
return;
|
|
38842
38849
|
}
|
|
@@ -39300,7 +39307,7 @@ var init_thread_hibernation = __esm({
|
|
|
39300
39307
|
});
|
|
39301
39308
|
|
|
39302
39309
|
// packages/server/src/context.ts
|
|
39303
|
-
import { join as
|
|
39310
|
+
import { join as join32 } from "node:path";
|
|
39304
39311
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
39305
39312
|
import { homedir as homedir13 } from "node:os";
|
|
39306
39313
|
function reconcileSessions(storage) {
|
|
@@ -39458,7 +39465,7 @@ async function createContext(opts = {}) {
|
|
|
39458
39465
|
function createContextUnchecked(opts, resources) {
|
|
39459
39466
|
const home = opts.home ?? homedir13();
|
|
39460
39467
|
const project = opts.project ?? resolveProject();
|
|
39461
|
-
const dbPath =
|
|
39468
|
+
const dbPath = join32(project.stateDir, "ui.db");
|
|
39462
39469
|
const storage = createStorage(dbPath);
|
|
39463
39470
|
resources.storage = storage;
|
|
39464
39471
|
const bus = new Bus();
|
|
@@ -39603,12 +39610,16 @@ function createContextUnchecked(opts, resources) {
|
|
|
39603
39610
|
projectId: project.id,
|
|
39604
39611
|
// The frizz worker environment — the SDK equivalent of the CLI argv's --plugin-dir / --mcp-config.
|
|
39605
39612
|
// Computed ONCE here (constant per project) and applied on every broker fork so a broker worker
|
|
39606
|
-
// gets the frizz sub-agent profiles, the frizz
|
|
39613
|
+
// gets the frizz sub-agent profiles, the frizz MCP server (the only one frizz mounts), and the
|
|
39614
|
+
// cc-worker hooks. A project's own `.mcp.json` servers load on top of these, not through them.
|
|
39607
39615
|
workerEnv: {
|
|
39608
39616
|
pluginDir: workerPluginDir(),
|
|
39609
39617
|
...claudeMcpConfig(resolveFrizzMcp(frizzMcpTarget)),
|
|
39610
39618
|
permDir: permRequestDir(project)
|
|
39611
39619
|
},
|
|
39620
|
+
// Read at every fork, not captured once: the compaction window is a Settings value the drawer
|
|
39621
|
+
// can change while the server runs, and the next dispatch or cold resume should carry it.
|
|
39622
|
+
getSettings: () => getSettings(storage, home),
|
|
39612
39623
|
// Which broker threads warmUp() may reattach at boot. Same predicate codex's shouldAutoResume
|
|
39613
39624
|
// applies: never wake a thread the human has already put away — a boot reattach is only for a
|
|
39614
39625
|
// thread that is still open and still theirs to come back to. Broker-backed rows only; a
|
|
@@ -42499,7 +42510,7 @@ var init_server = __esm({
|
|
|
42499
42510
|
});
|
|
42500
42511
|
|
|
42501
42512
|
// packages/server/src/repair.ts
|
|
42502
|
-
import { existsSync as
|
|
42513
|
+
import { existsSync as existsSync11, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
|
|
42503
42514
|
import { basename as basename7, dirname as dirname13, resolve as resolve6 } from "node:path";
|
|
42504
42515
|
function quoteValue(v) {
|
|
42505
42516
|
if (/^[\w./#:+-]+$/.test(v)) return v;
|
|
@@ -42514,7 +42525,7 @@ function repairThreadFile(frizzDir, file) {
|
|
|
42514
42525
|
const abs = resolve6(root, file);
|
|
42515
42526
|
if (dirname13(abs) !== root) throw new RepairError(`refusing to repair "${file}": not directly under .frizz/`);
|
|
42516
42527
|
if (!abs.endsWith(".md")) throw new RepairError(`refusing to repair "${file}": not a .md thread file`);
|
|
42517
|
-
if (!
|
|
42528
|
+
if (!existsSync11(abs)) throw new RepairError(`no thread file to repair: ${basename7(abs)}`);
|
|
42518
42529
|
const content = readFileSync19(abs, "utf8");
|
|
42519
42530
|
const firstLine2 = content.replace(/^/, "").split(/\r?\n/).find((l) => l.trim() !== "");
|
|
42520
42531
|
if (firstLine2?.trim() === "---") {
|
|
@@ -42706,10 +42717,10 @@ var init_bash_background = __esm({
|
|
|
42706
42717
|
});
|
|
42707
42718
|
|
|
42708
42719
|
// packages/server/src/transcript.ts
|
|
42709
|
-
import { closeSync as closeSync13, existsSync as
|
|
42720
|
+
import { closeSync as closeSync13, existsSync as existsSync12, fstatSync as fstatSync3, mkdirSync as mkdirSync15, openSync as openSync14, readdirSync as readdirSync9, readFileSync as readFileSync21, readSync as readSync7, renameSync as renameSync9, statSync as statSync14, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
42710
42721
|
import { createHash as createHash13 } from "node:crypto";
|
|
42711
42722
|
import { StringDecoder as StringDecoder4 } from "node:string_decoder";
|
|
42712
|
-
import { join as
|
|
42723
|
+
import { join as join33 } from "node:path";
|
|
42713
42724
|
import { homedir as homedir14 } from "node:os";
|
|
42714
42725
|
function formatTokens(n) {
|
|
42715
42726
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -43259,14 +43270,14 @@ function pruneScreenshotCache() {
|
|
|
43259
43270
|
if (entries.length <= SCREENSHOT_CACHE_MAX) return;
|
|
43260
43271
|
const byMtime = entries.map((n) => {
|
|
43261
43272
|
try {
|
|
43262
|
-
return { n, m: statSync14(
|
|
43273
|
+
return { n, m: statSync14(join33(SCREENSHOT_CACHE_DIR, n)).mtimeMs };
|
|
43263
43274
|
} catch {
|
|
43264
43275
|
return { n, m: 0 };
|
|
43265
43276
|
}
|
|
43266
43277
|
}).sort((a, b) => b.m - a.m);
|
|
43267
43278
|
for (const { n } of byMtime.slice(SCREENSHOT_CACHE_MAX)) {
|
|
43268
43279
|
try {
|
|
43269
|
-
unlinkSync5(
|
|
43280
|
+
unlinkSync5(join33(SCREENSHOT_CACHE_DIR, n));
|
|
43270
43281
|
} catch {
|
|
43271
43282
|
}
|
|
43272
43283
|
}
|
|
@@ -43296,14 +43307,14 @@ function persistBase64Image(mediaType, data, idKey) {
|
|
|
43296
43307
|
const ext = IMAGE_MEDIA_EXT[typeof mediaType === "string" ? mediaType.toLowerCase() : ""];
|
|
43297
43308
|
if (!ext || !data) return void 0;
|
|
43298
43309
|
const name = createHash13("sha256").update(idKey).digest("hex").slice(0, 32);
|
|
43299
|
-
const path =
|
|
43310
|
+
const path = join33(SCREENSHOT_CACHE_DIR, `${name}.${ext}`);
|
|
43300
43311
|
try {
|
|
43301
|
-
if (
|
|
43312
|
+
if (existsSync12(path)) return path;
|
|
43302
43313
|
if (data.length > SCREENSHOT_MAX_BASE64) return void 0;
|
|
43303
43314
|
const buf = Buffer.from(data, "base64");
|
|
43304
43315
|
if (buf.length === 0 || !looksLikeImage(buf, ext)) return void 0;
|
|
43305
43316
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
43306
|
-
const tmp =
|
|
43317
|
+
const tmp = join33(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
43307
43318
|
writeFileSync12(tmp, buf);
|
|
43308
43319
|
renameSync9(tmp, path);
|
|
43309
43320
|
pruneScreenshotCache();
|
|
@@ -43318,14 +43329,14 @@ function persistSentFile(srcPath, idKey) {
|
|
|
43318
43329
|
const outExt = ext === "jpeg" ? "jpg" : ext;
|
|
43319
43330
|
try {
|
|
43320
43331
|
const name = createHash13("sha256").update(idKey).digest("hex").slice(0, 32);
|
|
43321
|
-
const dest =
|
|
43322
|
-
if (
|
|
43332
|
+
const dest = join33(SCREENSHOT_CACHE_DIR, `${name}.${outExt}`);
|
|
43333
|
+
if (existsSync12(dest)) return dest;
|
|
43323
43334
|
const size = statSync14(srcPath).size;
|
|
43324
43335
|
if (size === 0 || size > SENT_IMAGE_MAX_BYTES) return void 0;
|
|
43325
43336
|
const buf = readFileSync21(srcPath);
|
|
43326
43337
|
if (!looksLikeImage(buf, outExt)) return void 0;
|
|
43327
43338
|
mkdirSync15(SCREENSHOT_CACHE_DIR, { recursive: true });
|
|
43328
|
-
const tmp =
|
|
43339
|
+
const tmp = join33(SCREENSHOT_CACHE_DIR, `.${name}.${process.pid}.${screenshotTmpSeq++}.tmp`);
|
|
43329
43340
|
writeFileSync12(tmp, buf);
|
|
43330
43341
|
renameSync9(tmp, dest);
|
|
43331
43342
|
pruneScreenshotCache();
|
|
@@ -43762,16 +43773,16 @@ function verifyIncrementalParse(path, identityPrefix, incremental) {
|
|
|
43762
43773
|
}
|
|
43763
43774
|
}
|
|
43764
43775
|
function logDirOf(project) {
|
|
43765
|
-
return
|
|
43776
|
+
return join33(homedir14(), ".claude", "projects", project.cwdSlug);
|
|
43766
43777
|
}
|
|
43767
43778
|
function resolveTranscriptPath(project, sessionId) {
|
|
43768
|
-
const path =
|
|
43779
|
+
const path = join33(logDirOf(project), `${sessionId}.jsonl`);
|
|
43769
43780
|
try {
|
|
43770
43781
|
if (statSync14(path).size > 0) return path;
|
|
43771
43782
|
} catch {
|
|
43772
43783
|
}
|
|
43773
43784
|
const stranded = discoverTranscriptDir(logDirOf(project), sessionId);
|
|
43774
|
-
return stranded ?
|
|
43785
|
+
return stranded ? join33(stranded, `${sessionId}.jsonl`) : path;
|
|
43775
43786
|
}
|
|
43776
43787
|
function projectCodexTranscript(raw2, identityPrefix = "codex") {
|
|
43777
43788
|
const out = [];
|
|
@@ -44715,7 +44726,7 @@ function sourceForThread(project, storage, slug, backendFor) {
|
|
|
44715
44726
|
}
|
|
44716
44727
|
if (!FOREIGN_SESSION_ID_RE.test(slug)) return void 0;
|
|
44717
44728
|
const claudePath = resolveTranscriptPath(project, slug);
|
|
44718
|
-
if (
|
|
44729
|
+
if (existsSync12(claudePath)) {
|
|
44719
44730
|
return { slug, sessionId: slug, nativeId: slug, backend: "claude", runtimeGeneration: 0, path: claudePath };
|
|
44720
44731
|
}
|
|
44721
44732
|
const rollout = (backendFor?.("codex") ?? defaultCodexBackend()).transcriptPath(slug);
|
|
@@ -45171,7 +45182,7 @@ var init_open_external = __esm({
|
|
|
45171
45182
|
import { spawn as spawn6 } from "node:child_process";
|
|
45172
45183
|
import { readFileSync as readFileSync22, realpathSync as realpathSync8, statSync as statSync15 } from "node:fs";
|
|
45173
45184
|
import { homedir as homedir15 } from "node:os";
|
|
45174
|
-
import { isAbsolute as isAbsolute3, join as
|
|
45185
|
+
import { isAbsolute as isAbsolute3, join as join34, resolve as resolve7, sep } from "node:path";
|
|
45175
45186
|
function isUnder(real, root) {
|
|
45176
45187
|
let rootReal;
|
|
45177
45188
|
try {
|
|
@@ -45201,7 +45212,7 @@ function resolveLocalFile(rawPath, roots) {
|
|
|
45201
45212
|
function resolveOpenableFile(raw2, projectDir, roots, home = homedir15()) {
|
|
45202
45213
|
const trimmed = raw2.trim().replace(/:\d+(?::\d+)?$/, "");
|
|
45203
45214
|
if (!trimmed) return null;
|
|
45204
|
-
const abs = trimmed === "~" ? home : trimmed.startsWith("~/") ?
|
|
45215
|
+
const abs = trimmed === "~" ? home : trimmed.startsWith("~/") ? join34(home, trimmed.slice(2)) : isAbsolute3(trimmed) ? trimmed : resolve7(projectDir, trimmed);
|
|
45205
45216
|
try {
|
|
45206
45217
|
return resolveLocalFile(abs, roots);
|
|
45207
45218
|
} catch {
|
|
@@ -45912,10 +45923,10 @@ var init_directory_picker = __esm({
|
|
|
45912
45923
|
|
|
45913
45924
|
// packages/server/src/router.ts
|
|
45914
45925
|
import { readFileSync as readFileSync23, statSync as statSync17 } from "node:fs";
|
|
45915
|
-
import { join as
|
|
45926
|
+
import { join as join35, resolve as resolve8 } from "node:path";
|
|
45916
45927
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
45917
45928
|
import { basename as basename9, dirname as dirname14 } from "node:path";
|
|
45918
|
-
import { existsSync as
|
|
45929
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync16, rmSync as rmSync10, writeFileSync as writeFileSync13 } from "node:fs";
|
|
45919
45930
|
import { homedir as homedir16 } from "node:os";
|
|
45920
45931
|
function validateGithubDispatchProfile(input) {
|
|
45921
45932
|
validateThreadProfile(input.backend, input.model, input.effort);
|
|
@@ -46075,7 +46086,7 @@ function projectCard(entry, stale) {
|
|
|
46075
46086
|
function addProjectAtPath(input) {
|
|
46076
46087
|
const typed = input.trim();
|
|
46077
46088
|
if (!typed) throw new Error("Enter a folder path.");
|
|
46078
|
-
const expanded = typed === "~" || typed.startsWith("~/") ?
|
|
46089
|
+
const expanded = typed === "~" || typed.startsWith("~/") ? join35(homedir16(), typed.slice(1)) : typed;
|
|
46079
46090
|
const absolute = resolve8(expanded);
|
|
46080
46091
|
let stats;
|
|
46081
46092
|
try {
|
|
@@ -46128,7 +46139,7 @@ function setProjectIconFromFile(id, file) {
|
|
|
46128
46139
|
return storeProjectIcon(id, file, bytes);
|
|
46129
46140
|
}
|
|
46130
46141
|
function createRouter(ctx) {
|
|
46131
|
-
const frizzDir =
|
|
46142
|
+
const frizzDir = join35(ctx.project.dir, ".frizz");
|
|
46132
46143
|
const openRoots = openableFileRoots(ctx.project);
|
|
46133
46144
|
function isAutoTitledSession(slug) {
|
|
46134
46145
|
return ctx.storage.getSession(slug)?.title_auto === 1;
|
|
@@ -47739,7 +47750,7 @@ ${gapNote}` : input.message;
|
|
|
47739
47750
|
}
|
|
47740
47751
|
const updated = clearProjectIcon(input.id);
|
|
47741
47752
|
if (!updated) throw new Error("No such project.");
|
|
47742
|
-
return projectCard(updated, !
|
|
47753
|
+
return projectCard(updated, !existsSync13(updated.path));
|
|
47743
47754
|
}
|
|
47744
47755
|
}),
|
|
47745
47756
|
/**
|
|
@@ -47789,7 +47800,7 @@ ${gapNote}` : input.message;
|
|
|
47789
47800
|
for (const entry of listProjects()) {
|
|
47790
47801
|
if (entry.stale) continue;
|
|
47791
47802
|
try {
|
|
47792
|
-
const db = new sqlite_default(
|
|
47803
|
+
const db = new sqlite_default(join35(projectStateDir(entry.id), "ui.db"), { readonly: true });
|
|
47793
47804
|
try {
|
|
47794
47805
|
const hit = db.prepare("SELECT 1 FROM session WHERE slug = ? LIMIT 1").get(input.slug);
|
|
47795
47806
|
if (hit) found.push({ projectSlug: entry.slug, projectName: entry.name ?? entry.slug });
|
|
@@ -48181,7 +48192,7 @@ var init_local_image = __esm({
|
|
|
48181
48192
|
// packages/server/src/project-icon.ts
|
|
48182
48193
|
import { readFileSync as readFileSync25, readdirSync as readdirSync10, realpathSync as realpathSync10, statSync as statSync19 } from "node:fs";
|
|
48183
48194
|
import { homedir as homedir17 } from "node:os";
|
|
48184
|
-
import { basename as basename10, dirname as dirname15, extname as extname3, join as
|
|
48195
|
+
import { basename as basename10, dirname as dirname15, extname as extname3, join as join36, relative, sep as sep2 } from "node:path";
|
|
48185
48196
|
function normalizeStem(stem) {
|
|
48186
48197
|
const sized = stem.toLowerCase().replace(/[@-]\d+(\.\d+)?x(\d+)?$/u, "").replace(/[-_]\d{2,4}$/u, "");
|
|
48187
48198
|
const normalized = sized.replace(VARIANT_SUFFIX, "");
|
|
@@ -48199,7 +48210,7 @@ function sizeScore(dimensions) {
|
|
|
48199
48210
|
return Math.max(0, Math.min(40, Math.round(Math.log2(edge / 24) * 8)));
|
|
48200
48211
|
}
|
|
48201
48212
|
function under(root, relativeDirectory) {
|
|
48202
|
-
return relativeDirectory ?
|
|
48213
|
+
return relativeDirectory ? join36(root, relativeDirectory) : root;
|
|
48203
48214
|
}
|
|
48204
48215
|
function listFiles(directory) {
|
|
48205
48216
|
try {
|
|
@@ -48221,19 +48232,19 @@ function iconDirectories(root) {
|
|
|
48221
48232
|
for (const asset of ASSET_DIRECTORIES) directories.push(under(root, asset));
|
|
48222
48233
|
for (const host of HOST_DIRECTORIES) {
|
|
48223
48234
|
if (!children2.has(host)) continue;
|
|
48224
|
-
for (const asset of ASSET_DIRECTORIES) directories.push(under(
|
|
48235
|
+
for (const asset of ASSET_DIRECTORIES) directories.push(under(join36(root, host), asset));
|
|
48225
48236
|
}
|
|
48226
48237
|
for (const extra of EXTRA_DIRECTORIES) directories.push(under(root, extra));
|
|
48227
48238
|
for (const container of WORKSPACE_CONTAINERS) {
|
|
48228
48239
|
if (!children2.has(container)) continue;
|
|
48229
48240
|
let members;
|
|
48230
48241
|
try {
|
|
48231
|
-
members = readdirSync10(
|
|
48242
|
+
members = readdirSync10(join36(root, container), { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
48232
48243
|
} catch {
|
|
48233
48244
|
continue;
|
|
48234
48245
|
}
|
|
48235
48246
|
for (const member of members) {
|
|
48236
|
-
for (const asset of ASSET_DIRECTORIES) directories.push(under(
|
|
48247
|
+
for (const asset of ASSET_DIRECTORIES) directories.push(under(join36(root, container, member), asset));
|
|
48237
48248
|
}
|
|
48238
48249
|
}
|
|
48239
48250
|
return [...new Set(directories)];
|
|
@@ -48247,7 +48258,7 @@ function manifestIcons(manifestPath) {
|
|
|
48247
48258
|
}
|
|
48248
48259
|
if (!Array.isArray(parsed?.icons)) return [];
|
|
48249
48260
|
const directory = dirname15(manifestPath);
|
|
48250
|
-
return parsed.icons.map((icon) => typeof icon?.src === "string" ? icon.src : void 0).filter((src) => !!src && !/^(https?:)?\/\//u.test(src) && !src.startsWith("data:")).map((src) =>
|
|
48261
|
+
return parsed.icons.map((icon) => typeof icon?.src === "string" ? icon.src : void 0).filter((src) => !!src && !/^(https?:)?\/\//u.test(src) && !src.startsWith("data:")).map((src) => join36(directory, src.replace(/[?#].*$/u, "").replace(/^\//u, "")));
|
|
48251
48262
|
}
|
|
48252
48263
|
function projectIconCandidates(root) {
|
|
48253
48264
|
const projectStem = normalizeStem(basename10(root)).normalized;
|
|
@@ -48266,7 +48277,7 @@ function projectIconCandidates(root) {
|
|
|
48266
48277
|
for (const name of listFiles(directory)) {
|
|
48267
48278
|
const extension2 = extname3(name).toLowerCase();
|
|
48268
48279
|
if (MANIFEST_NAMES.includes(name.toLowerCase())) {
|
|
48269
|
-
for (const icon of manifestIcons(
|
|
48280
|
+
for (const icon of manifestIcons(join36(directory, name))) {
|
|
48270
48281
|
if (MEASURABLE_IMAGE_EXTENSIONS.has(extname3(icon).toLowerCase())) {
|
|
48271
48282
|
fromManifest.add(icon);
|
|
48272
48283
|
files.push({ path: icon, directory: dirname15(icon) });
|
|
@@ -48277,7 +48288,7 @@ function projectIconCandidates(root) {
|
|
|
48277
48288
|
if (!MEASURABLE_IMAGE_EXTENSIONS.has(extension2)) continue;
|
|
48278
48289
|
const stem = name.slice(0, name.length - extension2.length);
|
|
48279
48290
|
if (normalizeStem(stem).normalized === "favicon") iconHomes.add(directory);
|
|
48280
|
-
files.push({ path:
|
|
48291
|
+
files.push({ path: join36(directory, name), directory });
|
|
48281
48292
|
if (files.length >= MAX_CANDIDATES) break;
|
|
48282
48293
|
}
|
|
48283
48294
|
}
|
|
@@ -48455,7 +48466,7 @@ var init_project_icon = __esm({
|
|
|
48455
48466
|
|
|
48456
48467
|
// packages/server/src/local-visualization.ts
|
|
48457
48468
|
import { readdirSync as readdirSync11, readFileSync as readFileSync26, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
48458
|
-
import { join as
|
|
48469
|
+
import { join as join37, sep as sep3 } from "node:path";
|
|
48459
48470
|
function children(path, pattern) {
|
|
48460
48471
|
try {
|
|
48461
48472
|
return readdirSync11(path, { withFileTypes: true }).filter((entry) => entry.isDirectory() && pattern.test(entry.name)).map((entry) => entry.name).sort().reverse();
|
|
@@ -48467,7 +48478,7 @@ function isUnder2(path, root) {
|
|
|
48467
48478
|
return path === root || path.startsWith(root.endsWith(sep3) ? root : root + sep3);
|
|
48468
48479
|
}
|
|
48469
48480
|
function resolveFragment(projectDir, sessionId, file) {
|
|
48470
|
-
const base =
|
|
48481
|
+
const base = join37(projectDir, ".codex", "visualizations");
|
|
48471
48482
|
let projectReal;
|
|
48472
48483
|
let baseReal;
|
|
48473
48484
|
try {
|
|
@@ -48478,12 +48489,12 @@ function resolveFragment(projectDir, sessionId, file) {
|
|
|
48478
48489
|
}
|
|
48479
48490
|
if (!isUnder2(baseReal, projectReal)) return null;
|
|
48480
48491
|
for (const year of children(base, YEAR_PART)) {
|
|
48481
|
-
const yearDir =
|
|
48492
|
+
const yearDir = join37(base, year);
|
|
48482
48493
|
for (const month of children(yearDir, DATE_PART)) {
|
|
48483
|
-
const monthDir =
|
|
48494
|
+
const monthDir = join37(yearDir, month);
|
|
48484
48495
|
for (const day of children(monthDir, DATE_PART)) {
|
|
48485
|
-
const sessionRoot =
|
|
48486
|
-
const candidate =
|
|
48496
|
+
const sessionRoot = join37(baseReal, year, month, day, sessionId);
|
|
48497
|
+
const candidate = join37(monthDir, day, sessionId, file);
|
|
48487
48498
|
try {
|
|
48488
48499
|
const real = realpathSync11(candidate);
|
|
48489
48500
|
if (isUnder2(real, sessionRoot) && statSync20(real).isFile()) return real;
|
|
@@ -48612,7 +48623,7 @@ var init_local_visualization = __esm({
|
|
|
48612
48623
|
|
|
48613
48624
|
// packages/server/src/app.ts
|
|
48614
48625
|
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync14 } from "node:fs";
|
|
48615
|
-
import { join as
|
|
48626
|
+
import { join as join38 } from "node:path";
|
|
48616
48627
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
48617
48628
|
function createApp(ctx, options = {}) {
|
|
48618
48629
|
const app = new Hono2();
|
|
@@ -48716,10 +48727,10 @@ function createApp(ctx, options = {}) {
|
|
|
48716
48727
|
if (typeof body.data !== "string" || body.data.length > ATTACHMENT_MAX_BASE64_CHARS) return c.json({ error: "bad payload" }, 400);
|
|
48717
48728
|
const ext = `.${attachmentExtension(name)}`;
|
|
48718
48729
|
const buf = Buffer.from(body.data, "base64");
|
|
48719
|
-
const dir =
|
|
48730
|
+
const dir = join38(ctx.project.stateDir, "attachments");
|
|
48720
48731
|
mkdirSync17(dir, { recursive: true });
|
|
48721
48732
|
const base = name.replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]+/g, "-").slice(0, 40) || "file";
|
|
48722
|
-
const path =
|
|
48733
|
+
const path = join38(dir, `${Date.now()}-${randomUUID17().slice(0, 8)}-${base}${ext}`);
|
|
48723
48734
|
writeFileSync14(path, buf);
|
|
48724
48735
|
return c.json({ path });
|
|
48725
48736
|
});
|
|
@@ -49959,9 +49970,9 @@ var init_app_socket = __esm({
|
|
|
49959
49970
|
|
|
49960
49971
|
// packages/server/src/boot-progress.ts
|
|
49961
49972
|
import { mkdirSync as mkdirSync18, readFileSync as readFileSync27, renameSync as renameSync10, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
49962
|
-
import { basename as basename11, dirname as dirname16, join as
|
|
49973
|
+
import { basename as basename11, dirname as dirname16, join as join39 } from "node:path";
|
|
49963
49974
|
function bootProgressPath(stateDir) {
|
|
49964
|
-
return
|
|
49975
|
+
return join39(stateDir, BOOT_PROGRESS_NAME);
|
|
49965
49976
|
}
|
|
49966
49977
|
function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
49967
49978
|
if (!stateDir) {
|
|
@@ -49982,7 +49993,7 @@ function createBootProgressPublisher(stateDir, minIntervalMs = 200) {
|
|
|
49982
49993
|
step++;
|
|
49983
49994
|
try {
|
|
49984
49995
|
mkdirSync18(dirname16(path), { recursive: true, mode: 448 });
|
|
49985
|
-
const temp =
|
|
49996
|
+
const temp = join39(dirname16(path), `.${basename11(path)}.${process.pid}.tmp`);
|
|
49986
49997
|
writeFileSync15(temp, `${JSON.stringify({ pid: process.pid, step, phase, at: new Date(now).toISOString() })}
|
|
49987
49998
|
`, "utf8");
|
|
49988
49999
|
renameSync10(temp, path);
|
|
@@ -50099,8 +50110,8 @@ __export(index_exports, {
|
|
|
50099
50110
|
unknownProjectPage: () => unknownProjectPage
|
|
50100
50111
|
});
|
|
50101
50112
|
import { createServer } from "node:http";
|
|
50102
|
-
import { readFileSync as readFileSync28, existsSync as
|
|
50103
|
-
import { dirname as dirname17, join as
|
|
50113
|
+
import { readFileSync as readFileSync28, existsSync as existsSync14 } from "node:fs";
|
|
50114
|
+
import { dirname as dirname17, join as join40, resolve as resolve9, extname as extname4, normalize } from "node:path";
|
|
50104
50115
|
function readServerAddressHolder(path) {
|
|
50105
50116
|
try {
|
|
50106
50117
|
const value = JSON.parse(readFileSync28(path, "utf8"));
|
|
@@ -50203,9 +50214,9 @@ function createShutdownSignalHandler(options) {
|
|
|
50203
50214
|
}
|
|
50204
50215
|
function serveStatic(distDir, req, res) {
|
|
50205
50216
|
const rel = normalize((req.url ?? "/").split("?")[0]).replace(/^(\.\.[/\\])+/, "");
|
|
50206
|
-
let file =
|
|
50207
|
-
if (!file.startsWith(distDir)) file =
|
|
50208
|
-
if (!
|
|
50217
|
+
let file = join40(distDir, rel === "/" ? "index.html" : rel);
|
|
50218
|
+
if (!file.startsWith(distDir)) file = join40(distDir, "index.html");
|
|
50219
|
+
if (!existsSync14(file)) file = join40(distDir, "index.html");
|
|
50209
50220
|
try {
|
|
50210
50221
|
const body = readFileSync28(file);
|
|
50211
50222
|
res.writeHead(200, { "content-type": MIME[extname4(file)] ?? "application/octet-stream" });
|
|
@@ -50556,7 +50567,7 @@ async function startServer(opts = {}) {
|
|
|
50556
50567
|
}
|
|
50557
50568
|
statusPath = serverLockPathFor(ctx.project);
|
|
50558
50569
|
const webRoot = resolve9(import.meta.dirname, "..", "..", "web");
|
|
50559
|
-
const distDir = opts.webDistDir ? resolve9(opts.webDistDir) :
|
|
50570
|
+
const distDir = opts.webDistDir ? resolve9(opts.webDistDir) : join40(webRoot, "dist");
|
|
50560
50571
|
startupPhase = "Vite";
|
|
50561
50572
|
if (opts.dev) {
|
|
50562
50573
|
try {
|
|
@@ -50632,7 +50643,7 @@ async function startServer(opts = {}) {
|
|
|
50632
50643
|
if (vite) {
|
|
50633
50644
|
vite.middlewares(req, res, () => {
|
|
50634
50645
|
try {
|
|
50635
|
-
const html = readFileSync28(
|
|
50646
|
+
const html = readFileSync28(join40(webRoot, "index.html"), "utf8");
|
|
50636
50647
|
void vite.transformIndexHtml(url, html).then((out) => {
|
|
50637
50648
|
res.writeHead(200, { "content-type": "text/html" });
|
|
50638
50649
|
res.end(out);
|
|
@@ -50644,7 +50655,7 @@ async function startServer(opts = {}) {
|
|
|
50644
50655
|
});
|
|
50645
50656
|
return;
|
|
50646
50657
|
}
|
|
50647
|
-
if (
|
|
50658
|
+
if (existsSync14(distDir)) {
|
|
50648
50659
|
serveStatic(distDir, req, res);
|
|
50649
50660
|
return;
|
|
50650
50661
|
}
|
|
@@ -50824,7 +50835,7 @@ var init_index = __esm({
|
|
|
50824
50835
|
}
|
|
50825
50836
|
};
|
|
50826
50837
|
isApiUrl = (url) => url === FRIZZ_ROUTE_PREFIX || url.startsWith(`${FRIZZ_ROUTE_PREFIX}/`);
|
|
50827
|
-
serverLockPathFor = (project) =>
|
|
50838
|
+
serverLockPathFor = (project) => join40(project.stateDir, "server.lock");
|
|
50828
50839
|
MIME = {
|
|
50829
50840
|
".html": "text/html",
|
|
50830
50841
|
".js": "text/javascript",
|
|
@@ -50842,8 +50853,8 @@ init_project();
|
|
|
50842
50853
|
init_project_launch();
|
|
50843
50854
|
init_shutdown();
|
|
50844
50855
|
init_logging();
|
|
50845
|
-
import { existsSync as
|
|
50846
|
-
import { join as
|
|
50856
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
50857
|
+
import { join as join41 } from "node:path";
|
|
50847
50858
|
process.on("uncaughtException", (error) => {
|
|
50848
50859
|
log.error("dev-child", `uncaught exception: ${error instanceof Error ? error.stack ?? error.message : error}`);
|
|
50849
50860
|
process.exit(1);
|
|
@@ -50881,9 +50892,9 @@ try {
|
|
|
50881
50892
|
["FRIZZ_SCRIPTS_DIR", process.env.FRIZZ_SCRIPTS_DIR, "index.mjs"],
|
|
50882
50893
|
["FRIZZ_WORKER_PLUGIN_DIR", process.env.FRIZZ_WORKER_PLUGIN_DIR, ".claude-plugin/plugin.json"]
|
|
50883
50894
|
];
|
|
50884
|
-
if (!
|
|
50895
|
+
if (!existsSync15(stableWebDist)) throw new Error("stable artifact launch is missing its verified web directory");
|
|
50885
50896
|
for (const [name, directory, requiredFile] of required) {
|
|
50886
|
-
if (!directory || !
|
|
50897
|
+
if (!directory || !existsSync15(join41(directory, requiredFile)))
|
|
50887
50898
|
throw new Error(`stable artifact launch is missing verified ${name}`);
|
|
50888
50899
|
}
|
|
50889
50900
|
}
|