frizz 0.12.9 → 0.12.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/claude-agent-broker.js +7850 -7778
  2. package/dist/codex-app-server-daemon.js +49 -10
  3. package/dist/dev-child.js +653 -297
  4. package/dist/frizz.js +118 -21
  5. package/package.json +1 -1
  6. package/runtime/cc-worker/bin/frizz-mcp.mjs +58 -5
  7. package/web-dist/assets/{TerminalPane-CDk5zKv9.js → TerminalPane-DHvHCziB.js} +1 -1
  8. package/web-dist/assets/{abnfDiagram-VRR7QNED-DmkK2qjk.js → abnfDiagram-VRR7QNED-DIzM_IN8.js} +1 -1
  9. package/web-dist/assets/architecture-TIHT7OUA-DBvKOf0j.js +1 -0
  10. package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-BFbA3OG6.js → architectureDiagram-ZJ3FMSHR-Bm_8vd5v.js} +1 -1
  11. package/web-dist/assets/{blockDiagram-677ZJIJ3-DTslTfq9.js → blockDiagram-677ZJIJ3-BXUW_N2o.js} +1 -1
  12. package/web-dist/assets/{c4Diagram-LMCZKHZV-Dmugni-f.js → c4Diagram-LMCZKHZV-C7rfqxUO.js} +1 -1
  13. package/web-dist/assets/channel-CbdXYswc.js +1 -0
  14. package/web-dist/assets/{chunk-32BRIVSS-DS7QIaUB.js → chunk-32BRIVSS-DbfUERLa.js} +1 -1
  15. package/web-dist/assets/{chunk-52WLFC77-CnnFIjVe.js → chunk-52WLFC77-BT_3wKSP.js} +1 -1
  16. package/web-dist/assets/{chunk-C7G6YPKG-BZxNdEVe.js → chunk-C7G6YPKG-JqApnOVt.js} +1 -1
  17. package/web-dist/assets/{chunk-EX3LRPZG-Zv7RLgbb.js → chunk-EX3LRPZG-Cj6hlA4t.js} +1 -1
  18. package/web-dist/assets/{chunk-FWX5IMBZ-6-Zb5eo-.js → chunk-FWX5IMBZ-BGthhuW_.js} +2 -2
  19. package/web-dist/assets/{chunk-HOUHSVGY-J5Ui6IxH.js → chunk-HOUHSVGY-uyLpm_YS.js} +1 -1
  20. package/web-dist/assets/{chunk-ICXQ74PX-DH6GE_Om.js → chunk-ICXQ74PX-BlwUMZAk.js} +1 -1
  21. package/web-dist/assets/{chunk-MOJQB5TN-Bjd1ChDq.js → chunk-MOJQB5TN-MXbNNk-P.js} +1 -1
  22. package/web-dist/assets/{chunk-OGEWGWER-BNvzjYRM.js → chunk-OGEWGWER-Da4My1Rf.js} +1 -1
  23. package/web-dist/assets/{chunk-PUDLZKDR-CdtfylsO.js → chunk-PUDLZKDR-C-PgvO__.js} +1 -1
  24. package/web-dist/assets/{chunk-Q4XR5HBZ-C7N3sKog.js → chunk-Q4XR5HBZ-BxZFe7gr.js} +1 -1
  25. package/web-dist/assets/{chunk-V7JOEXUC-vX-c4OzH.js → chunk-V7JOEXUC-DgERuXm_.js} +1 -1
  26. package/web-dist/assets/{chunk-VAUOI2AC-DtbheJmZ.js → chunk-VAUOI2AC-T5OoQE-_.js} +1 -1
  27. package/web-dist/assets/{chunk-VR4S4FIN-BpE1AOJR.js → chunk-VR4S4FIN--HFvJUG1.js} +1 -1
  28. package/web-dist/assets/{chunk-WYO6CB5R-BupZRR1a.js → chunk-WYO6CB5R-DlAvy41i.js} +1 -1
  29. package/web-dist/assets/{chunk-ZGVPDNZ5-XoWDM-02.js → chunk-ZGVPDNZ5-BdDg7X_H.js} +1 -1
  30. package/web-dist/assets/classDiagram-OUVF2IWQ-BVXwECjS.js +1 -0
  31. package/web-dist/assets/classDiagram-v2-EOCWNBFH-BVXwECjS.js +1 -0
  32. package/web-dist/assets/{cynefin-VYW2F7L2-DOIzVENe.js → cynefin-VYW2F7L2-BhjNO28R.js} +1 -1
  33. package/web-dist/assets/{cynefinDiagram-TSTJHNR4-DGq-kl_q.js → cynefinDiagram-TSTJHNR4-B6VA5gCd.js} +1 -1
  34. package/web-dist/assets/{dagre-VKFMJZFB-Brs6wxcd.js → dagre-VKFMJZFB-6MXoEc6K.js} +1 -1
  35. package/web-dist/assets/{diagram-FQU43EPY-BrQd5FEw.js → diagram-FQU43EPY-D2RSPoK4.js} +1 -1
  36. package/web-dist/assets/{diagram-G47NLZAW-B-DN7aQk.js → diagram-G47NLZAW-BOSbtzOf.js} +1 -1
  37. package/web-dist/assets/{diagram-NH7WQ7WH-DB-NFs3X.js → diagram-NH7WQ7WH-Dt_u21nP.js} +1 -1
  38. package/web-dist/assets/{diagram-OA4YK3LP-DsrBhvMB.js → diagram-OA4YK3LP-CjuWW-7r.js} +1 -1
  39. package/web-dist/assets/{diagram-WEI45ONY-DYctq6PN.js → diagram-WEI45ONY-rANIKJ8N.js} +1 -1
  40. package/web-dist/assets/{ebnfDiagram-CCIWWBDH-C6ghRrJP.js → ebnfDiagram-CCIWWBDH-Bf3kfaKZ.js} +1 -1
  41. package/web-dist/assets/{erDiagram-Q63AITRT-C_iK-Ja6.js → erDiagram-Q63AITRT-6vBp0ITn.js} +1 -1
  42. package/web-dist/assets/eventmodeling-45OFAUF4-STTT-geQ.js +1 -0
  43. package/web-dist/assets/flowDiagram-23GEKE2U-CC7DF1Fz.js +1 -0
  44. package/web-dist/assets/{ganttDiagram-NO4QXBWP-Y9GZAgbA.js → ganttDiagram-NO4QXBWP-C2qN2PMS.js} +1 -1
  45. package/web-dist/assets/{gitGraph-TEB2WS4Q-BgqW4vt7.js → gitGraph-TEB2WS4Q-CRASqc9n.js} +1 -1
  46. package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-eImStPZ8.js → gitGraphDiagram-IHSO6WYX-gsXSPrH2.js} +1 -1
  47. package/web-dist/assets/{index-BOACK0Xu.js → index-DimQCLe8.js} +96 -96
  48. package/web-dist/assets/index-XhfdAXcw.css +1 -0
  49. package/web-dist/assets/{info-DKCQHKI2-BtbNWkY3.js → info-DKCQHKI2-rDkFlFOd.js} +1 -1
  50. package/web-dist/assets/{infoDiagram-FWYZ7A6U-DMIPEeRd.js → infoDiagram-FWYZ7A6U-03ql8Tqr.js} +1 -1
  51. package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-08_raW8G.js → ishikawaDiagram-FXEZZL3T-CfDSAVNp.js} +1 -1
  52. package/web-dist/assets/{journeyDiagram-5HDEW3XC-hPkkufFj.js → journeyDiagram-5HDEW3XC-RWaA6AvH.js} +1 -1
  53. package/web-dist/assets/{kanban-definition-HUTT4EX6-CDBcUNEE.js → kanban-definition-HUTT4EX6-C89qresM.js} +1 -1
  54. package/web-dist/assets/{line-Njg200Gq.js → line-CZtSsvHu.js} +1 -1
  55. package/web-dist/assets/{mermaid-parser.core-1A-yH2Ql.js → mermaid-parser.core-DKNnvxt0.js} +3 -3
  56. package/web-dist/assets/{mermaid.core-D5Mvu4fo.js → mermaid.core-DX8cFeBF.js} +3 -3
  57. package/web-dist/assets/{mindmap-definition-LN4V7U3C-r-0LqhPG.js → mindmap-definition-LN4V7U3C-DW8ClyAX.js} +1 -1
  58. package/web-dist/assets/{packet-7NZHBO7P-Dj8tWs_Q.js → packet-7NZHBO7P-CUOv3apI.js} +1 -1
  59. package/web-dist/assets/{pegDiagram-2B236MQR-BHoUQUjJ.js → pegDiagram-2B236MQR-CFyxKEBL.js} +1 -1
  60. package/web-dist/assets/{pie-RZYD4A2V-GZmPkAjn.js → pie-RZYD4A2V-DyXXRie2.js} +1 -1
  61. package/web-dist/assets/{pieDiagram-ENE6RG2P-CL0ZHN1y.js → pieDiagram-ENE6RG2P-yUw7HA8l.js} +1 -1
  62. package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-vZJzUcfC.js → quadrantDiagram-ABIIQ3AL-Mc7aea_i.js} +1 -1
  63. package/web-dist/assets/{radar-I7S5WNFK-D3x_tyhl.js → radar-I7S5WNFK-BKj0BsQy.js} +1 -1
  64. package/web-dist/assets/{railroad-3IZDKUUU-HVHtGCKZ.js → railroad-3IZDKUUU-DUK_kJIY.js} +1 -1
  65. package/web-dist/assets/railroad-abnf-AHOZXSZD-BDImJcFw.js +1 -0
  66. package/web-dist/assets/railroad-ebnf-EBAXGLYW-BR2XIYqq.js +1 -0
  67. package/web-dist/assets/railroad-peg-LSFZ7HO6-DRCwBbJY.js +1 -0
  68. package/web-dist/assets/{railroadDiagram-RFXS5EU6-Dfw0JONh.js → railroadDiagram-RFXS5EU6-By0Xgb_U.js} +1 -1
  69. package/web-dist/assets/{requirementDiagram-TGXJPOKE-DLM4etHl.js → requirementDiagram-TGXJPOKE-CgTycsRY.js} +1 -1
  70. package/web-dist/assets/{sankeyDiagram-HTMAVEWB-2nsrE-nL.js → sankeyDiagram-HTMAVEWB-mJ_-Grkn.js} +1 -1
  71. package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-VkpQVaPX.js → sequenceDiagram-DBY2YBRQ-Dn6YyeNv.js} +1 -1
  72. package/web-dist/assets/{stateDiagram-2N3HPSRC-xvBH0825.js → stateDiagram-2N3HPSRC-BBws1E-e.js} +1 -1
  73. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-B2jOFVGG.js +1 -0
  74. package/web-dist/assets/{swimlanes-5IMT3BWC-DA8H4qPO.js → swimlanes-5IMT3BWC-Jab-07o9.js} +1 -1
  75. package/web-dist/assets/swimlanesDiagram-G3AALYLV-DhYK_6fH.js +8 -0
  76. package/web-dist/assets/{timeline-definition-FHXFAJF6-npL1KNyH.js → timeline-definition-FHXFAJF6-Cq6RznHz.js} +1 -1
  77. package/web-dist/assets/{treeView-QDETBFTQ-Cea7MDUV.js → treeView-QDETBFTQ-KSelJnyL.js} +1 -1
  78. package/web-dist/assets/{treemap-6X3UGDF4-CGHINewA.js → treemap-6X3UGDF4-B-iiUurZ.js} +1 -1
  79. package/web-dist/assets/{vennDiagram-L72KCM5P-D-RIigY2.js → vennDiagram-L72KCM5P-B8t4NeQy.js} +1 -1
  80. package/web-dist/assets/{wardley-OPB4EBWU-BXdXDctR.js → wardley-OPB4EBWU-CtkAPZLQ.js} +1 -1
  81. package/web-dist/assets/{wardleyDiagram-EHGQE667-tLo8yxD2.js → wardleyDiagram-EHGQE667-DC-ms_sD.js} +1 -1
  82. package/web-dist/assets/{xychartDiagram-FW5EYKEG-I4H6c-9Q.js → xychartDiagram-FW5EYKEG-DW6fcgjF.js} +1 -1
  83. package/web-dist/index.html +2 -2
  84. package/web-dist/assets/architecture-TIHT7OUA-c0q2ebfx.js +0 -1
  85. package/web-dist/assets/channel-CZ15urUA.js +0 -1
  86. package/web-dist/assets/classDiagram-OUVF2IWQ-DFxJiEZ1.js +0 -1
  87. package/web-dist/assets/classDiagram-v2-EOCWNBFH-DFxJiEZ1.js +0 -1
  88. package/web-dist/assets/eventmodeling-45OFAUF4-BdXQ9Pv4.js +0 -1
  89. package/web-dist/assets/flowDiagram-23GEKE2U-rTXtf38R.js +0 -1
  90. package/web-dist/assets/index-BIGkwpMf.css +0 -1
  91. package/web-dist/assets/railroad-abnf-AHOZXSZD-BD2umz4T.js +0 -1
  92. package/web-dist/assets/railroad-ebnf-EBAXGLYW-C1IGySZs.js +0 -1
  93. package/web-dist/assets/railroad-peg-LSFZ7HO6-BVCH7yeK.js +0 -1
  94. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-B3bLucl6.js +0 -1
  95. package/web-dist/assets/swimlanesDiagram-G3AALYLV-cYXAfa4Q.js +0 -8
