frizz 0.4.0 → 0.5.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 +17 -0
- package/dist/dev-child.js +111 -28
- package/dist/frizz.js +107 -3
- package/package.json +1 -1
- package/runtime/cc-worker/bin/frizz-mcp.mjs +8 -0
- package/runtime/cc-worker/hooks/session-seed.mjs +1 -1
- package/web-dist/assets/{TerminalPane-sd3XXjx5.js → TerminalPane-WcpgmCA-.js} +1 -1
- package/web-dist/assets/{abnfDiagram-VRR7QNED-Bry_FIqg.js → abnfDiagram-VRR7QNED-Caecklbz.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-BTy2nvYL.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-Baok4OeI.js → architectureDiagram-ZJ3FMSHR-BEk0fg8C.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-BgHIO9lI.js → blockDiagram-677ZJIJ3-B4yq3xiy.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-rfj9Z17Z.js → c4Diagram-LMCZKHZV-DaA5NBkz.js} +1 -1
- package/web-dist/assets/channel-WghlT4VS.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-BwaHfK1Y.js → chunk-32BRIVSS-2XsSs8F_.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-BmdQDZOA.js → chunk-52WLFC77-DWJfECP3.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-ByQFjoZe.js → chunk-C7G6YPKG-Bz07eaGt.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-DQFudBKr.js → chunk-EX3LRPZG-D78kZEMM.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-OW9qEPiq.js → chunk-FWX5IMBZ-CeCa17CW.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-BdKLF8nO.js → chunk-HOUHSVGY-9H4GFuBa.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-C1roqKR1.js → chunk-ICXQ74PX--Aa17r4X.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-Cx0u1ZDK.js → chunk-MOJQB5TN-C3vXhsPV.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-rxv9xtNR.js → chunk-OGEWGWER-G4kZRBkX.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-BXWPPPPi.js → chunk-PUDLZKDR-DWd5kvyM.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-CpqbD101.js → chunk-Q4XR5HBZ-u55p39Up.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-CP8_3qVt.js → chunk-V7JOEXUC-BU4YBmV4.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-Dl7xahpk.js → chunk-VAUOI2AC-VXcmT20q.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-BKtMX64l.js → chunk-VR4S4FIN-CSjEXLOC.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-DmLOdJcu.js → chunk-WYO6CB5R-4WGk2dpL.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-5wN7eXvS.js → chunk-ZGVPDNZ5-D5Xl8ZV6.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-D21-Dy4r.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-D21-Dy4r.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-DUYahBXb.js → cynefin-VYW2F7L2-O6wB49wK.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-Rm0i30nE.js → cynefinDiagram-TSTJHNR4-pd6ZogNC.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-3uhsB-W3.js → dagre-VKFMJZFB-D8W1S6fw.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-BUvflNRQ.js → diagram-FQU43EPY-Bm1NOkHd.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-DUluIZel.js → diagram-G47NLZAW-CjwnXTIc.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-BBrwsbed.js → diagram-NH7WQ7WH-DH1jZ_mu.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-DWnTQBw4.js → diagram-OA4YK3LP-B-s969Q_.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-BjEavoC0.js → diagram-WEI45ONY-BU3lv6cL.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-CW4xZAZH.js → ebnfDiagram-CCIWWBDH-FsAeyqcC.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-BemQ1R4B.js → erDiagram-Q63AITRT-BRvg5Y9d.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-RhX2WA7g.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-C7N14tdV.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-lDdG5I_z.js → ganttDiagram-NO4QXBWP-eATKNh9U.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-Bw87a_Se.js → gitGraph-TEB2WS4Q-CNYqsua8.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-B762r0yi.js → gitGraphDiagram-IHSO6WYX-BUxgluf8.js} +1 -1
- package/web-dist/assets/{index-CAapfhMv.js → index-BFuReKr0.js} +75 -72
- package/web-dist/assets/index-BH9U3Zlg.css +1 -0
- package/web-dist/assets/{info-DKCQHKI2-DGOv6Gx0.js → info-DKCQHKI2-HsVLwo1c.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-DL92kAzf.js → infoDiagram-FWYZ7A6U-D7U65xDp.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-CFYd4OtU.js → ishikawaDiagram-FXEZZL3T-BsfIYXjX.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-QHuYL5zq.js → journeyDiagram-5HDEW3XC-CpkREKol.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-DwmMluQ8.js → kanban-definition-HUTT4EX6-2M3KW6Gw.js} +1 -1
- package/web-dist/assets/{line-Je_PFFHm.js → line-Cs7zWs24.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-BeiGWsn3.js → mermaid-parser.core-Dw-IECV5.js} +3 -3
- package/web-dist/assets/{mermaid.core-BP8JrW48.js → mermaid.core-C1lrddjT.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-BsmjCIrM.js → mindmap-definition-LN4V7U3C-gVS5On1g.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-D6ekYYGJ.js → packet-7NZHBO7P-Tti1-UWA.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-CQc2Kt0u.js → pegDiagram-2B236MQR-DE5in93G.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-C_45fO8J.js → pie-RZYD4A2V-DfLNkvHl.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-Dg5z6iWt.js → pieDiagram-ENE6RG2P-DcqSqJqb.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-c7gZxuCX.js → quadrantDiagram-ABIIQ3AL-DR-nRPgN.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-D80XNJQq.js → radar-I7S5WNFK-DGLDBfPd.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-Brz7eZQ0.js → railroad-3IZDKUUU-BaiGEHlV.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-BCeoIOWA.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-lZpXJLD8.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-CaUBrHTL.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-Db9K7bty.js → railroadDiagram-RFXS5EU6-82aEev5_.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-m1ipMrDe.js → requirementDiagram-TGXJPOKE-Bs8opBRj.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-4Zz9ry0k.js → sankeyDiagram-HTMAVEWB-gOb3FIr8.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-CZeGHw4X.js → sequenceDiagram-DBY2YBRQ-6DvjtRHR.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-rLUVs1Pg.js → stateDiagram-2N3HPSRC-Cg2LWdUf.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-Digf9CWZ.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-BAeBdscz.js → swimlanes-5IMT3BWC-BDpPdYEl.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-DEZRDWHA.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-DL0eWMF-.js → timeline-definition-FHXFAJF6-BSjfeutv.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-gEtzLMA8.js → treeView-QDETBFTQ-DwgPy6V3.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-CCym1Gz6.js → treemap-6X3UGDF4-7eiifTKW.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-cF97-nb5.js → vennDiagram-L72KCM5P-9u4AhcnV.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-DQJHCGbM.js → wardley-OPB4EBWU-DqNb5x9U.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-0CnHzXLX.js → wardleyDiagram-EHGQE667-DlJ7h3vg.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-9YDOp4m5.js → xychartDiagram-FW5EYKEG-B_9ukg2S.js} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/assets/architecture-TIHT7OUA-CoMJQ5Ya.js +0 -1
- package/web-dist/assets/channel-D6uS1y7I.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-BW5YiBf4.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-BW5YiBf4.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-BF5KB7ja.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-BYo4Eytx.js +0 -1
- package/web-dist/assets/index-B3QArXu2.css +0 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-D44pcGhJ.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-CiWVH5SP.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-Cy1B6-pN.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-w7QDFEvx.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-UhdgWpNZ.js +0 -8
package/README.md
CHANGED
|
@@ -122,6 +122,7 @@ $ npx frizz --help
|
|
|
122
122
|
Frizz production launcher
|
|
123
123
|
|
|
124
124
|
Usage: npx frizz [options] [repository]
|
|
125
|
+
npx frizz up serve this repo publicly, board + tunnel together
|
|
125
126
|
|
|
126
127
|
Runs the npm-resolved immutable Frizz package, then opens it in your default browser. Use frizz-dev
|
|
127
128
|
only for a source checkout.
|
|
@@ -276,6 +277,22 @@ Frizz has its own small vocabulary. Most of it names a feature, so this doubles
|
|
|
276
277
|
|
|
277
278
|
<br/>
|
|
278
279
|
|
|
280
|
+
<h2 align="center">Contributing</h2>
|
|
281
|
+
|
|
282
|
+
Issues and pull requests are welcome. Fork the repo, branch off `main`, and open the PR against `main` — CI runs on every pull request.
|
|
283
|
+
|
|
284
|
+
Three checks run in CI, and they need no install:
|
|
285
|
+
|
|
286
|
+
```sh
|
|
287
|
+
$ node --test board/*.test.mjs
|
|
288
|
+
$ node scripts/sync-portable-monitors.mjs --check
|
|
289
|
+
$ node --test monitors/*.test.mjs
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Everything else runs locally. Install with `pnpm install`, typecheck with `pnpm typecheck`, and run the full suite with `pnpm test` — that suite drives real agent CLIs and a real browser, which is why CI does not gate on it. Say in the PR what you ran.
|
|
293
|
+
|
|
294
|
+
<br/>
|
|
295
|
+
|
|
279
296
|
<h2 align="center">License</h2>
|
|
280
297
|
|
|
281
298
|
MIT
|
package/dist/dev-child.js
CHANGED
|
@@ -5751,7 +5751,7 @@ function parseGithubWakeSteer(text) {
|
|
|
5751
5751
|
function frizzRoute(path) {
|
|
5752
5752
|
return `${FRIZZ_ROUTE_PREFIX}${path.startsWith("/") ? path : `/${path}`}`;
|
|
5753
5753
|
}
|
|
5754
|
-
var 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, NativeInputRequired, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, RETIRED_AWAITING_REPLACEMENT, 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, 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, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PR_WATCH_MAX_ARMED, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, PlanView, 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, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, ConfirmAwaitingInput, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GITHUB_DISPATCH_UI_BOUNDARY, WAKE_DELIVERY_TOKEN_TAIL, WAKE_DELIVERY_TOKEN_LINE, AGENT_MESSAGE_WRAPPER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REVIEW_LEAD, WAKE_BACKLOG_TAIL, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, WAKE_ITEM, WAKE_MORE, 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;
|
|
5754
|
+
var 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, NativeInputRequired, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, RETIRED_AWAITING_REPLACEMENT, 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, 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, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PR_WATCH_MAX_ARMED, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, PlanView, 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, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, ConfirmAwaitingInput, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GITHUB_DISPATCH_UI_BOUNDARY, WAKE_DELIVERY_TOKEN_TAIL, WAKE_DELIVERY_TOKEN_LINE, 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;
|
|
5755
5755
|
var init_src = __esm({
|
|
5756
5756
|
"packages/shared/src/index.ts"() {
|
|
5757
5757
|
"use strict";
|
|
@@ -6113,7 +6113,9 @@ var init_src = __esm({
|
|
|
6113
6113
|
"**STILL OWED counts things you are not going to do yourself.** A decision you are RECOMMENDING, a",
|
|
6114
6114
|
"draft you wrote but did not send, follow-up work you discovered \u2014 all of it dies with the card, even",
|
|
6115
6115
|
"the part that is someone else's to do. Each ends on a question with your recommendation as option A,",
|
|
6116
|
-
"or
|
|
6116
|
+
"or you DO it first \u2014 a sub-agent's result comes BACK to you, so it lands on your card; a new card via",
|
|
6117
|
+
"`mcp__frizz__spawn_thread` is the LAST resort, since nothing it learns returns to you or its siblings.",
|
|
6118
|
+
"None of them is a `done`. And what is not",
|
|
6117
6119
|
'worth a card is not worth a SENTENCE: delete the dangling "one thing to carry forward", never park it',
|
|
6118
6120
|
"in the handoff.",
|
|
6119
6121
|
"",
|
|
@@ -6928,6 +6930,9 @@ ${DISPATCH_TASK_BANNER}
|
|
|
6928
6930
|
);
|
|
6929
6931
|
WAKE_ITEM = /^- (👤|🤖) (.+?) from @(\S+?)(?: at (\S+?))?(?:: (\S+))?$/;
|
|
6930
6932
|
WAKE_MORE = /^- …and (\d+) more not listed — check .+ for the rest$/;
|
|
6933
|
+
PR_WATCH_FINISHED = new RegExp(String.raw`^⏰ (${WAKE_REF}) was (MERGED|CLOSED)\.$`);
|
|
6934
|
+
PR_WATCH_CI_PASSED = new RegExp(String.raw`^✅ CI PASSED on (${WAKE_REF}) — (\d+) checks? green\.$`);
|
|
6935
|
+
PR_WATCH_CI_FAILED = new RegExp(String.raw`^❌ CI FAILED on (${WAKE_REF})(?:: (.+?))?\.$`);
|
|
6931
6936
|
GithubStatus = external_exports.object({
|
|
6932
6937
|
installed: external_exports.boolean(),
|
|
6933
6938
|
inRepo: external_exports.boolean(),
|
|
@@ -15240,7 +15245,9 @@ function createTailer(deps) {
|
|
|
15240
15245
|
for (const e of state.subAgents.values()) {
|
|
15241
15246
|
if (e.kind !== "shell") continue;
|
|
15242
15247
|
const lastActivityAt = entryLastActivity(e);
|
|
15243
|
-
|
|
15248
|
+
const since = Date.parse(lastActivityAt ?? e.startedAt);
|
|
15249
|
+
const shellState = Number.isFinite(since) && now() - since > BGSHELL_STALE_MS ? "stale" : "running";
|
|
15250
|
+
out.push({ label: e.label, startedAt: e.startedAt, state: shellState, id: e.toolUseId, ...e.taskId ? { stoppable: true, taskId: e.taskId } : {}, ...lastActivityAt ? { lastActivityAt } : {} });
|
|
15244
15251
|
}
|
|
15245
15252
|
return out;
|
|
15246
15253
|
}
|
|
@@ -16294,7 +16301,7 @@ function landsAfterRead(eventAt, lastReadAt) {
|
|
|
16294
16301
|
if (!Number.isFinite(e) || !Number.isFinite(r)) return true;
|
|
16295
16302
|
return e > r;
|
|
16296
16303
|
}
|
|
16297
|
-
var IDLE_BACKSTOP_MS, RUNTIME_CHASE_MAX, POLL_MS2, MAX_PRIME_ROWS_PER_TICK, PRIME_BUDGET_MS, TRANSCRIPT_READ_WINDOW, EMPTY_BUFFER, MAX_POLL_MS, SUBAGENT_STALE_MS, FOREIGN_FRESH_MS, FOREIGN_MAX, FOREIGN_SCAN_EVERY, CACHE_FLUSH_MS, PRIME_PROGRESS_EVERY, DISCOVER_RETRY_MS, DISCOVER_RETRY_MAX_MS, PERM_YES_OPTION, PERM_QUESTION, PERM_FOOTER, PERM_COMPOSER_FOOTER, PERM_MODAL_TAIL_ROWS, PERM_COMPOSER_TAIL_ROWS, BOOT_APIKEY_HEADLINE, BOOT_APIKEY_QUESTION, BOOT_TRUST_QUESTION, BOOT_TRUST_OPTION, BOOT_MODAL_TAIL_ROWS, RETAINED_SUBAGENTS_MAX, RETAINED_SHELLS_MAX, DESCENDANT_TERMINALS_MAX, PENDING_RESUMES_MAX, PENDING_SHELLS_MAX, RESUME_REPLAY_SLACK_MS, QUESTION_BLOCK_RE, SIGNAL_FENCE_RE, AWAITING_HINT_RE, FENCE_BODY_MAX, HINT_MAX, HINT_VALUE_MAX, LAUNCH_ACK_RE, AUTO_BACKGROUND_ACK_RE, DESCENDANT_SIDECAR_MAX, DESCENDANT_NOTIFY_GRACE_MS, MAX_OWNED_TOOL_USE_IDS, BROKER_LIVENESS_TTL_MS, UNRESTORED_TAIL_FIELDS;
|
|
16304
|
+
var IDLE_BACKSTOP_MS, RUNTIME_CHASE_MAX, POLL_MS2, MAX_PRIME_ROWS_PER_TICK, PRIME_BUDGET_MS, TRANSCRIPT_READ_WINDOW, EMPTY_BUFFER, MAX_POLL_MS, SUBAGENT_STALE_MS, BGSHELL_STALE_MS, FOREIGN_FRESH_MS, FOREIGN_MAX, FOREIGN_SCAN_EVERY, CACHE_FLUSH_MS, PRIME_PROGRESS_EVERY, DISCOVER_RETRY_MS, DISCOVER_RETRY_MAX_MS, PERM_YES_OPTION, PERM_QUESTION, PERM_FOOTER, PERM_COMPOSER_FOOTER, PERM_MODAL_TAIL_ROWS, PERM_COMPOSER_TAIL_ROWS, BOOT_APIKEY_HEADLINE, BOOT_APIKEY_QUESTION, BOOT_TRUST_QUESTION, BOOT_TRUST_OPTION, BOOT_MODAL_TAIL_ROWS, RETAINED_SUBAGENTS_MAX, RETAINED_SHELLS_MAX, DESCENDANT_TERMINALS_MAX, PENDING_RESUMES_MAX, PENDING_SHELLS_MAX, RESUME_REPLAY_SLACK_MS, QUESTION_BLOCK_RE, SIGNAL_FENCE_RE, AWAITING_HINT_RE, FENCE_BODY_MAX, HINT_MAX, HINT_VALUE_MAX, LAUNCH_ACK_RE, AUTO_BACKGROUND_ACK_RE, DESCENDANT_SIDECAR_MAX, DESCENDANT_NOTIFY_GRACE_MS, MAX_OWNED_TOOL_USE_IDS, BROKER_LIVENESS_TTL_MS, UNRESTORED_TAIL_FIELDS;
|
|
16298
16305
|
var init_tailer = __esm({
|
|
16299
16306
|
"packages/server/src/tailer.ts"() {
|
|
16300
16307
|
"use strict";
|
|
@@ -16323,6 +16330,7 @@ var init_tailer = __esm({
|
|
|
16323
16330
|
EMPTY_BUFFER = Buffer.alloc(0);
|
|
16324
16331
|
MAX_POLL_MS = 1e4;
|
|
16325
16332
|
SUBAGENT_STALE_MS = 15 * 6e4;
|
|
16333
|
+
BGSHELL_STALE_MS = 12 * 60 * 6e4;
|
|
16326
16334
|
FOREIGN_FRESH_MS = 24 * 60 * 6e4;
|
|
16327
16335
|
FOREIGN_MAX = 20;
|
|
16328
16336
|
FOREIGN_SCAN_EVERY = 5;
|
|
@@ -25485,15 +25493,26 @@ landed, a follow-up the change implies. \`done\` is barred \u2014 the finding di
|
|
|
25485
25493
|
is barred \u2014 nothing is running. \`question\` looks barred \u2014 the human asked nothing. **That deadlock is
|
|
25486
25494
|
not real, and stretching \`done\` is not how you break it.** Take the first exit that fits:
|
|
25487
25495
|
|
|
25488
|
-
1. **DO IT
|
|
25489
|
-
|
|
25490
|
-
|
|
25491
|
-
|
|
25492
|
-
|
|
25493
|
-
|
|
25494
|
-
|
|
25495
|
-
|
|
25496
|
-
was pending" is not an objection.
|
|
25496
|
+
1. **DO IT \u2014 the default, and it covers far more than "small".** Anything inside your change's own blast
|
|
25497
|
+
radius is exit 1: the fix your change implies, the test it needs, the breakage it revealed, the caller
|
|
25498
|
+
it left stale. **Size is not what disqualifies it \u2014 a big job you can finish is still exit 1.** If it
|
|
25499
|
+
is more than one sitting, dispatch an in-session SUB-AGENT: its result comes BACK to you, so the
|
|
25500
|
+
follow-up lands on YOUR card, in your diff, under one review. One thread that finished two things
|
|
25501
|
+
beats two threads that each finished one and never learned of the other. Then \`done\` is honest with
|
|
25502
|
+
nothing left over.
|
|
25503
|
+
2. **ASK** \u2014 the human should choose whether or how it happens. An ordinary \` \`\`\`question \`; "nothing
|
|
25504
|
+
was pending" is not an objection. This is the exit for work you cannot bound, cannot verify, or that
|
|
25505
|
+
is genuinely the human's call \u2014 and it is where a separable effort goes, as an OPTION they pick,
|
|
25506
|
+
rather than a card you create for them.
|
|
25507
|
+
3. **HAND IT OFF TO ITS OWN CARD \u2014 the LAST resort, not the tidy one.** \`mcp__frizz__spawn_thread\` puts
|
|
25508
|
+
a separable effort on the board as its own thread; put the returned \`[title](/thread/<slug>)\` link in
|
|
25509
|
+
the body. **A spawned thread is FIRE-AND-FORGET: it reports to the HUMAN, never to you, so nothing it
|
|
25510
|
+
learns can ever reach this effort or its siblings.** That is the whole cost, and it is not
|
|
25511
|
+
theoretical \u2014 one thread here spawned four, three of those spawned more, and three separate
|
|
25512
|
+
descendants independently rediscovered the SAME root-cause commit over twenty hours because none of
|
|
25513
|
+
them could tell the others. Reach for it only when the work genuinely cannot ride on your card: a
|
|
25514
|
+
different repo, a different long-lived runtime, an effort that must outlive yours. If a sub-agent
|
|
25515
|
+
could do it, exit 1. If the human should choose, exit 2. Never spawn merely to clear your own \`done\`.
|
|
25497
25516
|
4. **DROP IT** \u2014 it is not worth an effort, a card, or a question. Then it is not worth a SENTENCE
|
|
25498
25517
|
either: delete it. Do not park it in the handoff as "one thing to carry forward".
|
|
25499
25518
|
|
|
@@ -26000,10 +26019,12 @@ Give it a self-contained \`prompt\` and choose \`model\` + \`effort\` by the new
|
|
|
26000
26019
|
required). It returns a \`[title](/thread/<slug>)\` link \u2014 put that in your handoff so the human can open
|
|
26001
26020
|
it.
|
|
26002
26021
|
|
|
26003
|
-
**
|
|
26004
|
-
|
|
26005
|
-
and
|
|
26006
|
-
|
|
26022
|
+
**It is the LAST resort among the exits, never the tidy one.** A finding you turned up is not by itself a
|
|
26023
|
+
reason to spawn: the ordered exits put DOING it (with a sub-agent, whose result comes back to you) first
|
|
26024
|
+
and ASKING second, precisely because both keep the work reachable. A spawned thread does not \u2014 it reports
|
|
26025
|
+
to the HUMAN and nothing it learns returns to you or to its siblings, so a chain of them re-derives the
|
|
26026
|
+
same facts in parallel and nobody notices. Spawn only when the work genuinely cannot ride on your card,
|
|
26027
|
+
and never merely to clear your own \` \`\`\`done \`. See **When the work is finished but the thread found
|
|
26007
26028
|
more**.`;
|
|
26008
26029
|
THREAD_EXECUTION = {
|
|
26009
26030
|
claude: `## Thread types
|
|
@@ -29378,8 +29399,11 @@ function isShellFenceId(fenceId) {
|
|
|
29378
29399
|
function prWatchFenceId(watchId, report) {
|
|
29379
29400
|
return `${PR_WATCH_FENCE_PREFIX}:${watchId}:${report}`;
|
|
29380
29401
|
}
|
|
29402
|
+
function prWatchExpiredFenceId(watchId) {
|
|
29403
|
+
return `${PR_WATCH_EXPIRED_FENCE_PREFIX}:${watchId}`;
|
|
29404
|
+
}
|
|
29381
29405
|
function isPrWatchFenceId(fenceId) {
|
|
29382
|
-
return fenceId.startsWith(`${PR_WATCH_FENCE_PREFIX}:`);
|
|
29406
|
+
return fenceId.startsWith(`${PR_WATCH_FENCE_PREFIX}:`) || fenceId.startsWith(`${PR_WATCH_EXPIRED_FENCE_PREFIX}:`);
|
|
29383
29407
|
}
|
|
29384
29408
|
function signoffFenceId(restedAt) {
|
|
29385
29409
|
return `${SIGNOFF_FENCE_PREFIX}:${restedAt}`;
|
|
@@ -29387,6 +29411,16 @@ function signoffFenceId(restedAt) {
|
|
|
29387
29411
|
function isSignoffFenceId(fenceId) {
|
|
29388
29412
|
return fenceId.startsWith(`${SIGNOFF_FENCE_PREFIX}:`);
|
|
29389
29413
|
}
|
|
29414
|
+
function parkFenceId(cause, spokeAt) {
|
|
29415
|
+
return `${PARK_FENCE_PREFIX}:${cause}:${spokeAt}`;
|
|
29416
|
+
}
|
|
29417
|
+
function isParkFenceId(fenceId) {
|
|
29418
|
+
return fenceId.startsWith(`${PARK_FENCE_PREFIX}:`);
|
|
29419
|
+
}
|
|
29420
|
+
function parkFenceRestOf(fenceId) {
|
|
29421
|
+
const cut = fenceId.indexOf(":", PARK_FENCE_PREFIX.length + 1);
|
|
29422
|
+
return cut < 0 ? "" : fenceId.slice(cut + 1);
|
|
29423
|
+
}
|
|
29390
29424
|
function timerFenceId(timerId) {
|
|
29391
29425
|
return `${TIMER_FENCE_PREFIX}:${timerId}`;
|
|
29392
29426
|
}
|
|
@@ -29670,6 +29704,14 @@ function createScheduler(deps) {
|
|
|
29670
29704
|
if (!stillMissing) return "superseded";
|
|
29671
29705
|
return tele.turn === "idle" ? "current-idle" : "current-busy";
|
|
29672
29706
|
}
|
|
29707
|
+
if (isParkFenceId(item.fenceId)) {
|
|
29708
|
+
if (parkFenceRestOf(item.fenceId) !== (tele.lastAssistantAt ?? "")) return "superseded";
|
|
29709
|
+
return tele.turn === "idle" ? "current-idle" : "current-busy";
|
|
29710
|
+
}
|
|
29711
|
+
if (!item.fenceId.includes("")) {
|
|
29712
|
+
log3(`waker: UNROUTED wake prefix ${item.fenceId.split(":")[0]} for ${item.slug} \u2014 no deliveryContext branch, superseding`);
|
|
29713
|
+
return "superseded";
|
|
29714
|
+
}
|
|
29673
29715
|
const fence = tele.lastFence;
|
|
29674
29716
|
if (!fence || fence.kind !== "awaiting" || !fence.hints.some(isActionable)) return "superseded";
|
|
29675
29717
|
if (fenceIdentity(fence.hints, tele.lastActivityAt) !== item.fenceId) return "superseded";
|
|
@@ -30135,7 +30177,7 @@ You have NOTHING running right now \u2014 no shell, no sub-agent, no timer, no r
|
|
|
30135
30177
|
pull request. There is nothing that could wake you, so this thread is not awaiting: finish in
|
|
30136
30178
|
\`\`\`done, or ask a \`\`\`question.`;
|
|
30137
30179
|
if (cause !== "expired" && (row.park_bumps ?? 0) >= PARK_BUMP_MAX) continue;
|
|
30138
|
-
const fenceId =
|
|
30180
|
+
const fenceId = parkFenceId(cause, spokeAt);
|
|
30139
30181
|
const deliveryId = wakeDeliveryId(row.slug, row.session_id, fenceId);
|
|
30140
30182
|
if (outbox.get(deliveryId)) continue;
|
|
30141
30183
|
const item = outbox.enqueue({
|
|
@@ -30170,7 +30212,7 @@ pull request. There is nothing that could wake you, so this thread is not awaiti
|
|
|
30170
30212
|
const ref = `${w.owner}/${w.repo}#${w.number}`;
|
|
30171
30213
|
log3(`waker: settled ${w.thread_slug} \u2014 pr watcher ${w.id} expired (${ref})`);
|
|
30172
30214
|
if (!row || row.state === "archived" || row.archived === 1) continue;
|
|
30173
|
-
const fenceId =
|
|
30215
|
+
const fenceId = prWatchExpiredFenceId(w.id);
|
|
30174
30216
|
const deliveryId = wakeDeliveryId(row.slug, row.session_id, fenceId);
|
|
30175
30217
|
if (outbox.get(deliveryId)) continue;
|
|
30176
30218
|
const item = outbox.enqueue({
|
|
@@ -30178,7 +30220,7 @@ pull request. There is nothing that could wake you, so this thread is not awaiti
|
|
|
30178
30220
|
slug: row.slug,
|
|
30179
30221
|
sessionId: row.session_id,
|
|
30180
30222
|
fenceId,
|
|
30181
|
-
hintKey:
|
|
30223
|
+
hintKey: fenceId,
|
|
30182
30224
|
message: `\u23F0 Your watcher on ${ref} has expired and is no longer armed \u2014 nothing on that PR will wake you now.
|
|
30183
30225
|
|
|
30184
30226
|
If you still care about it, register it again with \`mcp__frizz__watch_pr\` and a fresh \`for:\`. If you do not, and it was the only thing you were waiting on, end in a proper terminal state instead of parking on it again.`,
|
|
@@ -30715,7 +30757,7 @@ If you still care about it, register it again with \`mcp__frizz__watch_pr\` and
|
|
|
30715
30757
|
tick
|
|
30716
30758
|
};
|
|
30717
30759
|
}
|
|
30718
|
-
var execFileAsync4, PR_REF_RE2, LIMIT_FENCE_PREFIX, LIMIT_HINT_PREFIX, LIMIT_RESUME_GRACE_MS, LIMIT_RESUME_HEADROOM_PERCENT, LIMIT_HEADROOM_MIN_FAULT_AGE_MS, REPORT_FENCE_PREFIX, REPORT_HINT_PREFIX, SNOOZE_FENCE_PREFIX, SNOOZE_HINT_PREFIX, HEARTBEAT_FENCE_PREFIX, HEARTBEAT_HINT_PREFIX, STOP_HOOK_FENCE_PREFIX, STOP_HOOK_HINT_KEY, COMPACT_FENCE_PREFIX, COMPACT_HINT_KEY, TIMER_FENCE_PREFIX, TIMER_HINT_PREFIX, SHELL_FENCE_PREFIX, PR_WATCH_FENCE_PREFIX, PR_WATCH_POLL_MS, SIGNOFF_FENCE_PREFIX, SIGNOFF_HINT_KEY, SIGNOFF_NUDGE_MAX, PARK_BUMP_MAX, SIGNOFF_NUDGE_SETTING, FIRED_CAP, GITHUB_STATUS_CAP, REGISTRATION_CAP, REVIEW_SEEN_CAP, INTRODUCED_CAP, REVIEW_STEER_CAP;
|
|
30760
|
+
var execFileAsync4, PR_REF_RE2, LIMIT_FENCE_PREFIX, LIMIT_HINT_PREFIX, LIMIT_RESUME_GRACE_MS, LIMIT_RESUME_HEADROOM_PERCENT, LIMIT_HEADROOM_MIN_FAULT_AGE_MS, REPORT_FENCE_PREFIX, REPORT_HINT_PREFIX, SNOOZE_FENCE_PREFIX, SNOOZE_HINT_PREFIX, HEARTBEAT_FENCE_PREFIX, HEARTBEAT_HINT_PREFIX, STOP_HOOK_FENCE_PREFIX, STOP_HOOK_HINT_KEY, COMPACT_FENCE_PREFIX, COMPACT_HINT_KEY, TIMER_FENCE_PREFIX, TIMER_HINT_PREFIX, SHELL_FENCE_PREFIX, PR_WATCH_FENCE_PREFIX, PR_WATCH_EXPIRED_FENCE_PREFIX, PR_WATCH_POLL_MS, SIGNOFF_FENCE_PREFIX, SIGNOFF_HINT_KEY, SIGNOFF_NUDGE_MAX, PARK_BUMP_MAX, SIGNOFF_NUDGE_SETTING, PARK_FENCE_PREFIX, FIRED_CAP, GITHUB_STATUS_CAP, REGISTRATION_CAP, REVIEW_SEEN_CAP, INTRODUCED_CAP, REVIEW_STEER_CAP;
|
|
30719
30761
|
var init_scheduler = __esm({
|
|
30720
30762
|
"packages/server/src/scheduler.ts"() {
|
|
30721
30763
|
"use strict";
|
|
@@ -30749,12 +30791,14 @@ var init_scheduler = __esm({
|
|
|
30749
30791
|
TIMER_HINT_PREFIX = "timer:";
|
|
30750
30792
|
SHELL_FENCE_PREFIX = "shell";
|
|
30751
30793
|
PR_WATCH_FENCE_PREFIX = "prwatch";
|
|
30794
|
+
PR_WATCH_EXPIRED_FENCE_PREFIX = "prwatch-expired";
|
|
30752
30795
|
PR_WATCH_POLL_MS = 6e4;
|
|
30753
30796
|
SIGNOFF_FENCE_PREFIX = "signoff";
|
|
30754
30797
|
SIGNOFF_HINT_KEY = "signoff:rest";
|
|
30755
30798
|
SIGNOFF_NUDGE_MAX = 2;
|
|
30756
30799
|
PARK_BUMP_MAX = 3;
|
|
30757
30800
|
SIGNOFF_NUDGE_SETTING = "signoffNudge";
|
|
30801
|
+
PARK_FENCE_PREFIX = "park";
|
|
30758
30802
|
FIRED_CAP = 500;
|
|
30759
30803
|
GITHUB_STATUS_CAP = 200;
|
|
30760
30804
|
REGISTRATION_CAP = 500;
|
|
@@ -34981,6 +35025,7 @@ function createTranscriptFold(identityPrefix = "claude") {
|
|
|
34981
35025
|
const pendingTools = /* @__PURE__ */ new Map();
|
|
34982
35026
|
const agentDispatches = /* @__PURE__ */ new Map();
|
|
34983
35027
|
const backgroundShells = /* @__PURE__ */ new Map();
|
|
35028
|
+
const consumedShells = /* @__PURE__ */ new Map();
|
|
34984
35029
|
const backgroundTaskIds = /* @__PURE__ */ new Map();
|
|
34985
35030
|
const relayedWakesDrawn = /* @__PURE__ */ new Set();
|
|
34986
35031
|
const childDispatchIds = /* @__PURE__ */ new Map();
|
|
@@ -34988,9 +35033,11 @@ function createTranscriptFold(identityPrefix = "claude") {
|
|
|
34988
35033
|
const queuedPending = [];
|
|
34989
35034
|
let deliveredDedupe = null;
|
|
34990
35035
|
let pendingRest = null;
|
|
35036
|
+
const restEpoch = { n: 0 };
|
|
34991
35037
|
function flushRest() {
|
|
34992
35038
|
if (!pendingRest) return;
|
|
34993
35039
|
out.push(restMessage(pendingRest.sourceId, pendingRest.at));
|
|
35040
|
+
restEpoch.n++;
|
|
34994
35041
|
pendingRest = null;
|
|
34995
35042
|
lastAssistantId = null;
|
|
34996
35043
|
}
|
|
@@ -35034,7 +35081,7 @@ function createTranscriptFold(identityPrefix = "claude") {
|
|
|
35034
35081
|
if (pendingRest && !(rec.type === "assistant" && typeof rec.message?.id === "string" && rec.message.id === pendingRest.msgId)) {
|
|
35035
35082
|
flushRest();
|
|
35036
35083
|
}
|
|
35037
|
-
const evs = completionEvents(rec, agentDispatches, backgroundShells, backgroundTaskIds, relayedWakesDrawn);
|
|
35084
|
+
const evs = completionEvents(rec, agentDispatches, backgroundShells, backgroundTaskIds, relayedWakesDrawn, consumedShells, restEpoch);
|
|
35038
35085
|
let drewEvents = false;
|
|
35039
35086
|
if (evs.length > 0) {
|
|
35040
35087
|
attachToolResults(rec, pendingTools, backgroundShells, backgroundTaskIds, childDispatchIds);
|
|
@@ -35283,9 +35330,14 @@ ${block.text}` : block.text;
|
|
|
35283
35330
|
return {
|
|
35284
35331
|
ingest,
|
|
35285
35332
|
finalize,
|
|
35333
|
+
// The SAME window the paged reader returns (latestWindowStart), because this is the OTHER producer:
|
|
35334
|
+
// the /ws push renders from here while the RPC page renders from there, and a push whose head sat
|
|
35335
|
+
// further forward than the page's would splice the human's ask straight back out of a card that had
|
|
35336
|
+
// just anchored on it (reconcileLiveMessages replaces the window wholesale).
|
|
35286
35337
|
messages: () => {
|
|
35287
35338
|
const all = projected();
|
|
35288
|
-
|
|
35339
|
+
const start = latestWindowStart(all);
|
|
35340
|
+
return start === 0 ? all : all.slice(start);
|
|
35289
35341
|
},
|
|
35290
35342
|
allMessages: projected,
|
|
35291
35343
|
consumedBytes: () => offset + Buffer.byteLength(buffer)
|
|
@@ -35715,7 +35767,7 @@ function notificationCarrierText(rec) {
|
|
|
35715
35767
|
}
|
|
35716
35768
|
return void 0;
|
|
35717
35769
|
}
|
|
35718
|
-
function completionEvents(rec, dispatches, backgroundShells, backgroundTaskIds, relayedWakesDrawn) {
|
|
35770
|
+
function completionEvents(rec, dispatches, backgroundShells, backgroundTaskIds, relayedWakesDrawn, consumedShells = /* @__PURE__ */ new Map(), restEpoch = { n: 0 }) {
|
|
35719
35771
|
const carrier = notificationCarrierText(rec);
|
|
35720
35772
|
const raw2 = carrier === void 0 ? void 0 : splitWakeDeliveries(carrier).map((s) => relayNotificationBlock(s) ?? s).join("\n");
|
|
35721
35773
|
if (!raw2 || !raw2.includes("<task-notification>")) return [];
|
|
@@ -35749,10 +35801,17 @@ function completionEvents(rec, dispatches, backgroundShells, backgroundTaskIds,
|
|
|
35749
35801
|
if (!d) {
|
|
35750
35802
|
const shell = backgroundShells.get(id);
|
|
35751
35803
|
if (!shell) {
|
|
35804
|
+
const drawn = consumedShells.get(id);
|
|
35805
|
+
if (drawn && restEpoch.n > drawn.epoch) {
|
|
35806
|
+
consumedShells.set(id, { epoch: restEpoch.n, call: drawn.call });
|
|
35807
|
+
out.push({ role: "assistant", kind: "event", boundary: "wake", text: backgroundWakeLabel(drawn.call, status, block), tools: [], parts: [], at });
|
|
35808
|
+
continue;
|
|
35809
|
+
}
|
|
35752
35810
|
relayedFallback();
|
|
35753
35811
|
continue;
|
|
35754
35812
|
}
|
|
35755
35813
|
backgroundShells.delete(id);
|
|
35814
|
+
consumedShells.set(id, { epoch: restEpoch.n, call: shell.call });
|
|
35756
35815
|
const elapsedMs2 = elapsedBetween(shell.at, rec.timestamp);
|
|
35757
35816
|
shell.call.status = status === "completed" ? "completed" : status === "killed" ? "cancelled" : "failed";
|
|
35758
35817
|
if (elapsedMs2 !== void 0) shell.call.durationMs = elapsedMs2;
|
|
@@ -36108,8 +36167,30 @@ function parseCodexTranscript(raw2, identityPrefix = "codex") {
|
|
|
36108
36167
|
const out = projectCodexTranscript(raw2, identityPrefix);
|
|
36109
36168
|
return latestTranscriptWindow(out);
|
|
36110
36169
|
}
|
|
36170
|
+
function latestWindowStart(messages) {
|
|
36171
|
+
const tail = Math.max(0, messages.length - MAX_MESSAGES);
|
|
36172
|
+
if (tail === 0) return 0;
|
|
36173
|
+
let boundary = -1;
|
|
36174
|
+
for (let i = tail - 1; i >= 0; i--) {
|
|
36175
|
+
const m = messages[i];
|
|
36176
|
+
if (m.role === "user" && !m.wake && !m.queued) {
|
|
36177
|
+
boundary = i;
|
|
36178
|
+
break;
|
|
36179
|
+
}
|
|
36180
|
+
}
|
|
36181
|
+
if (boundary < 0) return tail;
|
|
36182
|
+
let start = tail;
|
|
36183
|
+
let bytes = 0;
|
|
36184
|
+
while (start > boundary && tail - start < LATEST_WINDOW_ASK_REACH_ITEMS) {
|
|
36185
|
+
const nextBytes = messageBytes(messages[start - 1]);
|
|
36186
|
+
if (bytes + nextBytes > LATEST_WINDOW_ASK_REACH_BYTES) break;
|
|
36187
|
+
start--;
|
|
36188
|
+
bytes += nextBytes;
|
|
36189
|
+
}
|
|
36190
|
+
return start === boundary ? start : tail;
|
|
36191
|
+
}
|
|
36111
36192
|
function latestTranscriptWindow(messages) {
|
|
36112
|
-
const start =
|
|
36193
|
+
const start = latestWindowStart(messages);
|
|
36113
36194
|
if (start === 0) return [...messages];
|
|
36114
36195
|
const pinned = [];
|
|
36115
36196
|
for (let i = 0; i < start; i++) {
|
|
@@ -37002,7 +37083,7 @@ function readLatestThreadTranscriptPage(project, storage, slug, backendFor) {
|
|
|
37002
37083
|
}
|
|
37003
37084
|
}
|
|
37004
37085
|
const latest = latestTranscriptWindow(projected);
|
|
37005
|
-
const canonicalStart =
|
|
37086
|
+
const canonicalStart = latestWindowStart(projected);
|
|
37006
37087
|
const row = storage.getSession(slug);
|
|
37007
37088
|
const pageMessages = row ? projectDeliveryLedger(latest, parseDeliveryLedger(row.delivery_ledger)) : latest;
|
|
37008
37089
|
return {
|
|
@@ -37143,7 +37224,7 @@ function readTranscriptFile(absPath) {
|
|
|
37143
37224
|
return [];
|
|
37144
37225
|
}
|
|
37145
37226
|
}
|
|
37146
|
-
var MAX_MESSAGES, NOISE_PREFIXES, INTERRUPT_MARKERS, REST_LABEL, LEGACY_TASK_MARKER, LEGACY_BANNER_PREAMBLE, COMMAND_NAME_RE, COMMAND_ARGS_RE, PEER_SESSION_PREAMBLE, QUEUED_STALE_MS, EDIT_CAP, TRUNC_MARKER, ENCRYPTED_PAYLOAD, AGENT_PROMPT_CAP, SEND_BODY_CAP, COMMAND_CAP, TOOL_INPUT_CAP, READ_LINE_CAP, READ_BYTE_CAP, IMAGE_MEDIA_EXT, SCREENSHOT_CACHE_DIR, SCREENSHOT_CACHE_MAX, SCREENSHOT_MAX_BASE64, screenshotTmpSeq, SENT_IMAGE_MAX_BYTES, SENT_FILES_MAX, TODO_ROWS_MAX, TODO_TEXT_CAP, TRANSCRIPT_CACHE_CAP, transcriptCache, PARSE_VERIFY_SAMPLE, TRANSCRIPT_DECODE_WINDOW, FOREIGN_SESSION_ID_RE, MAX_PINNED_BACKGROUND_OPERATIONS, CAPTION_MAX, _defaultCodexBackend, TRANSCRIPT_EARLIER_MAX_ITEMS, TRANSCRIPT_EARLIER_MAX_BYTES, fullDigestCache, FULL_DIGEST_CACHE_CAP, EMPTY_RETIRED_OPS;
|
|
37227
|
+
var MAX_MESSAGES, LATEST_WINDOW_ASK_REACH_ITEMS, LATEST_WINDOW_ASK_REACH_BYTES, NOISE_PREFIXES, INTERRUPT_MARKERS, REST_LABEL, LEGACY_TASK_MARKER, LEGACY_BANNER_PREAMBLE, COMMAND_NAME_RE, COMMAND_ARGS_RE, PEER_SESSION_PREAMBLE, QUEUED_STALE_MS, EDIT_CAP, TRUNC_MARKER, ENCRYPTED_PAYLOAD, AGENT_PROMPT_CAP, SEND_BODY_CAP, COMMAND_CAP, TOOL_INPUT_CAP, READ_LINE_CAP, READ_BYTE_CAP, IMAGE_MEDIA_EXT, SCREENSHOT_CACHE_DIR, SCREENSHOT_CACHE_MAX, SCREENSHOT_MAX_BASE64, screenshotTmpSeq, SENT_IMAGE_MAX_BYTES, SENT_FILES_MAX, TODO_ROWS_MAX, TODO_TEXT_CAP, TRANSCRIPT_CACHE_CAP, transcriptCache, PARSE_VERIFY_SAMPLE, TRANSCRIPT_DECODE_WINDOW, FOREIGN_SESSION_ID_RE, MAX_PINNED_BACKGROUND_OPERATIONS, CAPTION_MAX, _defaultCodexBackend, TRANSCRIPT_EARLIER_MAX_ITEMS, TRANSCRIPT_EARLIER_MAX_BYTES, fullDigestCache, FULL_DIGEST_CACHE_CAP, EMPTY_RETIRED_OPS;
|
|
37147
37228
|
var init_transcript = __esm({
|
|
37148
37229
|
"packages/server/src/transcript.ts"() {
|
|
37149
37230
|
"use strict";
|
|
@@ -37158,6 +37239,8 @@ var init_transcript = __esm({
|
|
|
37158
37239
|
init_bash_background();
|
|
37159
37240
|
init_frizz_paths();
|
|
37160
37241
|
MAX_MESSAGES = 300;
|
|
37242
|
+
LATEST_WINDOW_ASK_REACH_ITEMS = 100;
|
|
37243
|
+
LATEST_WINDOW_ASK_REACH_BYTES = 512 * 1024;
|
|
37161
37244
|
NOISE_PREFIXES = ["<task-notification>", "[SYSTEM NOTIFICATION", "<system-reminder>", "<frizz-", "[frizz]"];
|
|
37162
37245
|
INTERRUPT_MARKERS = ["[Request interrupted by user]", "[Request interrupted by user for tool use]"];
|
|
37163
37246
|
REST_LABEL = "Agent rested";
|
package/dist/frizz.js
CHANGED
|
@@ -6275,7 +6275,7 @@ var init_receipt_bus = __esm({
|
|
|
6275
6275
|
function fallbackPort(base) {
|
|
6276
6276
|
return base + 1e4;
|
|
6277
6277
|
}
|
|
6278
|
-
var 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, NativeInputRequired, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TimerPromptText, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, PlanView, 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, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, ConfirmAwaitingInput, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketClientMsg, ProjectCard, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT;
|
|
6278
|
+
var 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, NativeInputRequired, AwaitingHint, RETIRED_AWAITING_KINDS, RETIRED_LINE_RE, AWAITING_FOR_MAX_MS, SnoozeUntil, SNOOZE_PROMPT_MAX, SnoozePrompt, RECURRING_PROMPT_MAX, RECURRING_MIN_INTERVAL_SECONDS, RECURRING_MAX_INTERVAL_SECONDS, RecurringPromptText, RecurringIntervalSeconds, ThreadRecurringPrompt, TIMER_PROMPT_MAX, TIMER_MAX_DELAY_SECONDS, TimerPromptText, SIGNOFF_NUDGE_MARKER, SIGNOFF_NUDGE_MESSAGE, ThreadWatchKind, GithubChecksState, GithubMergeState, GithubWatchStatus, ThreadWatchView, PR_WATCH_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, PlanView, 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, FollowUpInput, UnqueueFollowUpInput, UnqueueFollowUpResult, DeliverQueuedNowInput, DeliverQueuedNowResult, SetThreadSnoozeInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, ConfirmAwaitingInput, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, 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_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT;
|
|
6279
6279
|
var init_src = __esm({
|
|
6280
6280
|
"packages/shared/src/index.ts"() {
|
|
6281
6281
|
"use strict";
|
|
@@ -6623,7 +6623,9 @@ var init_src = __esm({
|
|
|
6623
6623
|
"**STILL OWED counts things you are not going to do yourself.** A decision you are RECOMMENDING, a",
|
|
6624
6624
|
"draft you wrote but did not send, follow-up work you discovered \u2014 all of it dies with the card, even",
|
|
6625
6625
|
"the part that is someone else's to do. Each ends on a question with your recommendation as option A,",
|
|
6626
|
-
"or
|
|
6626
|
+
"or you DO it first \u2014 a sub-agent's result comes BACK to you, so it lands on your card; a new card via",
|
|
6627
|
+
"`mcp__frizz__spawn_thread` is the LAST resort, since nothing it learns returns to you or its siblings.",
|
|
6628
|
+
"None of them is a `done`. And what is not",
|
|
6627
6629
|
'worth a card is not worth a SENTENCE: delete the dangling "one thing to carry forward", never park it',
|
|
6628
6630
|
"in the handoff.",
|
|
6629
6631
|
"",
|
|
@@ -7429,6 +7431,9 @@ ${DISPATCH_TASK_BANNER}
|
|
|
7429
7431
|
WAKE_MULTI_HEAD = new RegExp(
|
|
7430
7432
|
String.raw`^(👤|🤖) (\d+) new GitHub items on (${WAKE_REF})\. Read exactly these — ` + WAKE_SCOPE + String.raw` — and continue:$`
|
|
7431
7433
|
);
|
|
7434
|
+
PR_WATCH_FINISHED = new RegExp(String.raw`^⏰ (${WAKE_REF}) was (MERGED|CLOSED)\.$`);
|
|
7435
|
+
PR_WATCH_CI_PASSED = new RegExp(String.raw`^✅ CI PASSED on (${WAKE_REF}) — (\d+) checks? green\.$`);
|
|
7436
|
+
PR_WATCH_CI_FAILED = new RegExp(String.raw`^❌ CI FAILED on (${WAKE_REF})(?:: (.+?))?\.$`);
|
|
7432
7437
|
GithubStatus = external_exports.object({
|
|
7433
7438
|
installed: external_exports.boolean(),
|
|
7434
7439
|
inRepo: external_exports.boolean(),
|
|
@@ -8609,6 +8614,10 @@ var ANSI = {
|
|
|
8609
8614
|
cyan: "\x1B[36m",
|
|
8610
8615
|
red: "\x1B[31m"
|
|
8611
8616
|
};
|
|
8617
|
+
function clockTime(ms) {
|
|
8618
|
+
const at = new Date(ms);
|
|
8619
|
+
return [at.getHours(), at.getMinutes(), at.getSeconds()].map((part) => String(part).padStart(2, "0")).join(":");
|
|
8620
|
+
}
|
|
8612
8621
|
function formatDuration(ms) {
|
|
8613
8622
|
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
8614
8623
|
if (ms < 1e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
@@ -8636,6 +8645,8 @@ var Readout = class {
|
|
|
8636
8645
|
settled = false;
|
|
8637
8646
|
/** Non-TTY only: suppress repeating an identical status row. */
|
|
8638
8647
|
lastPlainLine = "";
|
|
8648
|
+
/** Has a post-boot notice printed yet? The first one leads with a blank line, the rest stack. */
|
|
8649
|
+
noticed = false;
|
|
8639
8650
|
constructor(options2 = {}) {
|
|
8640
8651
|
this.out = options2.output ?? process.stdout;
|
|
8641
8652
|
this.tty = this.out.isTTY === true;
|
|
@@ -8765,8 +8776,33 @@ ${SYNC_END}`);
|
|
|
8765
8776
|
this.out.write(`${line}
|
|
8766
8777
|
`);
|
|
8767
8778
|
}
|
|
8779
|
+
/**
|
|
8780
|
+
* A lifecycle line printed AFTER the ready block — the board restarting, updating, or falling over.
|
|
8781
|
+
*
|
|
8782
|
+
* The block above it is a snapshot of one moment; these are a timeline, and they arrive minutes or
|
|
8783
|
+
* hours later because somebody clicked Restart in a browser or a control-plane child crashed. So
|
|
8784
|
+
* this row carries a wall-clock time, which no other row here does: without one, a beat found on
|
|
8785
|
+
* a scrolled-back terminal says what happened and gives no way to tell when.
|
|
8786
|
+
*/
|
|
8787
|
+
notice(tone, label, detail) {
|
|
8788
|
+
const glyph = tone === "done" ? this.c(ANSI.green, "\u2713") : tone === "failed" ? this.c(ANSI.red, "\u2717") : this.c(ANSI.cyan, "\u21BB");
|
|
8789
|
+
if (!this.tty || this.debug) {
|
|
8790
|
+
this.out.write(`frizz: ${label.toLowerCase()}${detail ? ` \u2014 ${detail}` : ""}
|
|
8791
|
+
`);
|
|
8792
|
+
return;
|
|
8793
|
+
}
|
|
8794
|
+
const lead = this.noticed ? "" : "\n";
|
|
8795
|
+
this.noticed = true;
|
|
8796
|
+
const time = this.c(ANSI.dim, clockTime(this.now()));
|
|
8797
|
+
const tail = detail ? this.c(ANSI.dim, detail) : "";
|
|
8798
|
+
this.write(`${lead} ${glyph} ${time} ${tail ? label.padEnd(12) : label}${tail}`);
|
|
8799
|
+
}
|
|
8768
8800
|
/** Print a line without disturbing the repaint region (used for the debug feed and warnings). */
|
|
8769
8801
|
note(line) {
|
|
8802
|
+
this.write(line);
|
|
8803
|
+
}
|
|
8804
|
+
/** Put one line on screen, above the repaint region if there still is one. */
|
|
8805
|
+
write(line) {
|
|
8770
8806
|
if (this.settled || !this.tty || this.debug) {
|
|
8771
8807
|
this.out.write(`${line}
|
|
8772
8808
|
`);
|
|
@@ -8880,6 +8916,19 @@ function sliceVisible(line, limit) {
|
|
|
8880
8916
|
}
|
|
8881
8917
|
return `${out}${ANSI.reset}`;
|
|
8882
8918
|
}
|
|
8919
|
+
function renderSupervisorActivity(readout2, event) {
|
|
8920
|
+
if (!readout2) return;
|
|
8921
|
+
switch (event.kind) {
|
|
8922
|
+
case "restarting":
|
|
8923
|
+
return readout2.notice("progress", "Restarting", event.message);
|
|
8924
|
+
case "updating":
|
|
8925
|
+
return readout2.notice("progress", "Updating", event.message);
|
|
8926
|
+
case "ready":
|
|
8927
|
+
return readout2.notice("done", "Restarted", event.ms === void 0 ? event.message : `in ${formatDuration(event.ms)}`);
|
|
8928
|
+
case "failed":
|
|
8929
|
+
return readout2.notice("failed", "Failed", event.message);
|
|
8930
|
+
}
|
|
8931
|
+
}
|
|
8883
8932
|
|
|
8884
8933
|
// src/production.ts
|
|
8885
8934
|
init_logging();
|
|
@@ -8991,6 +9040,7 @@ function parseCliArgs(argv) {
|
|
|
8991
9040
|
"--stop",
|
|
8992
9041
|
"--status",
|
|
8993
9042
|
"--link",
|
|
9043
|
+
"--cloud",
|
|
8994
9044
|
"--help",
|
|
8995
9045
|
"-h",
|
|
8996
9046
|
"--dev",
|
|
@@ -9023,6 +9073,7 @@ function parseCliArgs(argv) {
|
|
|
9023
9073
|
foreground: true,
|
|
9024
9074
|
stop: args2.has("--stop"),
|
|
9025
9075
|
link: args2.has("--link"),
|
|
9076
|
+
cloud: args2.has("--cloud"),
|
|
9026
9077
|
status: args2.has("--status"),
|
|
9027
9078
|
help: args2.has("--help") || args2.has("-h"),
|
|
9028
9079
|
dev: args2.has("--dev"),
|
|
@@ -10123,6 +10174,13 @@ var Supervisor = class {
|
|
|
10123
10174
|
launchTarget;
|
|
10124
10175
|
logLine;
|
|
10125
10176
|
errorLine;
|
|
10177
|
+
onActivity;
|
|
10178
|
+
/** Suppresses activity beats until the first boot has settled; until then the readout owns the terminal. */
|
|
10179
|
+
booted = false;
|
|
10180
|
+
/** When the restart currently in flight began, so its "ready" beat can report a duration. */
|
|
10181
|
+
restartStartedAt;
|
|
10182
|
+
/** Last beat emitted, so a transition reported twice is printed once. */
|
|
10183
|
+
lastActivity;
|
|
10126
10184
|
publicProxy;
|
|
10127
10185
|
updateRestart;
|
|
10128
10186
|
rollbackUpdate;
|
|
@@ -10156,6 +10214,7 @@ var Supervisor = class {
|
|
|
10156
10214
|
this.ownerToken = opts.launchOwnerToken;
|
|
10157
10215
|
this.logLine = opts.log ?? ((line) => log.info("supervisor", stripPrefix(line)));
|
|
10158
10216
|
this.errorLine = opts.error ?? ((line) => log.error("supervisor", stripPrefix(line)));
|
|
10217
|
+
this.onActivity = opts.onActivity;
|
|
10159
10218
|
this.updateRestart = opts.updateRestart;
|
|
10160
10219
|
this.rollbackUpdate = opts.rollbackUpdate;
|
|
10161
10220
|
this.durableReexec = opts.durableReexec;
|
|
@@ -10323,8 +10382,13 @@ var Supervisor = class {
|
|
|
10323
10382
|
}
|
|
10324
10383
|
async updateFromBrowser() {
|
|
10325
10384
|
if (!this.updateRestart) return { state: "failed", message: "Update & Restart is unavailable in this launcher mode" };
|
|
10385
|
+
this.emitActivity("updating", "preparing the new build \u2014 the running one is untouched until it is ready");
|
|
10326
10386
|
const candidate = await this.updateRestart();
|
|
10327
|
-
if (candidate.state !== "ready")
|
|
10387
|
+
if (candidate.state !== "ready") {
|
|
10388
|
+
this.emitActivity("failed", candidate.message ?? "the update could not be prepared");
|
|
10389
|
+
return candidate;
|
|
10390
|
+
}
|
|
10391
|
+
if (candidate.message) this.emitActivity("updating", candidate.message);
|
|
10328
10392
|
if (!this.durableReexec) {
|
|
10329
10393
|
return this.failDurableUpdate(
|
|
10330
10394
|
"Update & Restart requires a durable supervisor handoff; the current supervisor was left running",
|
|
@@ -10489,7 +10553,38 @@ var Supervisor = class {
|
|
|
10489
10553
|
});
|
|
10490
10554
|
});
|
|
10491
10555
|
}
|
|
10556
|
+
/**
|
|
10557
|
+
* One beat to the foreground terminal, deduped.
|
|
10558
|
+
*
|
|
10559
|
+
* Every transition already funnels through writeStatus, so this hangs off that single point rather
|
|
10560
|
+
* than off the dozen call sites that report one — a path added later cannot forget to announce
|
|
10561
|
+
* itself. The dedupe matters because a failure is often written twice (the crash handler, then the
|
|
10562
|
+
* browser-restart waiter that observed it), and the operator should read that once.
|
|
10563
|
+
*/
|
|
10564
|
+
emitActivity(kind, message, ms) {
|
|
10565
|
+
if (!this.onActivity) return;
|
|
10566
|
+
const signature = `${kind}\0${message}`;
|
|
10567
|
+
if (signature === this.lastActivity) return;
|
|
10568
|
+
this.lastActivity = signature;
|
|
10569
|
+
try {
|
|
10570
|
+
this.onActivity({ kind, message, ...ms === void 0 ? {} : { ms } });
|
|
10571
|
+
} catch {
|
|
10572
|
+
}
|
|
10573
|
+
}
|
|
10492
10574
|
writeStatus(state, message, boot = this.boot) {
|
|
10575
|
+
if (state === "ready" && !this.booted) this.booted = true;
|
|
10576
|
+
else if (this.booted) {
|
|
10577
|
+
if (state === "restarting") {
|
|
10578
|
+
this.restartStartedAt = Date.now();
|
|
10579
|
+
this.emitActivity("restarting", message);
|
|
10580
|
+
} else if (state === "ready") {
|
|
10581
|
+
const startedAt = this.restartStartedAt;
|
|
10582
|
+
this.restartStartedAt = void 0;
|
|
10583
|
+
this.emitActivity("ready", message, startedAt === void 0 ? void 0 : Date.now() - startedAt);
|
|
10584
|
+
} else if (state === "failed" || state === "degraded") {
|
|
10585
|
+
this.emitActivity("failed", message);
|
|
10586
|
+
}
|
|
10587
|
+
}
|
|
10493
10588
|
if (!this.supervisorLock) return;
|
|
10494
10589
|
try {
|
|
10495
10590
|
writeProjectStatus(this.supervisorLock, {
|
|
@@ -10791,6 +10886,7 @@ if (options.help) {
|
|
|
10791
10886
|
`Frizz production launcher
|
|
10792
10887
|
|
|
10793
10888
|
Usage: npx ${PACKAGE_NAME} [options] [repository]
|
|
10889
|
+
npx ${PACKAGE_NAME} up serve this repo publicly, board + tunnel together
|
|
10794
10890
|
|
|
10795
10891
|
Runs the npm-resolved immutable Frizz package, then opens it in your default browser. Use frizz-dev
|
|
10796
10892
|
only for a source checkout.
|
|
@@ -11009,6 +11105,10 @@ async function runSupervisor(port, token) {
|
|
|
11009
11105
|
childEntry,
|
|
11010
11106
|
childEnvironment: () => ({ FRIZZ_STABLE_WEB_DIST: webDist, FRIZZ_STABLE_ARTIFACT: `npm:${PACKAGE_NAME}@${PACKAGE_VERSION}`, FRIZZ_SCRIPTS_DIR: scriptsDir, FRIZZ_WORKER_PLUGIN_DIR: workerPluginDir }),
|
|
11011
11107
|
updateAvailable: () => updateAvailable,
|
|
11108
|
+
// The terminal that owns the board says so when the board goes down and comes back. Everything
|
|
11109
|
+
// here is triggered from a browser tab or by a crash, so without this the foreground process is
|
|
11110
|
+
// the last place to learn what happened to it.
|
|
11111
|
+
onActivity: (event) => renderSupervisorActivity(readout, event),
|
|
11012
11112
|
updateRestart: async () => {
|
|
11013
11113
|
try {
|
|
11014
11114
|
const plan = await planRegistryUpdate(PACKAGE_NAME, PACKAGE_VERSION, npmRegistryReleaseAdapter);
|
|
@@ -11026,6 +11126,10 @@ async function runSupervisor(port, token) {
|
|
|
11026
11126
|
const plan = plannedUpdate ?? await planRegistryUpdate(PACKAGE_NAME, PACKAGE_VERSION, npmRegistryReleaseAdapter);
|
|
11027
11127
|
if (!plan) throw new Error("Frizz is already current");
|
|
11028
11128
|
handoffToRegistrySuccessor(plan, { port, projectDir: workspace.root, cwd: workspace.root, env }, npmRegistryReleaseAdapter);
|
|
11129
|
+
readout?.notice("done", "Updated", `Frizz ${plan.latestVersion} is taking over on port ${port}`);
|
|
11130
|
+
readout?.note(`
|
|
11131
|
+
Frizz ${plan.latestVersion} now runs in the background \u2014 ctrl-c here no longer reaches it. Stop it with ${PACKAGE_NAME} --stop.
|
|
11132
|
+
`);
|
|
11029
11133
|
process.exit(0);
|
|
11030
11134
|
}
|
|
11031
11135
|
});
|