package/dist/frizz.js CHANGED
@@ -12469,7 +12469,7 @@ var init_shell_writes = __esm({
12469
12469
  function fallbackPort(base) {
12470
12470
  return base + 1e4;
12471
12471
  }
12472
- var import_yaml, ATTACHMENT_IMAGE_EXTENSIONS, ATTACHMENT_TEXT_EXTENSIONS, ATTACHMENT_OFFICE_EXTENSIONS, ATTACHMENT_DATA_EXTENSIONS, ATTACHMENT_ARCHIVE_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, 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_FOR_MAX_MS, PR_WATCH_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, OwnWatchKind, AddOwnWatchInput, OwnWatchView, AddOwnWatchResult, DropOwnWatchInput, DropOwnWatchResult, AskQuestionKind, AskedOptionSchema, AskedQuestionSchema, AskInput, RegisteredQuestionView, AskResult, UnaskInput, UnaskResult, QuestionAnswerSchema, AnswerQuestionsInput, AnswerQuestionsResult, DismissQuestionsInput, DismissQuestionsResult, MarkOwnDoneInput, MarkOwnDoneResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ProviderError, 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, SetThreadPinnedInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetOwnThreadTitleInput, SetOwnThreadTitleResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkillSource, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, HUMAN_GAP_FLOOR_MS, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_GATED, PR_WATCH_STATE, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, EditedFile, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketFilePath, SocketTranscriptClientMsg, SocketFileClientMsg, SocketClientMsg, ProjectCard, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT;
12472
+ var import_yaml, ATTACHMENT_IMAGE_EXTENSIONS, ATTACHMENT_TEXT_EXTENSIONS, ATTACHMENT_OFFICE_EXTENSIONS, ATTACHMENT_DATA_EXTENSIONS, ATTACHMENT_ARCHIVE_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, 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_FOR_MAX_MS, PR_WATCH_DEFAULT_FOR_MS, PrWatchView, AddOwnPrWatchInput, AddOwnPrWatchResult, DropOwnPrWatchInput, DropOwnPrWatchResult, OwnWatchKind, AddOwnWatchInput, OwnWatchView, AddOwnWatchResult, DropOwnWatchInput, DropOwnWatchResult, AskQuestionKind, AskedOptionSchema, AskedQuestionSchema, AskInput, RegisteredQuestionView, AskResult, UnaskInput, UnaskResult, QuestionAnswerSchema, AnswerQuestionsInput, AnswerQuestionsResult, DismissQuestionsInput, DismissQuestionsResult, MarkOwnDoneInput, MarkOwnDoneResult, ListOwnPrWatchesInput, OwnPrWatchesResult, ThreadTimerView, ThreadFence, LimitWindow, LimitPause, ProviderError, ThreadLinkView, UpsertOwnLinkInput, UpsertOwnLinkResult, DropOwnLinkInput, DropOwnLinkResult, 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, SetThreadPinnedInput, SetThreadRecurringPromptInput, SetOwnThreadRecurringPromptInput, SetOwnThreadRecurringPromptResult, GetOwnThreadRecurringPromptInput, OwnThreadRecurringPromptResult, SetOwnThreadTimerInput, CancelOwnThreadTimerInput, ListOwnThreadTimersInput, OwnThreadTimersResult, ThreadActivityItem, ListOwnThreadActivityInput, OwnThreadActivityResult, SetOwnThreadTimerResult, CancelOwnThreadTimerResult, SetOwnThreadStopHookInput, SetOwnThreadHeartbeatInput, ThreadPluginReloadResult, RenameThreadInput, AiRenameThreadInput, AiRenameThreadResult, SetOwnThreadTitleInput, SetOwnThreadTitleResult, SetThreadPermissionInput, SetThreadPermissionResult, ThreadProfileOptionsInput, ThreadProfileOptionsResult, ThreadSkillSource, ThreadSkill, ThreadSkillsInput, ThreadSkillsResult, SetThreadProfileInput, SetThreadProfileResult, DISPATCH_TASK_BANNER, DISPATCH_TASK_BANNER_MARKER, HUMAN_GAP_FLOOR_MS, GithubWakeItem, GithubWakeSteer, WAKE_SCOPE, WAKE_REF, WAKE_SINGLE, WAKE_MULTI_HEAD, PR_WATCH_FINISHED, PR_WATCH_CI_PASSED, PR_WATCH_CI_GATED, PR_WATCH_STATE, PR_WATCH_CI_FAILED, GithubStatus, GithubRefCard, GithubRefPreviewInput, GithubRefPreviewResult, GithubItem, GithubListInput, GithubListResult, GithubBatchInput, GithubBatchResult, BoardMeta, ServerEvent, TranscriptEdit, TranscriptTodo, TranscriptToolCall, TranscriptPart, TranscriptMessage, TranscriptPageCursor, EditedFile, TranscriptPage, TranscriptEarlierInput, SocketTranscriptSlug, SocketFilePath, SocketTranscriptClientMsg, SocketFileClientMsg, SocketClientMsg, ProjectCard, PROJECT_ICON_MAX_BASE64_CHARS, DirectoryPickResult, ThreadLocation, FRIZZ_ROUTE_PREFIX, DEFAULT_PORT;
12473
12473
  var init_src = __esm({
12474
12474
  "packages/shared/src/index.ts"() {
12475
12475
  "use strict";
@@ -12593,7 +12593,14 @@ var init_src = __esm({
12593
12593
  slug: external_exports.string(),
12594
12594
  displayName: external_exports.string(),
12595
12595
  defaultEffort: external_exports.string(),
12596
- efforts: external_exports.array(external_exports.string())
12596
+ efforts: external_exports.array(external_exports.string()),
12597
+ // The model's stock context window and the largest one it accepts, in tokens, straight from the
12598
+ // cache's `context_window` / `max_context_window` (272K / 872K on GPT-5.6, 128K / 128K on Spark).
12599
+ // The Settings "Context window" presets are built from these so the drawer names the numbers codex
12600
+ // will actually run at (maintainer 2026-09-11: "reflect the actual numbers"). Optional: a cache from
12601
+ // before the fields existed, or the degraded fallback, simply carries neither.
12602
+ contextWindow: external_exports.number().int().positive().optional(),
12603
+ maxContextWindow: external_exports.number().int().positive().optional()
12597
12604
  });
12598
12605
  ThreadProfileOption = external_exports.object({
12599
12606
  model: external_exports.string().min(1),
@@ -13187,6 +13194,20 @@ var init_src = __esm({
13187
13194
  retrying: external_exports.boolean().optional(),
13188
13195
  at: external_exports.string().optional()
13189
13196
  });
13197
+ ThreadLinkView = external_exports.object({
13198
+ id: external_exports.string(),
13199
+ kind: external_exports.enum(["link", "file"]),
13200
+ label: external_exports.string(),
13201
+ target: external_exports.string()
13202
+ }).strict();
13203
+ UpsertOwnLinkInput = external_exports.object({
13204
+ slug: ThreadSlug,
13205
+ label: external_exports.string().trim().min(1).max(240).regex(/^[^\x00-\x1f\x7f]+$/),
13206
+ target: external_exports.string().trim().min(1).max(8192).regex(/^[^\x00-\x1f\x7f]+$/)
13207
+ }).strict();
13208
+ UpsertOwnLinkResult = external_exports.object({ link: ThreadLinkView }).strict();
13209
+ DropOwnLinkInput = external_exports.object({ slug: ThreadSlug, id: external_exports.string().min(1) }).strict();
13210
+ DropOwnLinkResult = external_exports.object({ dropped: external_exports.boolean() }).strict();
13190
13211
  ThreadView = external_exports.object({
13191
13212
  id: ThreadSlug,
13192
13213
  // slug; filename is <slug>.md
@@ -13255,6 +13276,8 @@ var init_src = __esm({
13255
13276
  // Live background SHELLS the worker launched (tailer-derived). Same default-[] discipline. Rendered
13256
13277
  // in the anchored background-ops strip alongside sub-agents; ids make current rows drillable.
13257
13278
  bgShells: external_exports.array(BgShellView).default([]),
13279
+ // Optional for snapshots from a server that predates link registration.
13280
+ links: external_exports.array(ThreadLinkView).optional(),
13258
13281
  // The thread's ARMED WATCHERS — registry-derived, not folded from the transcript, which is what makes
13259
13282
  // them survive the worker saying one more sentence. Same default-[] discipline as the two above.
13260
13283
  //
@@ -13573,6 +13596,15 @@ var init_src = __esm({
13573
13596
  // writes were 51% of a day's spend while the entries were invalidated every 15–30 minutes anyway
13574
13597
  // (see claudePromptCacheEnv). Optional so an old blob parses; defaultSettings pins "auto".
13575
13598
  promptCacheTtl: external_exports.enum(["auto", "5m", "1h"]).optional(),
13599
+ // The context window a NEW Codex thread runs with, in tokens. Codex's own default is the model's
13600
+ // stock window (272K on GPT-5.6), but the catalogue also carries a larger `max_context_window` (872K
13601
+ // on GPT-5.6-sol/terra/luna and GPT-6-astra, measured 2026-09-11 in ~/.codex/models_cache.json) that
13602
+ // a thread only reaches when asked. Reaches codex as the `model_context_window` config override on
13603
+ // `thread/start` and every cold `thread/resume` (see codexContextWindowConfig); codex clamps it to
13604
+ // the model's maximum, so a value above it is harmless, and it moves the auto-compact threshold with
13605
+ // it (codex compacts at 90% of the resolved window). Unset ⇒ nothing is sent and the model's stock
13606
+ // window applies. Optional so an old blob parses; defaultSettings leaves it unset.
13607
+ codexContextWindow: external_exports.number().int().positive().optional(),
13576
13608
  // The GitHub batch-dispatch prompt template (the picker's per-item worker prompt). Optional: when
13577
13609
  // unset OR blank the server falls back to its exported DEFAULT_GITHUB_PROMPT. Substitution tokens
13578
13610
  // the server fills: {repo} {n} {title} {url} {labels} {body}. The leading `THREAD: <slug>` tag is
@@ -13792,6 +13824,7 @@ var init_src = __esm({
13792
13824
  }).strict();
13793
13825
  OwnThreadActivityResult = external_exports.object({
13794
13826
  activity: external_exports.array(ThreadActivityItem),
13827
+ links: external_exports.array(ThreadLinkView).optional(),
13795
13828
  /** Every question still owed an answer. NOT a `ThreadActivityItem` and deliberately its own list: a
13796
13829
  * question is not running work, it waits on a PERSON, and there is no `questions:` key in the awaiting
13797
13830
  * fence for it to be written into. Until 2026-08-28 a worker could read its open questions back only
@@ -24557,6 +24590,11 @@ function sliceVisible(line, limit) {
24557
24590
  }
24558
24591
  return `${out}${ANSI.reset}`;
24559
24592
  }
24593
+ function noticeOnlyReadout(options2 = {}) {
24594
+ const readout2 = new Readout(options2);
24595
+ readout2.stop();
24596
+ return readout2;
24597
+ }
24560
24598
  function renderSupervisorActivity(readout2, event) {
24561
24599
  if (!readout2) return;
24562
24600
  switch (event.kind) {
@@ -25802,7 +25840,10 @@ async function startDevSupervisor(opts) {
25802
25840
 
25803
25841
  // src/production-update.ts
25804
25842
  import { execFile as execFile4, spawn as spawn3 } from "node:child_process";
25843
+ import { existsSync as existsSync7 } from "node:fs";
25844
+ import { isAbsolute as isAbsolute5 } from "node:path";
25805
25845
  var PRODUCTION_REEXEC_FLAG = "--_frizz-production-reexec";
25846
+ var PRODUCTION_PRINT_LAUNCHER_FLAG = "--_frizz-print-launcher";
25806
25847
  function compareReleaseVersions(a, b) {
25807
25848
  const parse2 = (value) => {
25808
25849
  const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/u.exec(value);
@@ -25829,18 +25870,45 @@ async function planRegistryUpdate(packageName, currentVersion, adapter) {
25829
25870
  if (comparison >= 0) return null;
25830
25871
  return { packageName, currentVersion, latestVersion, packageSpec: `${packageName}@${latestVersion}` };
25831
25872
  }
25832
- function handoffToRegistrySuccessor(plan, request, adapter) {
25833
- const child = adapter.spawnNpmExec({
25873
+ function successorArgs(port) {
25874
+ return [PRODUCTION_REEXEC_FLAG, "--port", String(port)];
25875
+ }
25876
+ async function resolveRegistrySuccessor(plan, request, adapter) {
25877
+ const result = await adapter.npmExec({
25834
25878
  packageSpec: plan.packageSpec,
25835
25879
  // The published bin name tracks the package name (frizz). Never hardcode a stale bin here or
25836
25880
  // a renamed release would resolve the new package but invoke a bin that no longer exists.
25837
25881
  bin: plan.packageName,
25838
- args: [PRODUCTION_REEXEC_FLAG, "--port", String(request.port), request.projectDir],
25882
+ args: [PRODUCTION_PRINT_LAUNCHER_FLAG],
25883
+ cwd: request.cwd,
25884
+ env: request.env
25885
+ });
25886
+ if (result.code !== 0) {
25887
+ const how = result.signal ? `signal ${result.signal}` : `exit ${result.code}`;
25888
+ const tail = result.stderr.trim().split("\n").slice(-6).join("\n").trim();
25889
+ throw new Error(`npm exec ${plan.packageSpec} failed (${how})${tail ? `: ${tail}` : ""}`);
25890
+ }
25891
+ const entry = result.stdout.trim().split("\n").map((line) => line.trim()).filter(Boolean).at(-1) ?? "";
25892
+ if (!isAbsolute5(entry) || !existsSync7(entry))
25893
+ throw new Error(`${plan.packageSpec} did not report its launcher entry (got ${JSON.stringify(entry)})`);
25894
+ return { plan, entry };
25895
+ }
25896
+ function reexecIntoRegistrySuccessor(successor, request, execve = process.execve.bind(process)) {
25897
+ return execve(process.execPath, [process.execPath, successor.entry, ...successorArgs(request.port)], {
25898
+ ...request.env,
25899
+ FRIZZ_REGISTRY_PACKAGE: successor.plan.packageName,
25900
+ FRIZZ_REGISTRY_VERSION: successor.plan.latestVersion
25901
+ });
25902
+ }
25903
+ function handoffToRegistrySuccessor(successor, request, adapter) {
25904
+ const child = adapter.spawnDetached({
25905
+ entry: successor.entry,
25906
+ args: successorArgs(request.port),
25839
25907
  cwd: request.cwd,
25840
25908
  env: {
25841
25909
  ...request.env,
25842
- FRIZZ_REGISTRY_PACKAGE: plan.packageName,
25843
- FRIZZ_REGISTRY_VERSION: plan.latestVersion
25910
+ FRIZZ_REGISTRY_PACKAGE: successor.plan.packageName,
25911
+ FRIZZ_REGISTRY_VERSION: successor.plan.latestVersion
25844
25912
  }
25845
25913
  });
25846
25914
  child.once("error", () => {
@@ -25861,13 +25929,28 @@ var npmRegistryReleaseAdapter = {
25861
25929
  });
25862
25930
  });
25863
25931
  },
25864
- spawnNpmExec({ packageSpec, bin, args: args2, cwd, env }) {
25865
- return spawn3("npm", ["exec", "--yes", `--package=${packageSpec}`, "--", bin, ...args2], {
25866
- cwd,
25867
- env,
25868
- detached: true,
25869
- stdio: "ignore"
25932
+ npmExec({ packageSpec, bin, args: args2, cwd, env }) {
25933
+ return new Promise((settle) => {
25934
+ const child = spawn3("npm", ["exec", "--yes", `--package=${packageSpec}`, "--", bin, ...args2], {
25935
+ cwd,
25936
+ env,
25937
+ stdio: ["ignore", "pipe", "pipe"]
25938
+ });
25939
+ let stdout = "";
25940
+ let stderr = "";
25941
+ child.stdout.setEncoding("utf8").on("data", (chunk) => {
25942
+ stdout += chunk;
25943
+ });
25944
+ child.stderr.setEncoding("utf8").on("data", (chunk) => {
25945
+ stderr += chunk;
25946
+ });
25947
+ child.once("error", (error) => settle({ code: null, signal: null, stdout, stderr: `${stderr}
25948
+ ${error.message}` }));
25949
+ child.once("close", (code, signal) => settle({ code, signal, stdout, stderr }));
25870
25950
  });
25951
+ },
25952
+ spawnDetached({ entry, args: args2, cwd, env }) {
25953
+ return spawn3(process.execPath, [entry, ...args2], { cwd, env, detached: true, stdio: "ignore" });
25871
25954
  }
25872
25955
  };
25873
25956
 
@@ -25955,6 +26038,10 @@ function resolvePackageVersion() {
25955
26038
  var PACKAGE_VERSION = resolvePackageVersion();
25956
26039
  var rawArgs = process.argv.slice(2);
25957
26040
  var reexec = rawArgs.includes(PRODUCTION_REEXEC_FLAG);
26041
+ if (rawArgs.includes(PRODUCTION_PRINT_LAUNCHER_FLAG)) {
26042
+ console.log(fileURLToPath2(import.meta.url));
26043
+ process.exit(0);
26044
+ }
25958
26045
  var args = rawArgs.filter((arg) => arg !== PRODUCTION_REEXEC_FLAG);
25959
26046
  var fail = (error) => {
25960
26047
  console.error(`frizz: ${error instanceof Error ? error.message : error}`);
@@ -26064,6 +26151,7 @@ var logger = setAmbientLogger(
26064
26151
  process.env.FRIZZ_LOG_FILE ? createLogger({ file: process.env.FRIZZ_LOG_FILE, owner: false }) : createLogger({ file: runLogPath(workspace.stateDir) })
26065
26152
  );
26066
26153
  var readout = reexec || process.env.FRIZZ_PRODUCTION_SUPERVISOR === "1" ? void 0 : new Readout({ debug: options.debug, version: PACKAGE_VERSION });
26154
+ var activityReadout = readout ?? (reexec && process.stdout.isTTY ? noticeOnlyReadout({ version: PACKAGE_VERSION }) : void 0);
26067
26155
  attachTerminalMirror(logger, options.debug || process.env.FRIZZ_DEBUG === "1");
26068
26156
  readout?.plan([
26069
26157
  { key: "server", label: "Server" },
@@ -26182,7 +26270,7 @@ async function runSupervisor(port, token) {
26182
26270
  const scriptsDir = join15(runtimeDir, "board");
26183
26271
  const workerPluginDir = join15(runtimeDir, "cc-worker");
26184
26272
  const childEntry = fileURLToPath2(new URL("./dev-child.js", import.meta.url));
26185
- let plannedUpdate;
26273
+ let plannedSuccessor;
26186
26274
  let updateAvailable = true;
26187
26275
  let updateVersion;
26188
26276
  const refreshUpdateAvailable = async () => {
@@ -26221,7 +26309,7 @@ async function runSupervisor(port, token) {
26221
26309
  // The terminal that owns the board says so when the board goes down and comes back. Everything
26222
26310
  // here is triggered from a browser tab or by a crash, so without this the foreground process is
26223
26311
  // the last place to learn what happened to it.
26224
- onActivity: (event) => renderSupervisorActivity(readout, event),
26312
+ onActivity: (event) => renderSupervisorActivity(activityReadout, event),
26225
26313
  updateRestart: async () => {
26226
26314
  try {
26227
26315
  const plan = await planRegistryUpdate(PACKAGE_NAME, PACKAGE_VERSION, npmRegistryReleaseAdapter);
@@ -26230,17 +26318,25 @@ async function runSupervisor(port, token) {
26230
26318
  updateVersion = void 0;
26231
26319
  return { state: "failed", message: `Frizz ${PACKAGE_VERSION} is already current` };
26232
26320
  }
26233
- plannedUpdate = plan;
26234
26321
  updateVersion = plan.latestVersion;
26235
- return { state: "ready", message: `Frizz ${plan.latestVersion} will start in a new npm execution cache` };
26322
+ plannedSuccessor = await resolveRegistrySuccessor(plan, { cwd: workspace.root, env }, npmRegistryReleaseAdapter);
26323
+ return { state: "ready", message: `Frizz ${plan.latestVersion} is installed in its own npm execution cache` };
26236
26324
  } catch (error) {
26237
26325
  return { state: "failed", message: error instanceof Error ? error.message : String(error) };
26238
26326
  }
26239
26327
  },
26240
26328
  durableReexec: async () => {
26241
- const plan = plannedUpdate ?? await planRegistryUpdate(PACKAGE_NAME, PACKAGE_VERSION, npmRegistryReleaseAdapter);
26242
- if (!plan) throw new Error("Frizz is already current");
26243
- handoffToRegistrySuccessor(plan, { port, projectDir: workspace.root, cwd: workspace.root, env }, npmRegistryReleaseAdapter);
26329
+ const successor = plannedSuccessor;
26330
+ if (!successor) throw new Error("no update was prepared");
26331
+ const { plan } = successor;
26332
+ const successorEnv = { ...env, FRIZZ_REGISTRY_PACKAGE: plan.packageName, FRIZZ_REGISTRY_VERSION: plan.latestVersion };
26333
+ if (typeof process.execve === "function") {
26334
+ activityReadout?.notice("progress", "Updating", `reloading this launcher in place on Frizz ${plan.latestVersion}`);
26335
+ paneHost?.dispose();
26336
+ remote?.stop();
26337
+ reexecIntoRegistrySuccessor(successor, { port, env: successorEnv });
26338
+ }
26339
+ handoffToRegistrySuccessor(successor, { port, cwd: workspace.root, env: successorEnv }, npmRegistryReleaseAdapter);
26244
26340
  readout?.notice("done", "Updated", `Frizz ${plan.latestVersion} is taking over on port ${port}`);
26245
26341
  readout?.note(`
26246
26342
  Frizz ${plan.latestVersion} now runs in the background \u2014 ctrl-c here no longer reaches it. Stop it with ${PACKAGE_NAME} --stop.
@@ -26276,7 +26372,7 @@ async function runSupervisor(port, token) {
26276
26372
  // Acknowledge the first signal on the spot; the drain that follows is bounded but not instant.
26277
26373
  onStop: () => {
26278
26374
  logger.info("launcher", "stop signal received; draining the control plane");
26279
- readout?.notice("progress", "Stopping", "draining the control plane \u2014 press ctrl-c again to force");
26375
+ activityReadout?.notice("progress", "Stopping", "draining the control plane \u2014 press ctrl-c again to force");
26280
26376
  },
26281
26377
  exit: (code) => {
26282
26378
  logger.info("launcher", `stopped with code ${code}`);
@@ -26302,6 +26398,7 @@ async function runSupervisor(port, token) {
26302
26398
  process.on("SIGHUP", stop);
26303
26399
  void supervisor.stopRequested.then(stop);
26304
26400
  await supervisor.firstBoot;
26401
+ if (reexec) activityReadout?.notice("done", "Updated", `Frizz ${PACKAGE_VERSION} is serving on port ${port} \xB7 ctrl-c to stop`);
26305
26402
  return await new Promise(() => {
26306
26403
  });
26307
26404
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frizz",
3
- "version": "0.12.9",
3
+ "version": "0.12.11",
4
4
  "private": false,
5
5
  "description": "A local web UI for running many coding agents at once",
6
6
  "keywords": [
@@ -672,7 +672,7 @@ const ACTIVITY = {
672
672
  description:
673
673
  "EVERYTHING YOU CURRENTLY HAVE OUT, with the id each one is named by — your background shells, your " +
674
674
  "sub-agents, your armed timers, the pull requests you registered, the `wch_…` of every watch holding " +
675
- "one of them, and every QUESTION still owed an answer.\n\n" +
675
+ "one of them, every QUESTION still owed an answer, and saved links/files with their lnk_ ids.\n\n" +
676
676
  "WHY YOU NEED IT: an ```awaiting fence names what you are waiting on BY ID, and frizz checks every " +
677
677
  "one against what is actually live. A name that matches nothing is not a park — you are bumped and " +
678
678
  "your thread queues. The same goes for the ids `unwatch` and `unask` take, and for the id you put in " +
@@ -684,7 +684,36 @@ const ACTIVITY = {
684
684
  inputSchema: { type: "object", properties: {}, required: [] },
685
685
  }
686
686
 
687
- const TOOLS = [SPAWN_THREAD, GOAL, TIMER, WATCH_PR, WATCH, UNWATCH, ASK, UNASK, DONE, TITLE, ACTIVITY]
687
+ const LINK = {
688
+ name: "link",
689
+ description: "Register a labeled URL or local file underneath this thread's prompt, alongside agents and shells. " +
690
+ "Use for dev servers, working documents, reports, and downloads the human will need again. " +
691
+ "The same label updates its existing row without duplicating or reordering it. " +
692
+ "HTTP(S) destinations render as Link; local files render as File and use Frizz's existing file reader/opener. " +
693
+ "Files must exist. Relative paths resolve from the project root; use absolute paths for worktrees. " +
694
+ "Registration survives rests and restarts, but does not start, monitor, or verify a server. " +
695
+ "It never blocks done or parks the thread. Read registrations with activity; remove one with unlink.",
696
+ inputSchema: {
697
+ type: "object",
698
+ properties: {
699
+ label: { type: "string", description: "Short destination label, such as Open dev server or Working plan. Reuse it to update that row." },
700
+ target: { type: "string", description: "An HTTP(S) URL, file:// URL, or existing local file path. No credentials in URLs." },
701
+ },
702
+ required: ["label", "target"],
703
+ additionalProperties: false,
704
+ },
705
+ }
706
+ const UNLINK = {
707
+ name: "unlink",
708
+ description: "Remove one saved link/file from this thread by its lnk_ id (returned by link or listed by activity). " +
709
+ "Only removes the registration: it never deletes a file or stops a server.",
710
+ inputSchema: {
711
+ type: "object", properties: { id: { type: "string", description: "The lnk_ id of a registration on this thread." } },
712
+ required: ["id"], additionalProperties: false,
713
+ },
714
+ }
715
+
716
+ const TOOLS = [SPAWN_THREAD, GOAL, TIMER, WATCH_PR, WATCH, UNWATCH, ASK, UNASK, DONE, TITLE, ACTIVITY, LINK, UNLINK]
688
717
 
689
718
  /** @type {Record<string, (args: Record<string, unknown>) => Promise<string>>} */
690
719
  const HANDLERS = {
@@ -699,6 +728,27 @@ const HANDLERS = {
699
728
  [TITLE.name]: title,
700
729
  [UNWATCH.name]: unwatch,
701
730
  [ACTIVITY.name]: activity,
731
+ [LINK.name]: link,
732
+ [UNLINK.name]: unlink,
733
+ }
734
+
735
+ /** @param {Record<string, unknown>} args @returns {Promise<string>} */
736
+ async function link(args) {
737
+ const label = typeof args.label === "string" ? args.label.trim() : ""
738
+ const target = typeof args.target === "string" ? args.target.trim() : ""
739
+ if (!label || !target) throw new Error("`label` and `target` are required")
740
+ const result = (await callRpc("upsertOwnLink", { slug: threadSlug(), label, target }))?.result
741
+ const saved = result?.link
742
+ if (!saved?.id) throw new Error("Frizz did not return a saved link")
743
+ return `Registered ${saved.kind} ${saved.id}: ${saved.label}\n${saved.target}\n\nThis reference stays underneath the prompt. It does not assert a server is running or block completion. Remove it with unlink.`
744
+ }
745
+
746
+ /** @param {Record<string, unknown>} args @returns {Promise<string>} */
747
+ async function unlink(args) {
748
+ const id = typeof args.id === "string" ? args.id.trim() : ""
749
+ if (!id) throw new Error("`id` is required — take it from link or activity")
750
+ const result = (await callRpc("dropOwnLink", { slug: threadSlug(), id }))?.result
751
+ return result?.dropped ? `Removed registration ${id}. No file was deleted and no server was stopped.` : `No registration ${id} on this thread.`
702
752
  }
703
753
 
704
754
  /** The `title` handler: register this thread's considered name.
@@ -726,6 +776,9 @@ async function activity() {
726
776
  const result = (await callRpc("listOwnThreadActivity", { slug: threadSlug() }))?.result
727
777
  const items = Array.isArray(result?.activity) ? result.activity : []
728
778
  const questions = Array.isArray(result?.questions) ? result.questions : []
779
+ const links = Array.isArray(result?.links) ? result.links : []
780
+ const linksBlock = links.length === 0 ? "" : "\n\nSaved links and files (not running work; remove with unlink):\n" +
781
+ links.map((link) => ` ${link.id} ${link.kind}: ${link.label}\n ${link.target}`).join("\n")
729
782
  // THE QUESTIONS ARE NOT PART OF THE FENCE, so they are printed in their own section and never fed to
730
783
  // the fence builder below. A question waits on a person; there is no `questions:` key to write it into.
731
784
  const askedBlock = questions.length === 0 ? "" : (
@@ -740,14 +793,14 @@ async function activity() {
740
793
  return (
741
794
  "Nothing is RUNNING on this thread — no background shells, no sub-agents, no armed timers, no " +
742
795
  "registered PRs. So an ```awaiting fence would have nothing to name, and a fence naming nothing " +
743
- "is not a park." + askedBlock
796
+ "is not a park." + askedBlock + linksBlock
744
797
  )
745
798
  }
746
799
  return (
747
800
  "Nothing is running on this thread — no background shells, no sub-agents, no armed timers, no " +
748
801
  "registered PRs, and no open questions.\n\nSo there is nothing to wait on: an ```awaiting fence " +
749
802
  "would have nothing to name, and a fence naming nothing is not a park. End with ```done, or with " +
750
- "a ```question if you need the human."
803
+ "a ```question if you need the human." + linksBlock
751
804
  )
752
805
  }
753
806
  const lines = items.map((i) => {
@@ -775,7 +828,7 @@ async function activity() {
775
828
  "```\n\nDrop the lines you are not actually waiting on — a dev server you left running is not a wait." +
776
829
  "\n\nBETTER THAN NAMING A SHELL IN THE FENCE: `watch` REGISTERS the wait, so it survives your turn " +
777
830
  "ending and you never restate it. Anything already marked `[watched as …]` above needs no fence line." +
778
- askedBlock
831
+ askedBlock + linksBlock
779
832
  )
780
833
  }
781
834