weir-harness 1.1.6 → 1.2.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/lib/client.js CHANGED
@@ -1,4 +1,4 @@
1
- // Weir client chunks: {"client.blackboard-model.js":"66fd9fc5438477d6d7ff156631f810a647ce352612a16051e987e8cd449bc4c9","client.blackboard-panel.js":"f961e0242dad7bf311829a25e265bf091925711b2fb9c19d2141997fbdf792b5","client.capability-badge.js":"6ffd703f498e0aa5cc8ac78f244402ec4ceee56d22d2a0e74c246799565776cc","client.capability-manager.js":"d8d1076e1b624c1dfc0834ad393c05fd7d9ee35004cd2fb34e5e5ba83f44c902","client.capability-model.js":"d0ad248c4a6defbc90f79c8c0e7904639779d47927874b8663c15c6cecb9d54a","client.capability-presets.js":"12ac8da3568d013abd76b67cfe473a329f4af2feaac9cd55a82d8881e5bc1017","client.chain-editor.js":"1e9a33bc68cabc43bc27b91ef83eab5028a33256596c147e15722d684687765b","client.chain-model.js":"81cdd04626900a63c38ccb3d9c4d117686c6f8a5da2ce9131b7aaf2f089dea77","client.disabled-categories-editor.js":"d4606a3172b47b25caf76fd64c8420a0079cd5f008bc67a9c71b3f146724e393","client.edit-lock-maintenance.js":"f5dca1a7658e2f536b52d265c49ab37bb5d2df6bcd6cf21826b843c9554311a8","client.edit-lock-panel.js":"54f7a21b79adc2b91803c61d92b0dad72d95d5d320fdf35433719cefd0a6c46d","client.hash-edit-model.js":"99df87cc3cc261abd160b83124b5ce726d0708f3c87eba9d58ad9e5a1f41bae9","client.hash-edit-view.js":"fc0f4dabddab9a48527553ad4232b3715e46e6863aab75e02ae2dcd6687265c2","client.lsp-model.js":"6b5bead2900289427a1ad723b9c7bea85af4c5547029e486c620ff94ece24775","client.lsp-panel.js":"39211da7658e0810abc0984b8bcbbfb4ee6a6299fedfd21649ded1ab39d1f291","client.lsp-toggle.js":"4d960984ccf1045c617be6d282665513a9cf636779563a276973b55036a59fb6","client.model-picker.js":"57f96826e00b37ae6d6474a6750f31b4e128e5fdb37e302875a41cdb2e18f14a","client.notify-permissions.js":"c1c103ce5976a4032b62e12b3b3ecb907a574159bf89512539c68c4886ea37a7","client.notify-web.js":"b2ccf831524be4e94c532324cb5495793d4424e3b78d6014d2a3f3d20e9c5871","client.robash-editor.js":"cd6a283b72cb02598e32ca4ce03a1b8de5f328ecdd1f5f920377524f3bdcbe1c","client.robash-model.js":"356ee7a679223bcd351720b2bc9e7300e390d97a60d1c8d75998706b4644923b","client.settings-page.js":"3f33da4ce1676721e38e5437653a2d706948ddb3f2afc6507e03d79a596339b9","client.worktree-model.js":"819f1b00650aa0bb01140690b29b4a1f09b9d26e6bb73adc7efbb3a08e215766","client.worktree-view.js":"356c3f5f683b8509ae8679243a6460ca02957fd15e057a629b2ac4fdd12ed057"}
1
+ // Weir client chunks: {"client.blackboard-model.js":"f635f6c1a03538b41c253a3236826220c38a5a1f45db73547fa82f4955e41cb3","client.blackboard-panel.js":"c9d6a0f02623075fc884f3519f982574ad33ad871f7bcd7e8c36f12512f0de39","client.capability-badge.js":"6ffd703f498e0aa5cc8ac78f244402ec4ceee56d22d2a0e74c246799565776cc","client.capability-manager.js":"d8d1076e1b624c1dfc0834ad393c05fd7d9ee35004cd2fb34e5e5ba83f44c902","client.capability-model.js":"d0ad248c4a6defbc90f79c8c0e7904639779d47927874b8663c15c6cecb9d54a","client.capability-presets.js":"12ac8da3568d013abd76b67cfe473a329f4af2feaac9cd55a82d8881e5bc1017","client.chain-editor.js":"1e9a33bc68cabc43bc27b91ef83eab5028a33256596c147e15722d684687765b","client.chain-model.js":"81cdd04626900a63c38ccb3d9c4d117686c6f8a5da2ce9131b7aaf2f089dea77","client.disabled-categories-editor.js":"d4606a3172b47b25caf76fd64c8420a0079cd5f008bc67a9c71b3f146724e393","client.edit-lock-maintenance.js":"f5dca1a7658e2f536b52d265c49ab37bb5d2df6bcd6cf21826b843c9554311a8","client.edit-lock-panel.js":"54f7a21b79adc2b91803c61d92b0dad72d95d5d320fdf35433719cefd0a6c46d","client.hash-edit-model.js":"99df87cc3cc261abd160b83124b5ce726d0708f3c87eba9d58ad9e5a1f41bae9","client.hash-edit-view.js":"fc0f4dabddab9a48527553ad4232b3715e46e6863aab75e02ae2dcd6687265c2","client.lsp-model.js":"6b5bead2900289427a1ad723b9c7bea85af4c5547029e486c620ff94ece24775","client.lsp-panel.js":"39211da7658e0810abc0984b8bcbbfb4ee6a6299fedfd21649ded1ab39d1f291","client.lsp-toggle.js":"4d960984ccf1045c617be6d282665513a9cf636779563a276973b55036a59fb6","client.model-picker.js":"57f96826e00b37ae6d6474a6750f31b4e128e5fdb37e302875a41cdb2e18f14a","client.notify-permissions.js":"c1c103ce5976a4032b62e12b3b3ecb907a574159bf89512539c68c4886ea37a7","client.notify-web.js":"b2ccf831524be4e94c532324cb5495793d4424e3b78d6014d2a3f3d20e9c5871","client.robash-editor.js":"cd6a283b72cb02598e32ca4ce03a1b8de5f328ecdd1f5f920377524f3bdcbe1c","client.robash-model.js":"356ee7a679223bcd351720b2bc9e7300e390d97a60d1c8d75998706b4644923b","client.settings-page.js":"ca31b2fbf5bbca0e1357bf6c78d5860898a5bdc9c878fe61c6b4645e0a7ecb79","client.worktree-model.js":"819f1b00650aa0bb01140690b29b4a1f09b9d26e6bb73adc7efbb3a08e215766","client.worktree-view.js":"356c3f5f683b8509ae8679243a6460ca02957fd15e057a629b2ac4fdd12ed057"}
2
2
  window.__ModuleLoader__.load({
3
3
  id: "weir-harness",
4
4
  factory: (require) => {
@@ -31,7 +31,9 @@ window.__ModuleLoader__.load({
31
31
  })();
32
32
  const en = {
33
33
  title: "Weir",
34
- description: "One-stop configuration for the Weir preset: intent classification, model chains, continuation, context pressure, editing, read-only bash, and LSP.",
34
+ description: "One-stop configuration for the Weir preset: intent classification, auto-continuation, context pressure, file editing, worktree lanes, read-only shell, LSP, and notifications; model routing is a separate page.",
35
+ routingTitle: "Weir Model Routing",
36
+ routingDescription: "Which models delegated children run on: per task category or curated agent, with ordered fallbacks.",
35
37
  loading: "Loading Weir settings…",
36
38
  loadFailed: "Weir settings could not be loaded:",
37
39
  unavailable: "This plugin is not loaded, so it cannot be configured right now.",
@@ -39,6 +41,8 @@ window.__ModuleLoader__.load({
39
41
  saveFailed: "The deployment did not accept these values; they were left for you to correct.",
40
42
  save: "Save",
41
43
  saving: "Saving…",
44
+ pendingChanges: "{n} unsaved change(s)",
45
+ discardChanges: "Discard",
42
46
  overridden: "Overridden",
43
47
  reset: "Reset to default",
44
48
  restartRequired: "Restart required",
@@ -56,57 +60,56 @@ window.__ModuleLoader__.load({
56
60
  modelEmpty: "Select a model",
57
61
  pickerUnavailable: "Model picker unavailable — reload the settings page to retry.",
58
62
  groupIntent: "Intent",
59
- groupDelegate: "Delegation",
60
- groupTodo: "Continuation",
63
+ groupTodo: "Auto-continuation",
61
64
  groupGuard: "Context pressure",
62
- groupEditing: "Editing",
65
+ groupEditing: "File editing",
63
66
  groupWorktree: "Worktree lanes",
64
- groupRobash: "Read-only bash",
67
+ groupRobash: "Read-only shell",
65
68
  groupLsp: "LSP",
66
69
  groupNotify: "Notifications",
67
- groupBlackboard: "Blackboard",
68
- blackboardWriteTokenTtlMinutes: "Blackboard write-token TTL (minutes)",
69
- blackboardWriteTokenTtlMinutesHint: "Minutes an acquired blackboard write authority stays valid; expiry releases the key and notifies its subscribers (default 60). Applies immediately.",
70
+ groupRoutingCategories: "Task categories",
71
+ groupRoutingAgents: "Curated agents",
72
+ groupRoutingSupervision: "Supervision and retries",
70
73
  intentGateClassifierOptionRegex: "regex",
71
74
  intentGateClassifierOptionLlm: "llm",
72
75
  intentGateClassifierOptionJev: "jev",
73
76
  intentGateClassifier: "Intent classifier",
74
- intentGateClassifierHint: "regex (default, zero cost), llm (sidecar semantic classification), jev (experimental, off by default).",
75
- intentGateProvider: "Classifier provider (llm mode)",
76
- intentGateProviderHint: "Sidecar route override; blank follows the session route.",
77
- intentGateModel: "Classifier model (llm mode)",
78
- intentGateModelHint: "Sidecar model override; blank follows the session route.",
77
+ intentGateClassifierHint: "How each message's intent is detected: regex uses built-in rules at zero cost (default); llm uses a small dedicated model; jev is experimental.",
78
+ intentGateProvider: "Classifier model (llm mode)",
79
+ intentGateProviderHint: "A dedicated model for semantic classification; blank follows the session model.",
80
+ intentGateModel: "Classifier model name (llm mode)",
81
+ intentGateModelHint: "Blank follows the session route's model.",
79
82
  intentGateReasoningEffort: "Classifier reasoning effort (llm mode)",
80
- intentGateReasoningEffortHint: "Sidecar reasoning-effort override; blank follows the model default.",
83
+ intentGateReasoningEffortHint: "Blank follows the model default.",
81
84
  intentGateTimeoutMs: "Classifier timeout (ms)",
82
- intentGateTimeoutMsHint: "Classification fails open to the regex result on timeout.",
85
+ intentGateTimeoutMsHint: "On timeout the rule-based result is used; the message is never blocked (default 1500).",
83
86
  jevEndpoint: "Jev endpoint",
84
- jevEndpointHint: "Jev decisions endpoint (experimental mode).",
87
+ jevEndpointHint: "Jev decisions service URL (experimental mode).",
85
88
  jevModel: "Jev model",
86
- jevModelHint: "Jev model name (experimental mode).",
89
+ jevModelHint: "Model name for Jev (default jev).",
87
90
  jevApiKeyEnv: "Jev API key env var",
88
- jevApiKeyEnvHint: "Environment variable name holding the Jev API key (the key itself never enters config).",
89
- delegateCategoryChains: "Category model chains (JSON)",
90
- delegateCategoryChainsHint: "Which model each category's children run on, edited visually; rungs fall back in order.",
91
- delegateAgentChains: "Agent model chains (JSON)",
92
- delegateAgentChainsHint: "Which model each curated agent runs on, edited visually; an empty lane inherits the caller route.",
91
+ jevApiKeyEnvHint: "Environment variable name holding the Jev API key; the key itself never enters config.",
92
+ delegateCategoryChains: "Category models",
93
+ delegateCategoryChainsHint: "The model children of each task category run on; add fallbacks tried in order, or leave empty to follow the session model.",
94
+ delegateAgentChains: "Curated agent models",
95
+ delegateAgentChainsHint: "The model each curated agent (finder, scholar, advisor) runs on; empty inherits the caller's route.",
93
96
  delegateDisabledCategories: "Disabled categories",
94
- delegateDisabledCategoriesHint: "Pick the categories to disable from the registry list: disabled categories leave the delegate target list and cannot be delegated to. Append-only — a registry-level disable always stays in effect and cannot be cleared from here; unknown names are no longer reachable through this control.",
97
+ delegateDisabledCategoriesHint: "Disabled categories leave the delegation list and can no longer be delegated to.",
95
98
  disabledCategoriesCount: "disabled",
96
- disabledCategoriesPanelHint: "One switch per category. Saving writes exactly the switched-on names; switching everything off saves an empty list, which the server reads as \"nothing disabled\".",
97
- disabledCategoriesInvalid: "The stored value is not a JSON string array; the editor opened with every category off — saving replaces the stored value.",
99
+ disabledCategoriesPanelHint: "One switch per category; saving writes exactly the switched-on names — all off disables nothing.",
100
+ disabledCategoriesInvalid: "The stored value is not a valid category list; the editor opened with every category off — saving replaces it.",
98
101
  chainAgent_finder: "Finder",
99
102
  chainAgent_finder_desc: "Contextual codebase search: answers \"where is X?\" and \"find the code that does Z\". Read-only, fast, parallel-first.",
100
103
  chainAgent_scholar: "Scholar",
101
104
  chainAgent_scholar_desc: "Documentation and OSS research: official docs, library APIs, best practices, real-world usage. Read-only.",
102
105
  chainAgent_advisor: "Advisor",
103
106
  chainAgent_advisor_desc: "Architecture and design advisor: module boundaries, decomposition, trade-offs. Read-only, high reasoning.",
104
- chainAgentPanelHint: "Pick models per curated-agent lane; an empty lane inherits the caller route. Rungs fall back in order.",
107
+ chainAgentPanelHint: "One row per curated agent; empty inherits the caller's route, fallbacks are tried in order.",
105
108
  chainEdit: "Edit",
106
- chainPanelHint: "Pick models per category lane; an empty lane inherits the session route. Rungs fall back in order.",
109
+ chainPanelHint: "One row per category: Edit picks the models, fallbacks are tried in order; an empty row follows the session model.",
107
110
  chainSave: "Save",
108
111
  chainCancel: "Cancel",
109
- chainAddRung: "Add rung",
112
+ chainAddRung: "Add fallback",
110
113
  chainRemove: "Remove",
111
114
  chainClear: "Clear (inherit)",
112
115
  chainCategory_quick: "Quick",
@@ -119,38 +122,34 @@ window.__ModuleLoader__.load({
119
122
  chainCategory_visual_desc: "Frontend, UI/UX, styling, animation, layout.",
120
123
  chainCategory_writing: "Writing",
121
124
  chainCategory_writing_desc: "Documentation, prose, technical writing, README and guides.",
122
- "chainCategory_general-low": "General (low)",
125
+ "chainCategory_general-low": "General (light)",
123
126
  "chainCategory_general-low_desc": "Small tasks that fit no other category.",
124
- "chainCategory_general-high": "General (high)",
127
+ "chainCategory_general-high": "General (standard)",
125
128
  "chainCategory_general-high_desc": "Standard features spanning a few files with known patterns.",
126
129
  chainCategory_artistry: "Artistry",
127
130
  chainCategory_artistry_desc: "Highly creative or artistic tasks, novel ideas, design exploration.",
128
131
  chainCategory_architect: "Architect",
129
132
  chainCategory_architect_desc: "Advisory architecture consult: boundaries, decomposition, trade-offs (read-only).",
130
- supervisionMaxRetries: "Supervision retry cap",
131
- supervisionMaxRetriesHint: "Supervised continuation retry cap.",
132
- supervisionInitialBackoffMs: "Supervision initial backoff (ms)",
133
- supervisionInitialBackoffMsHint: "Supervised retry initial backoff.",
134
- supervisionMaxBackoffMs: "Supervision backoff cap (ms)",
135
- supervisionMaxBackoffMsHint: "Supervised retry backoff cap.",
136
- todoEnabled: "Todo continuation",
137
- todoEnabledHint: "Todo continuation driver switch (true/false).",
138
- todoMaxConsecutive: "Auto-continuation cap",
139
- todoMaxConsecutiveHint: "Auto-continuation cap without user input.",
140
- todoErrorRetryMax: "Provider-error retry cap",
141
- todoErrorRetryMaxHint: "Provider-error retry cap.",
142
- todoErrorBackoffBaseMs: "Provider-error initial backoff (ms)",
143
- todoErrorBackoffBaseMsHint: "Provider-error retry initial backoff.",
144
- todoErrorBackoffCapMs: "Provider-error backoff cap (ms)",
145
- todoErrorBackoffCapMsHint: "Provider-error retry backoff cap.",
133
+ supervisionMaxRetries: "Child retry limit",
134
+ supervisionMaxRetriesHint: "How many times a supervised child is continued when it ends without a report or keeps failing (default 5).",
135
+ supervisionInitialBackoffMs: "Initial retry backoff (ms)",
136
+ supervisionInitialBackoffMsHint: "Wait before the first retry; doubles each round (default 30000).",
137
+ supervisionMaxBackoffMs: "Maximum retry backoff (ms)",
138
+ supervisionMaxBackoffMsHint: "The retry wait never grows past this (default 300000).",
139
+ todoEnabled: "Auto-continuation",
140
+ todoEnabledHint: "With unfinished todos the assistant keeps going without waiting for your message (default on).",
141
+ todoMaxConsecutive: "Continuation limit",
142
+ todoMaxConsecutiveHint: "At most this many consecutive auto-continuations without your input (default 8).",
143
+ todoErrorRetryMax: "Error retry limit",
144
+ todoErrorRetryMaxHint: "How many times a provider error is retried automatically (default 5).",
146
145
  guardEnabled: "Context pressure guard",
147
- guardEnabledHint: "Context pressure guard switch (true/false).",
148
- guardSoftThreshold: "Soft pressure threshold",
149
- guardSoftThresholdHint: "Soft pressure threshold (advisory).",
150
- guardHardThreshold: "Hard pressure threshold",
151
- guardHardThresholdHint: "Hard pressure threshold (forced compaction).",
146
+ guardEnabledHint: "As the context fills up, asks the assistant to wrap up and requests compaction before it overflows; applies immediately.",
147
+ guardSoftThreshold: "Advisory threshold",
148
+ guardSoftThresholdHint: "Above this fill ratio the assistant is asked to wrap up (default 0.72; must stay below the compaction threshold).",
149
+ guardHardThreshold: "Compaction threshold",
150
+ guardHardThresholdHint: "Above this fill ratio compaction is requested (default 0.88; not a completion guarantee).",
152
151
  hashlineHideStockEdit: "Anchor editing only",
153
- hashlineHideStockEditHint: "Hide the stock edit tool, leaving hash_edit as the only editor (true/false).",
152
+ hashlineHideStockEditHint: "Hides the built-in edit tool; file edits go through hash_edit anchors only.",
154
153
  editLockEnabled: "Edit Lock",
155
154
  editLockLabel: "Edit Lock",
156
155
  editLockTitle: "Files this session is editing",
@@ -162,7 +161,8 @@ window.__ModuleLoader__.load({
162
161
  editLockResume: "Continue editing",
163
162
  editLockRetry: "Retry connection",
164
163
  editLockRetryPending: "Retrying connection… Editing remains unavailable.",
165
- editLockBinding_serving: "The original holder is still serving. Disconnect it there before retrying. Retry does not continue editing.",
164
+ editLockBinding_serving: "This session is being edited in another attachment right now. Retry the connection when that turn finishes; retry does not continue editing.",
165
+ editLockBinding_transferable: "This session's editing authority is held by an inactive attachment of this same session. It attaches here automatically when you send a message; Retry connection also takes it over now (retry does not continue editing).",
166
166
  editLockBinding_unknown: "The holder cannot be verified. Wait for its disconnect or confirmed process shutdown, then retry. Never remove a live publisher reservation.",
167
167
  "editLockBinding_cross-process": "The holder is in another process. Disconnect it or confirm that process has shut down before retrying.",
168
168
  "editLockBinding_revocation-failed": "Durable revocation was not acknowledged. Inspect Edit Lock maintenance; no replacement has been granted.",
@@ -199,24 +199,14 @@ window.__ModuleLoader__.load({
199
199
  editLockRow_confirm: "Continue",
200
200
  editLockRow_unlock: "Unlock",
201
201
  editLockRow_unlockConfirm: "Unlock now — the other session loses this file",
202
- editLockEnabledHint: "Lets sessions take turns editing the same files instead of overwriting each other. Applies after restarting DeepSeek Harness.",
202
+ editLockEnabledHint: "Sessions take turns editing the same files instead of overwriting each other.",
203
203
  editLockOptOutWarning: "Edit Lock is set to off. After saving, restart DeepSeek Harness to apply the change. Once enforcement is off, ordinary editing is UNPROTECTED and can overwrite another session's work. Old fences and history are retained and may block files when you re-enable Edit Lock.",
204
- editLockHoldDefaultMinutes: "Edit Lock: how long files stay reserved after a turn ends when the assistant gives no period",
205
- editLockHoldSingleMaxMinutes: "Edit Lock: most minutes one reservation may last",
206
- editLockHoldCumulativeMaxMinutes: "Edit Lock: total minutes one batch of files may stay reserved after a turn ends",
207
- editLockNudgeAttempts: "Edit Lock: how many times a finished turn is continued to settle left-over files",
208
- editLockNudgeFallback: "Edit Lock: what happens when those reminders run out (release / abnormal)",
209
- editLockAutoResume: "Edit Lock: your next message resumes a stopped session automatically",
210
- editLockAutoResumeHint: "After you stop a session, sending any message restores its editing right and re-confirms its files — no manual Continue needed (default on). Turn off to always confirm by hand.",
211
- editLockStaleSweep: "Edit Lock: silently sweep locks whose file is gone",
212
- editLockStaleSweepHint: "On any message you send, locks whose target file was deleted or moved are quietly released after re-verification at the arbitration point (default on). Turn off to keep manual unlock only.",
213
- editLockHoldDefaultMinutesHint: "Minutes a file stays reserved after a turn ends when the assistant gives no period (default 30).",
214
- editLockHoldSingleMaxMinutesHint: "Upper bound for one reservation request, in minutes (default 30).",
215
- editLockHoldCumulativeMaxMinutesHint: "Total minutes one batch of files may stay reserved after turns end; once it is used up only releasing remains (default 120).",
216
- editLockNudgeAttemptsHint: "How many times a finished turn is continued to ask for left-over files to be released or reserved (default 2).",
217
- editLockNudgeFallbackHint: "release frees those files for other sessions; abnormal keeps them for you to sort out (default release).",
204
+ editLockAutoResume: "Message resumes editing",
205
+ editLockAutoResumeHint: "After a session is stopped, sending any message restores its editing right and re-confirms its kept files (default on).",
206
+ editLockStaleSweep: "Sweep stale locks",
207
+ editLockStaleSweepHint: "Locks whose target file was deleted or moved are re-verified and released as you send messages (default on).",
218
208
  editLockMaint: "Edit Lock maintenance",
219
- editLockMaintHint: "Profile-wide enforcement status and read-only authority diagnostics.",
209
+ editLockMaintHint: "Profile-wide enforcement status and read-only diagnostics.",
220
210
  editLockMaintFailed: "Edit Lock maintenance failed",
221
211
  editLockMaintLoading: "Loading…",
222
212
  editLockMaintUnavailable: "Maintenance data unavailable:",
@@ -277,59 +267,53 @@ window.__ModuleLoader__.load({
277
267
  editLockMaintRecoverDone: "Settled at revision {revision}; admission is unblocked and the unknown outcome stays in history.",
278
268
  editLockMaintRecoverFailed: "Recovery not acknowledged:",
279
269
  worktreeEnabled: "Worktree lanes",
280
- worktreeEnabledHint: "Master switch: lane tools, the /worktree command, Worktree mode, and the Worktrees panel (true/false).",
281
- worktreeAutoSetup: "Install dependencies in new lanes",
282
- worktreeAutoSetupHint: "Run the repository's setup (or the lockfile's install command) when a lane opens (true/false).",
270
+ worktreeEnabledHint: "Lets the assistant work in isolated git worktrees: lane tools, the /worktree command, and the lanes panel.",
271
+ worktreeAutoSetup: "Auto-install in new lanes",
272
+ worktreeAutoSetupHint: "Runs the repository's configured install command when a lane opens (default on).",
283
273
  worktreeMaxActive: "Active lane limit",
284
- worktreeMaxActiveHint: "How many lanes may be active per repository at once (default 4).",
274
+ worktreeMaxActiveHint: "At most this many active lanes per repository (default 4).",
285
275
  worktreeRoot: "Lane directory",
286
- worktreeRootHint: "Repository-relative folder for lanes (default .weir/worktrees). It is ignored locally through .git/info/exclude; nothing tracked changes.",
287
- worktreeWatchTimeoutMinutes: "Lane watch timeout",
288
- worktreeWatchTimeoutMinutesHint: "Minutes a worktree_watch subscription waits for its target states before expiring with one notice (default 360 = 6 hours, minimum 1). Existing watches keep their original deadline.",
289
- worktreeAutoApprove: "Lane auto-approve default",
290
- worktreeAutoApproveHint: "Default auto-approve mode for NEW sessions: manual asks on every card; auto-keep merges/abandons without cards and removes the worktree but keeps the branch; auto-clean also deletes the branch. A session's /worktree approve overrides this.",
276
+ worktreeRootHint: "Repository-relative directory holding lanes (default .weir/worktrees; locally git-ignored).",
277
+ worktreeWatchTimeoutMinutes: "Lane watch timeout (minutes)",
278
+ worktreeWatchTimeoutMinutesHint: "A lane-state watch expires with one notice after this long without a hit (default 360); existing watches keep their deadline.",
279
+ worktreeAutoApprove: "Lane auto-approve",
280
+ worktreeAutoApproveHint: "Default approval mode for new sessions: manual asks every time; auto-keep approves and keeps the branch; auto-clean also deletes it; /worktree approve overrides per session.",
291
281
  worktreeAutoApproveOptionManual: "manual",
292
282
  "worktreeAutoApproveOptionAuto-keep": "auto-keep",
293
283
  "worktreeAutoApproveOptionAuto-clean": "auto-clean",
294
- robashEnabled: "Read-only bash guard",
295
- robashEnabledHint: "Guarded read-only bash for curated agents, master switch (true/false).",
296
- robashAllow: "Allow list additions",
297
- robashAllowHint: "Command names to ADD to the read-only bash guard's product defaults. The defaults are always in effect; leaving this empty adds nothing (it cannot clear the defaults).",
298
- robashGitAllow: "Git subcommand additions",
299
- robashGitAllowHint: "Git subcommands to ADD to the read-only bash guard's product defaults (shared with the pwsh git gate). Leaving this empty adds nothing.",
300
- robashDeny: "Deny list additions",
301
- robashDenyHint: "Command names to ADD to the read-only bash guard's product deny list. The product defaults always stay denied; leaving this empty adds nothing.",
302
- robashPwshAllow: "Pwsh allow list additions",
303
- robashPwshAllowHint: "Command names to ADD to the read-only pwsh guard's product defaults (Windows read-only shell). The defaults are always in effect; leaving this empty adds nothing.",
304
- robashPwshDeny: "Pwsh deny list additions",
305
- robashPwshDenyHint: "Command names to ADD to the read-only pwsh guard's product deny list (Windows read-only shell). The product defaults always stay denied.",
284
+ robashEnabled: "Read-only shell guard",
285
+ robashEnabledHint: "Curated read-only agents (finder etc.) may only run allow-listed read-only commands (default on).",
286
+ robashAllow: "Extra allowed commands",
287
+ robashAllowHint: "Command names added on top of the built-in allow list; built-ins always apply, empty adds nothing.",
288
+ robashGitAllow: "Extra allowed git subcommands",
289
+ robashGitAllowHint: "Git subcommands added on top of the built-in list (shared with the pwsh gate); empty adds nothing.",
290
+ robashDeny: "Extra denied commands",
291
+ robashDenyHint: "Command names added on top of the built-in deny list; deny wins over allow.",
292
+ robashPwshAllow: "Extra allowed pwsh commands",
293
+ robashPwshAllowHint: "Additions to the Windows read-only pwsh allow list; built-ins always apply.",
294
+ robashPwshDeny: "Extra denied pwsh commands",
295
+ robashPwshDenyHint: "Additions to the Windows read-only pwsh deny list; deny wins over allow.",
306
296
  robashListEntries: "entries",
307
297
  robashListAdd: "Add entry",
308
- robashListInvalid: "The stored value is not a JSON string array; the editor opened with an empty list — saving replaces the stored value.",
309
- robashListPanelHint: "One command name per row. These entries are ADDED to the product defaults, which stay in effect — saving an empty list adds nothing and never removes a default.",
298
+ robashListInvalid: "The stored value is not a valid command list; the editor opened empty — saving replaces it.",
299
+ robashListPanelHint: "One command name per row; entries are added to the built-in list, which always applies — an empty list adds nothing.",
310
300
  robashListEntryPlaceholder: "command name",
311
301
  lspEnabled: "LSP semantic tools",
312
- lspEnabledHint: "Capability master switch: off removes LSP entirely; on adds a per-session switch in the composer bar (sessions start with LSP off).",
313
- lspIdleMs: "Server idle shutdown (ms)",
314
- lspIdleMsHint: "Idle servers shut down after this many milliseconds.",
315
- lspRequestTimeoutMs: "Request timeout (ms)",
316
- lspRequestTimeoutMsHint: "Per-request LSP timeout; timeouts are ordinary tool errors.",
317
- lspDiagnosticsWaitMs: "Diagnostics wait (ms)",
318
- lspDiagnosticsWaitMsHint: "How long to wait for published diagnostics before answering.",
319
- lspServers: "Custom LSP servers (JSON)",
320
- lspServersHint: "Custom language server definitions, edited visually in this row's LSP manager panel.",
302
+ lspEnabledHint: "When on, each session can enable go-to-definition, find-references and friends from its composer switch (sessions start off).",
303
+ lspServers: "Custom language servers",
304
+ lspServersHint: "Add language servers beyond the built-in catalog, edited visually in the manager panel.",
321
305
  notifyEnabled: "System notifications",
322
- notifyEnabledHint: "Master switch: send a system notification when a session needs you or a turn finishes (true/false).",
306
+ notifyEnabledHint: "Sends a system notification when a session needs you or a turn finishes (default on).",
323
307
  notifyOnComplete: "Notify on completion",
324
- notifyOnCompleteHint: "Notify when a turn finishes, once it has run longer than the minimum below (true/false).",
325
- notifyOnAttention: "Notify when you are needed",
326
- notifyOnAttentionHint: "Notify on approval requests, questions, plan reviews, and failed or stopped turns (true/false).",
308
+ notifyOnCompleteHint: "Notifies when a turn finishes and ran longer than the minimum below.",
309
+ notifyOnAttention: "Notify when needed",
310
+ notifyOnAttentionHint: "Notifies on approval requests, questions, plan reviews, and failed or stopped turns.",
327
311
  notifyMinTurnSeconds: "Minimum turn length (seconds)",
328
- notifyMinTurnSecondsHint: "A finished turn is only reported when it ran at least this long; 0 reports every turn.",
312
+ notifyMinTurnSecondsHint: "A finished turn is only reported when it ran at least this long; 0 reports every turn (default 15).",
329
313
  notifySound: "Notification sound",
330
- notifySoundHint: "Play the platform notification sound where supported (true/false).",
314
+ notifySoundHint: "Plays the platform notification sound where supported.",
331
315
  notifyForeground: "When the window is in front",
332
- notifyForegroundHint: "Whether to notify while the DeepSeek Harness window is in the foreground. Skip stays quiet (you are already looking at it); Always notifies anyway.",
316
+ notifyForegroundHint: "Whether to notify while the window is in the foreground: don't notify (default) or always notify.",
333
317
  notifyForegroundOptionSkip: "Don't notify",
334
318
  notifyForegroundOptionAlways: "Always notify",
335
319
  notifyPermissions: "Notification permission",
@@ -732,6 +716,7 @@ window.__ModuleLoader__.load({
732
716
  "blackboard.entries": "{n} entries",
733
717
  "blackboard.loading": "Loading the board…",
734
718
  "blackboard.unavailable": "Blackboard unavailable for this session.",
719
+ "blackboard.parentBoard": "Showing the parent conversation's board.",
735
720
  "blackboard.retry": "Retry",
736
721
  "blackboard.empty": "The board is empty.",
737
722
  "blackboard.emptyDesc": "Findings agents write to this session's board appear here.",
@@ -793,7 +778,9 @@ window.__ModuleLoader__.load({
793
778
  };
794
779
  const zh = {
795
780
  title: "Weir",
796
- description: "Weir 预设的一站式配置:意图分类、模型链、续推、上下文压力、编辑、只读 bash 与 LSP。",
781
+ description: "Weir 预设的一站式配置:意图分类、自动续推、上下文压力、文件编辑、Worktree 车道、只读命令行、LSP 与系统通知;模型路由为独立页面。",
782
+ routingTitle: "Weir 模型路由",
783
+ routingDescription: "委派给子代理的模型:按任务类别或精选代理指定,可设备选按序回退。",
797
784
  loading: "正在加载 Weir 设置…",
798
785
  loadFailed: "Weir 设置加载失败:",
799
786
  unavailable: "此插件未加载,当前无法配置。",
@@ -801,6 +788,8 @@ window.__ModuleLoader__.load({
801
788
  saveFailed: "部署未接受这些值,已保留供你修正。",
802
789
  save: "保存",
803
790
  saving: "保存中…",
791
+ pendingChanges: "{n} 项未保存的更改",
792
+ discardChanges: "放弃更改",
804
793
  overridden: "已覆盖",
805
794
  reset: "恢复默认",
806
795
  restartRequired: "需重启",
@@ -818,59 +807,58 @@ window.__ModuleLoader__.load({
818
807
  modelEmpty: "选择模型",
819
808
  pickerUnavailable: "模型选择器不可用——请重新加载设置页后重试。",
820
809
  groupIntent: "意图分类",
821
- groupDelegate: "委派与模型链",
822
- groupTodo: "续推",
810
+ groupTodo: "自动续推",
823
811
  groupGuard: "上下文压力",
824
- groupEditing: "编辑",
812
+ groupEditing: "文件编辑",
825
813
  groupWorktree: "Worktree 车道",
826
- groupRobash: "只读 bash",
814
+ groupRobash: "只读命令行",
827
815
  groupLsp: "LSP 语义工具",
828
816
  groupNotify: "系统通知",
829
- groupBlackboard: "黑板",
830
- blackboardWriteTokenTtlMinutes: "黑板写入权有效期(分钟)",
831
- blackboardWriteTokenTtlMinutesHint: "已申请的黑板写入权在此分钟后过期,键被释放并通知其订阅者(默认 60)。立即生效。",
832
- intentGateClassifierOptionRegex: "regex(正则)",
817
+ groupRoutingCategories: "任务类别",
818
+ groupRoutingAgents: "精选代理",
819
+ groupRoutingSupervision: "监督与重试",
820
+ intentGateClassifierOptionRegex: "regex(规则)",
833
821
  intentGateClassifierOptionLlm: "llm(语义)",
834
822
  intentGateClassifierOptionJev: "jev(实验)",
835
823
  intentGateClassifier: "意图分类器",
836
- intentGateClassifierHint: "regex(默认,零成本)、llm(sidecar 语义分类)、jev(实验,默认关闭)。",
837
- intentGateProvider: "分类器 provider(llm 模式)",
838
- intentGateProviderHint: "sidecar 路由覆盖;留空跟随会话路由。",
839
- intentGateModel: "分类器 model(llm 模式)",
840
- intentGateModelHint: "sidecar 模型覆盖;留空跟随会话路由。",
841
- intentGateReasoningEffort: "分类器推理等级(llm 模式)",
842
- intentGateReasoningEffortHint: "sidecar 推理等级覆盖;留空跟随模型默认。",
843
- intentGateTimeoutMs: "分类器超时(毫秒)",
844
- intentGateTimeoutMsHint: "超时按正则结果 fail-open。",
824
+ intentGateClassifierHint: "如何识别每条消息的意图:regex 用内置规则,零成本(默认);llm 用独立小模型做语义分类;jev 为实验实现。",
825
+ intentGateProvider: "分类器模型(llm 模式)",
826
+ intentGateProviderHint: "为语义分类单独指定的模型;留空跟随会话当前模型。",
827
+ intentGateModel: "分类器模型名(llm 模式)",
828
+ intentGateModelHint: "留空跟随会话路由所用模型。",
829
+ intentGateReasoningEffort: "分类器推理档位(llm 模式)",
830
+ intentGateReasoningEffortHint: "留空跟随模型默认。",
831
+ intentGateTimeoutMs: "分类超时(毫秒)",
832
+ intentGateTimeoutMsHint: "超过该时长按规则分类结果继续,不阻塞消息(默认 1500)。",
845
833
  jevEndpoint: "Jev 端点",
846
- jevEndpointHint: "Jev 决策端点(实验模式)。",
834
+ jevEndpointHint: "Jev 决策服务地址(实验模式)。",
847
835
  jevModel: "Jev 模型",
848
- jevModelHint: "Jev 模型名(实验模式)。",
836
+ jevModelHint: "Jev 使用的模型名(默认 jev)。",
849
837
  jevApiKeyEnv: "Jev 密钥环境变量名",
850
- jevApiKeyEnvHint: "持有 Jev API 密钥的环境变量名(密钥本身永不入配置)。",
851
- delegateCategoryChains: "类别模型链(JSON)",
852
- delegateCategoryChainsHint: "每个类别的子代理跑哪个模型,可视化配置;档位按序回退。",
853
- delegateAgentChains: "精选 agent 模型链(JSON)",
854
- delegateAgentChainsHint: "每个精选 agent 跑哪个模型,可视化配置;空车道继承调用方路由。",
855
- delegateDisabledCategories: "停用类别",
856
- delegateDisabledCategoriesHint: "从注册表清单勾选要停用的类别:停用类别从委派目标清单消失且不可派发。只能追加停用——注册表级 disabled 始终生效,无法在此清除;未知名已无法通过此控件写入。",
838
+ jevApiKeyEnvHint: "存放 Jev API 密钥的环境变量名;密钥本身不写入配置。",
839
+ delegateCategoryChains: "任务类别模型",
840
+ delegateCategoryChainsHint: "每类任务委派给子代理时使用的模型;可添加备选按序回退,留空跟随会话模型。",
841
+ delegateAgentChains: "精选代理模型",
842
+ delegateAgentChainsHint: "finder、scholar、advisor 各自运行的模型;留空继承调用方路由。",
843
+ delegateDisabledCategories: "停用任务类别",
844
+ delegateDisabledCategoriesHint: "停用的类别从委派清单中移除,助手无法再委派这类任务。",
857
845
  disabledCategoriesCount: "个已停用",
858
- disabledCategoriesPanelHint: "每个类别一个开关。保存时只写入打开的类别名;全部关闭则保存空数组,服务器视为「未停用任何类别」。",
859
- disabledCategoriesInvalid: "已保存的值不是 JSON 字符串数组;编辑器已以全部关闭打开——保存将覆盖该值。",
846
+ disabledCategoriesPanelHint: "每个类别一个开关;保存只写入打开的类别,全部关闭即不停用任何类别。",
847
+ disabledCategoriesInvalid: "已保存的值不是有效的类别清单;编辑器已以全部关闭打开,保存将覆盖该值。",
860
848
  chainAgent_finder: "finder(检索)",
861
849
  chainAgent_finder_desc: "代码库上下文检索:回答「X 在哪里」「做 Z 的代码在哪」。只读、快速、并行优先。",
862
850
  chainAgent_scholar: "scholar(调研)",
863
851
  chainAgent_scholar_desc: "文档与 OSS 调研:官方文档、库 API、最佳实践、真实用法。只读。",
864
852
  chainAgent_advisor: "advisor(架构)",
865
853
  chainAgent_advisor_desc: "架构与设计顾问:模块边界、拆分、权衡。只读、高推理。",
866
- chainAgentPanelHint: "按精选 agent 车道挑选模型;空车道继承调用方路由。档位按序回退,首选不可用时用下一个。",
854
+ chainAgentPanelHint: "每个精选代理一行;留空继承调用方路由,备选按序回退。",
867
855
  chainEdit: "编辑",
868
- chainPanelHint: "按类别车道挑选模型;空车道继承会话路由。档位按序回退,首选不可用时用下一个。",
856
+ chainPanelHint: "每个类别一行:点「编辑」挑选模型,可添加备选按序回退;留空的类别跟随会话模型。",
869
857
  chainSave: "保存",
870
858
  chainCancel: "取消",
871
- chainAddRung: "添加档位",
859
+ chainAddRung: "添加备选",
872
860
  chainRemove: "删除",
873
- chainClear: "清空(恢复继承)",
861
+ chainClear: "清空(跟随会话)",
874
862
  chainCategory_quick: "quick(快活)",
875
863
  chainCategory_quick_desc: "机械性小活:单文件修改、错别字、样板代码。",
876
864
  chainCategory_deep: "deep(攻坚)",
@@ -881,38 +869,34 @@ window.__ModuleLoader__.load({
881
869
  chainCategory_visual_desc: "前端、UI/UX、样式、动画、布局。",
882
870
  chainCategory_writing: "writing(写作)",
883
871
  chainCategory_writing_desc: "文档、散文、技术写作、README 与指南。",
884
- "chainCategory_general-low": "general-low(通用低)",
872
+ "chainCategory_general-low": "general-low(通用·轻量)",
885
873
  "chainCategory_general-low_desc": "不属于任何专业类别的小任务。",
886
- "chainCategory_general-high": "general-high(通用高)",
874
+ "chainCategory_general-high": "general-high(通用·标准)",
887
875
  "chainCategory_general-high_desc": "跨几个文件、有既定模式的标准特性。",
888
876
  chainCategory_artistry: "artistry(艺术)",
889
877
  chainCategory_artistry_desc: "高度创意或艺术性任务、新颖想法、设计探索。",
890
878
  chainCategory_architect: "architect(架构)",
891
879
  chainCategory_architect_desc: "咨询式架构评估:模块边界、拆分、权衡(只读)。",
892
- supervisionMaxRetries: "监督续推上限",
893
- supervisionMaxRetriesHint: "受监督续推连续上限。",
894
- supervisionInitialBackoffMs: "监督续推初始退避(毫秒)",
895
- supervisionInitialBackoffMsHint: "受监督重试初始退避。",
896
- supervisionMaxBackoffMs: "监督续推退避封顶(毫秒)",
897
- supervisionMaxBackoffMsHint: "受监督重试退避封顶。",
898
- todoEnabled: "todo 续推",
899
- todoEnabledHint: "todo 空转续推开关(true/false)。",
900
- todoMaxConsecutive: "自动续推上限",
901
- todoMaxConsecutiveHint: "无用户输入时的自动续推上限。",
902
- todoErrorRetryMax: "供应商错误重试上限",
903
- todoErrorRetryMaxHint: "供应商错误连续重试上限。",
904
- todoErrorBackoffBaseMs: "供应商错误初始退避(毫秒)",
905
- todoErrorBackoffBaseMsHint: "供应商错误重试初始退避。",
906
- todoErrorBackoffCapMs: "供应商错误退避封顶(毫秒)",
907
- todoErrorBackoffCapMsHint: "供应商错误重试退避封顶。",
880
+ supervisionMaxRetries: "子代理续推上限",
881
+ supervisionMaxRetriesHint: "受监督子代理未交结果或连续出错时,最多自动续推几次(默认 5)。",
882
+ supervisionInitialBackoffMs: "重试初始间隔(毫秒)",
883
+ supervisionInitialBackoffMsHint: "首次重试前的等待时间,之后逐次加倍(默认 30000)。",
884
+ supervisionMaxBackoffMs: "重试间隔上限(毫秒)",
885
+ supervisionMaxBackoffMsHint: "重试间隔最多增长到该值(默认 300000)。",
886
+ todoEnabled: "自动续推",
887
+ todoEnabledHint: "有待办未完成时,助手自动继续推进,无需你发消息(默认开启)。",
888
+ todoMaxConsecutive: "连续续推上限",
889
+ todoMaxConsecutiveHint: "没有你输入时最多连续自动续推几轮(默认 8)。",
890
+ todoErrorRetryMax: "出错重试上限",
891
+ todoErrorRetryMaxHint: "模型供应商报错时最多自动重试几次(默认 5)。",
908
892
  guardEnabled: "上下文压力守卫",
909
- guardEnabledHint: "上下文压力守卫开关(true/false)。",
910
- guardSoftThreshold: "软阈值",
911
- guardSoftThresholdHint: "上下文压力软阈值(提示)。",
912
- guardHardThreshold: "硬阈值",
913
- guardHardThresholdHint: "上下文压力硬阈值(强制压缩)。",
914
- hashlineHideStockEdit: "仅锚点编辑",
915
- hashlineHideStockEditHint: "隐藏 stock edit,hash_edit 成为唯一编辑器(true/false)。",
893
+ guardEnabledHint: "上下文将满时提醒助手收尾并请求压缩,避免超限报错;即时生效。",
894
+ guardSoftThreshold: "提醒阈值",
895
+ guardSoftThresholdHint: "上下文用量超过该比例时提醒助手收尾(默认 0.72,须小于压缩阈值)。",
896
+ guardHardThreshold: "压缩阈值",
897
+ guardHardThresholdHint: "上下文用量超过该比例时请求立即压缩(默认 0.88,不保证压缩完成)。",
898
+ hashlineHideStockEdit: "仅用锚点编辑",
899
+ hashlineHideStockEditHint: "隐藏内置 edit 工具,文件修改一律走 hash_edit 锚点编辑。",
916
900
  editLockEnabled: "编辑锁",
917
901
  editLockLabel: "编辑锁",
918
902
  editLockTitle: "本会话正在编辑的文件",
@@ -924,7 +908,8 @@ window.__ModuleLoader__.load({
924
908
  editLockResume: "继续编辑",
925
909
  editLockRetry: "重试连接",
926
910
  editLockRetryPending: "正在重试连接……编辑仍不可用。",
927
- editLockBinding_serving: "原持有者仍在服务。请先在原会话断开,再重试;重试不等于继续编辑。",
911
+ editLockBinding_serving: "本会话正在另一个附着位置编辑中。请在该回合结束后重试连接;重试不等于继续编辑。",
912
+ editLockBinding_transferable: "本会话的编辑权由同一会话的一个不活跃附着持有。你发送下一条消息时会自动接管;也可以立即点「重试连接」接管(重试不等于继续编辑)。",
928
913
  editLockBinding_unknown: "无法核实原持有者。请等待原连接断开或确认其进程已退出,再重试;勿删除存活 publisher 的预约。",
929
914
  "editLockBinding_cross-process": "原持有者位于另一进程。请先断开原连接或确认其进程已退出,再重试。",
930
915
  "editLockBinding_revocation-failed": "持久撤权尚未确认。请查看编辑锁维护;未授予替代绑定权限。",
@@ -961,24 +946,14 @@ window.__ModuleLoader__.load({
961
946
  editLockRow_confirm: "继续",
962
947
  editLockRow_unlock: "解锁",
963
948
  editLockRow_unlockConfirm: "确认解锁——对方会失去这个文件",
964
- editLockEnabledHint: "让多个会话轮流编辑同一批文件,而不是相互覆盖。重启 DeepSeek Harness 后生效。",
949
+ editLockEnabledHint: "多个会话轮流编辑同一批文件,而不是互相覆盖。",
965
950
  editLockOptOutWarning: "编辑锁已设为关闭。保存后须重启 DeepSeek Harness 才会生效。停用强制执行后,普通编辑不受保护,可能覆盖其他会话的工作。旧围栏与历史仍会保留,重新启用编辑锁时可能再次阻塞文件。",
966
- editLockHoldDefaultMinutes: "编辑锁:回合结束后保留文件多久(助手未指定时)",
967
- editLockHoldSingleMaxMinutes: "编辑锁:单次申请最多保留多少分钟",
968
- editLockHoldCumulativeMaxMinutes: "编辑锁:一批文件回合结束后累计最多保留多少分钟",
969
- editLockNudgeAttempts: "编辑锁:回合结束后最多提醒几次去处理未释放的文件",
970
- editLockNudgeFallback: "编辑锁:提醒用完后的处置(release 自动释放 / abnormal 转为人工处理)",
971
- editLockAutoResume: "编辑锁:停止后发送消息即自动恢复编辑",
972
- editLockAutoResumeHint: "停止会话后,发送任意消息即恢复其编辑权限并确认保留的文件,无需手动点「继续编辑」(默认开启)。关闭则仍走手动确认。",
973
- editLockStaleSweep: "编辑锁:静默清理目标已消失的失效锁",
974
- editLockStaleSweepHint: "你发送任意消息时,目标文件已被删除或移动的锁会在仲裁点复核后被静默释放(默认开启)。关闭则只能手动解锁。",
975
- editLockHoldDefaultMinutesHint: "助手未指定时,文件在回合结束后继续保留的分钟数(默认 30)。",
976
- editLockHoldSingleMaxMinutesHint: "单次保留申请的上限分钟数(默认 30)。",
977
- editLockHoldCumulativeMaxMinutesHint: "一批文件在回合结束后累计最多保留的分钟数;用尽后只能释放(默认 120)。",
978
- editLockNudgeAttemptsHint: "回合结束后最多提醒几次,去处理未释放的文件(默认 2)。",
979
- editLockNudgeFallbackHint: "release 把文件让给其他会话;abnormal 保留下来等你处理(默认 release)。",
951
+ editLockAutoResume: "发消息即恢复编辑",
952
+ editLockAutoResumeHint: "会话被停止后,发送任意消息即自动恢复其编辑权并确认保留的文件(默认开启)。",
953
+ editLockStaleSweep: "自动清理失效锁",
954
+ editLockStaleSweepHint: "目标文件已被删除或移动的锁,在你发消息时自动复核并释放(默认开启)。",
980
955
  editLockMaint: "编辑锁维护",
981
- editLockMaintHint: "整个 profile 的强制执行状态与只读权威诊断。",
956
+ editLockMaintHint: "查看全 profile 的强制执行状态与只读诊断。",
982
957
  editLockMaintFailed: "编辑锁维护面板加载失败",
983
958
  editLockMaintLoading: "加载中……",
984
959
  editLockMaintUnavailable: "维护数据不可用:",
@@ -1039,59 +1014,53 @@ window.__ModuleLoader__.load({
1039
1014
  editLockMaintRecoverDone: "已在 revision {revision} 结清;准入阻塞解除,历史仍保持未知。",
1040
1015
  editLockMaintRecoverFailed: "恢复未确认:",
1041
1016
  worktreeEnabled: "Worktree 车道",
1042
- worktreeEnabledHint: "总开关:车道工具、/worktree 命令、Worktree 模式与 Worktrees 面板(true/false)。",
1017
+ worktreeEnabledHint: "让助手在隔离的 git worktree 中工作:车道工具、/worktree 命令与车道面板。",
1043
1018
  worktreeAutoSetup: "新车道自动安装依赖",
1044
- worktreeAutoSetupHint: "开车道时执行仓库配置的 setup,或按 lockfile 推导的安装命令(true/false)。",
1019
+ worktreeAutoSetupHint: "开车道时自动执行仓库配置的安装命令(默认开启)。",
1045
1020
  worktreeMaxActive: "活跃车道上限",
1046
- worktreeMaxActiveHint: "每个仓库同时活跃的车道数上限(默认 4)。",
1021
+ worktreeMaxActiveHint: "每个仓库最多同时活跃几条车道(默认 4)。",
1047
1022
  worktreeRoot: "车道目录",
1048
- worktreeRootHint: "仓库内存放车道的相对目录(默认 .weir/worktrees),通过 .git/info/exclude 本地忽略,不改动任何入库文件。",
1049
- worktreeWatchTimeoutMinutes: "车道订阅超时",
1050
- worktreeWatchTimeoutMinutesHint: "worktree_watch 订阅等待目标状态的分钟数,到期投递一条过期通知(默认 360 = 6 小时,最小 1);已建立的订阅按建立时的期限不变。",
1051
- worktreeAutoApprove: "车道自动授权默认",
1052
- worktreeAutoApproveHint: "新会话的初始自动授权模式:manual 每张卡片都要批准;auto-keep 自动批准合并/放弃并清理 worktree 但保留分支;auto-clean 连分支一起删除。会话内 /worktree approve 可覆盖。",
1023
+ worktreeRootHint: "车道存放在仓库内的相对目录(默认 .weir/worktrees,已通过 .git/info/exclude 本地忽略)。",
1024
+ worktreeWatchTimeoutMinutes: "车道订阅有效期(分钟)",
1025
+ worktreeWatchTimeoutMinutesHint: "订阅车道状态后,超过该时长未命中即过期并通知一次(默认 360);已建立的订阅不变。",
1026
+ worktreeAutoApprove: "车道自动授权",
1027
+ worktreeAutoApproveHint: "新会话的默认审批方式:manual 每次都问;auto-keep 自动批准并保留分支;auto-clean 自动批准并删除分支;会话内 /worktree approve 可覆盖。",
1053
1028
  worktreeAutoApproveOptionManual: "manual(手动)",
1054
1029
  "worktreeAutoApproveOptionAuto-keep": "auto-keep(保留分支)",
1055
1030
  "worktreeAutoApproveOptionAuto-clean": "auto-clean(清理分支)",
1056
- robashEnabled: "只读 bash 守卫",
1057
- robashEnabledHint: "精选只读代理的受守卫 bash 总开关(true/false)。",
1058
- robashAllow: "允许列表",
1059
- robashAllowHint: "追加到只读 bash 守卫产品默认项的命令名。默认项始终生效;留空表示不追加(无法清空默认项)。",
1060
- robashGitAllow: "git 子命令允许列表",
1061
- robashGitAllowHint: "追加到只读 bash 守卫产品默认项的 git 子命令(与 pwsh 的 git 门控共用)。留空表示不追加。",
1062
- robashDeny: "拒绝列表",
1063
- robashDenyHint: "追加到只读 bash 守卫产品拒绝列表的命令名。产品默认拒绝项始终生效;留空表示不追加。",
1064
- robashPwshAllow: "pwsh 允许列表",
1065
- robashPwshAllowHint: "追加到只读 pwsh 守卫产品默认项的命令名(Windows 只读 shell)。默认项始终生效;留空表示不追加。",
1066
- robashPwshDeny: "pwsh 拒绝列表",
1067
- robashPwshDenyHint: "追加到只读 pwsh 守卫产品拒绝列表的命令名(Windows 只读 shell)。产品默认拒绝项始终生效。",
1031
+ robashEnabled: "只读命令行守卫",
1032
+ robashEnabledHint: "精选只读代理(finder 等)只能运行允许清单内的只读命令(默认开启)。",
1033
+ robashAllow: "额外允许的命令",
1034
+ robashAllowHint: "在内置允许清单之上追加的命令名;内置清单始终生效,留空即不追加。",
1035
+ robashGitAllow: "额外允许的 git 子命令",
1036
+ robashGitAllowHint: "追加的 git 只读子命令(与 pwsh 侧共用);留空即不追加。",
1037
+ robashDeny: "额外禁止的命令",
1038
+ robashDenyHint: "在内置禁止清单之上追加的命令名;禁止优先于允许。",
1039
+ robashPwshAllow: "额外允许的 pwsh 命令",
1040
+ robashPwshAllowHint: "Windows 只读 pwsh 的追加允许项;内置清单始终生效。",
1041
+ robashPwshDeny: "额外禁止的 pwsh 命令",
1042
+ robashPwshDenyHint: "Windows 只读 pwsh 的追加禁止项;禁止优先于允许。",
1068
1043
  robashListEntries: "条目",
1069
1044
  robashListAdd: "添加条目",
1070
- robashListInvalid: "已保存的值不是 JSON 字符串数组;编辑器已以空列表打开——保存将覆盖该值。",
1071
- robashListPanelHint: "每行一个命令名。这些条目会追加到产品默认项,默认项始终生效——保存空列表只表示不追加,不会移除任何默认项。",
1045
+ robashListInvalid: "已保存的值不是有效的命令清单;编辑器已以空列表打开,保存将覆盖该值。",
1046
+ robashListPanelHint: "每行一个命令名;条目追加到内置清单,内置清单始终生效——空列表即不追加。",
1072
1047
  robashListEntryPlaceholder: "命令名",
1073
1048
  lspEnabled: "LSP 语义工具",
1074
- lspEnabledHint: "能力总开关:关闭则完全移除 LSP;开启后输入栏出现本会话开关(新会话默认关,按会话启用)。",
1075
- lspIdleMs: "服务器空闲关停(毫秒)",
1076
- lspIdleMsHint: "空闲的语言服务器超过该时长自动关停。",
1077
- lspRequestTimeoutMs: "请求超时(毫秒)",
1078
- lspRequestTimeoutMsHint: "单请求 LSP 超时;超时为普通工具错误。",
1079
- lspDiagnosticsWaitMs: "诊断等待(毫秒)",
1080
- lspDiagnosticsWaitMsHint: "回答前等待诊断发布的窗口时长。",
1081
- lspServers: "自定义 LSP 服务器(JSON)",
1082
- lspServersHint: "自定义语言服务器定义,经本行的 LSP 管理面板可视化编辑。",
1049
+ lspEnabledHint: "开启后,每个会话可在输入栏单独启用定义跳转、引用查找等语言服务(会话默认关)。",
1050
+ lspServers: "自定义语言服务器",
1051
+ lspServersHint: "添加内置清单之外的语言服务器,在管理面板中可视化配置。",
1083
1052
  notifyEnabled: "系统通知",
1084
- notifyEnabledHint: "总开关:会话需要你处理、或一轮任务结束时发送系统通知(true/false)。",
1053
+ notifyEnabledHint: "会话需要你处理或一轮任务结束时发送系统通知(默认开启)。",
1085
1054
  notifyOnComplete: "完成时通知",
1086
- notifyOnCompleteHint: "一轮任务结束且耗时超过下方最短时长时通知(true/false)。",
1055
+ notifyOnCompleteHint: "一轮任务结束且耗时超过下方最短时长时通知。",
1087
1056
  notifyOnAttention: "需要处理时通知",
1088
- notifyOnAttentionHint: "审批请求、提问、计划评审、任务失败或中止时通知(true/false)。",
1089
- notifyMinTurnSeconds: "最短任务时长(秒)",
1090
- notifyMinTurnSecondsHint: "一轮任务至少运行这么久才会通知完成;0 表示每轮都通知。",
1057
+ notifyOnAttentionHint: "审批请求、提问、计划评审、任务失败或中止时通知。",
1058
+ notifyMinTurnSeconds: "最短通知时长(秒)",
1059
+ notifyMinTurnSecondsHint: "任务至少运行这么久才通知完成;0 表示每轮都通知(默认 15)。",
1091
1060
  notifySound: "通知提示音",
1092
- notifySoundHint: "在支持的平台上播放系统通知提示音(true/false)。",
1061
+ notifySoundHint: "通知时播放系统提示音(平台支持时)。",
1093
1062
  notifyForeground: "窗口在前台时",
1094
- notifyForegroundHint: "DeepSeek Harness 窗口在前台时是否通知。「不通知」表示你正看着窗口、不打扰;「始终通知」则前台也通知。",
1063
+ notifyForegroundHint: "你正看着窗口时是否仍通知:不通知(默认)或始终通知。",
1095
1064
  notifyForegroundOptionSkip: "不通知",
1096
1065
  notifyForegroundOptionAlways: "始终通知",
1097
1066
  notifyPermissions: "通知权限",
@@ -1491,6 +1460,7 @@ window.__ModuleLoader__.load({
1491
1460
  "blackboard.entries": "{n} 条",
1492
1461
  "blackboard.loading": "正在加载黑板…",
1493
1462
  "blackboard.unavailable": "此会话的黑板不可用。",
1463
+ "blackboard.parentBoard": "正在显示父会话的黑板。",
1494
1464
  "blackboard.retry": "重试",
1495
1465
  "blackboard.empty": "黑板为空。",
1496
1466
  "blackboard.emptyDesc": "Agent 写入本会话黑板的发现会出现在这里。",
@@ -1551,6 +1521,12 @@ window.__ModuleLoader__.load({
1551
1521
  const NS = "settings.weir";
1552
1522
  const SECTION_ID = "weir-settings";
1553
1523
  const ITEM_SLOT = "settings.weir.item";
1524
+ // The model-routing settings live on their own page: a second section
1525
+ // registration (order 41, right after the main page) with its own item
1526
+ // slot, its own controller, and the routing-page groups of the shared
1527
+ // settings-page chunk.
1528
+ const ROUTING_SECTION_ID = "weir-model-routing";
1529
+ const ROUTING_ITEM_SLOT = "settings.weir-routing.item";
1554
1530
  // ---- Package-local chunk wiring (composition root) ----
1555
1531
  // Same-package sync require is impossible in the ModuleLoader, so each
1556
1532
  // lazily delivered surface fans out one Promise.all over
@@ -2344,8 +2320,19 @@ window.__ModuleLoader__.load({
2344
2320
  // inject faces (cached by the host on first render) carry a
2345
2321
  // stable deferred store plus delegating actions.
2346
2322
  let controller = null;
2323
+ let routingController = null;
2347
2324
  let serving = true;
2348
2325
  const deferredStore = createDeferredStore();
2326
+ const routingDeferredStore = createDeferredStore();
2327
+ const routingCardFace = {
2328
+ hooks: { weirSettingsCard: routingDeferredStore },
2329
+ edit: (field, text) => routingController?.inject().edit(field, text),
2330
+ resetField: (field) => routingController?.inject().resetField(field),
2331
+ save: (...args) => routingController?.inject().save(...args),
2332
+ discard: () => routingController?.inject().discard(),
2333
+ dismissRestartReminder: () => routingController?.inject().dismissRestartReminder(),
2334
+ getSession: () => ctx.remote.session
2335
+ };
2349
2336
  const cardFace = {
2350
2337
  hooks: { weirSettingsCard: deferredStore },
2351
2338
  edit: (field, text) => controller?.inject().edit(field, text),
@@ -2376,8 +2363,10 @@ window.__ModuleLoader__.load({
2376
2363
  require.async("./client.edit-lock-maintenance.js")
2377
2364
  ]).then(([settingsPage, chainEditor, robashEditor, disabledCategoriesEditor, lspPanel, chainModel, robashModel, lspModel, notifyPermissions, editLockMaintenance]) => {
2378
2365
  if (serving) {
2379
- controller = new settingsPage.WeirCardController(scope, { settingsBus, getSession: () => ctx.remote.session });
2366
+ controller = new settingsPage.WeirCardController(scope, { settingsBus, getSession: () => ctx.remote.session }, "main");
2380
2367
  deferredStore.attach(controller.store);
2368
+ routingController = new settingsPage.WeirCardController(scope, { settingsBus, getSession: () => ctx.remote.session }, "routing");
2369
+ routingDeferredStore.attach(routingController.store);
2381
2370
  }
2382
2371
  // Editor components pre-bound with their model chunks,
2383
2372
  // created once per arrival so their identity is stable
@@ -2409,6 +2398,27 @@ window.__ModuleLoader__.load({
2409
2398
  }
2410
2399
  return react_jsx_runtime.jsx("div", { style: settingsLoadingStyle, children: props.t("loading") });
2411
2400
  }
2401
+ function RoutingSectionWrapper(props) {
2402
+ const sectionArrival = useChunkArrival(ensureSettingsChunks);
2403
+ if (sectionArrival?.chunks) {
2404
+ return react_jsx_runtime.jsx(sectionArrival.chunks.settingsPage.WeirSection, { renderSlot: props.renderSlot, slot: ROUTING_ITEM_SLOT });
2405
+ }
2406
+ if (sectionArrival?.error) {
2407
+ return react_jsx_runtime.jsx("div", { style: settingsLoadFailedStyle, children: `${props.t("loadFailed")} ${describeChunkError(sectionArrival.error)}` });
2408
+ }
2409
+ return react_jsx_runtime.jsx("div", { style: settingsLoadingStyle, children: props.t("loading") });
2410
+ }
2411
+ function RoutingCardWrapper(props) {
2412
+ const cardArrival = useChunkArrival(ensureSettingsChunks);
2413
+ const pickerArrival = useChunkArrival(loadModelPickerChunk);
2414
+ if (cardArrival?.chunks) {
2415
+ return react_jsx_runtime.jsx(cardArrival.chunks.settingsPage.WeirCard, { ...props, page: "routing", editors: cardArrival.chunks.editors, modelPicker: pickerArrival?.chunks });
2416
+ }
2417
+ if (cardArrival?.error) {
2418
+ return react_jsx_runtime.jsx("div", { style: settingsLoadFailedStyle, children: `${props.t("loadFailed")} ${describeChunkError(cardArrival.error)}` });
2419
+ }
2420
+ return react_jsx_runtime.jsx("div", { style: settingsLoadingStyle, children: props.t("loading") });
2421
+ }
2412
2422
  function SettingsCardWrapper(props) {
2413
2423
  const cardArrival = useChunkArrival(ensureSettingsChunks);
2414
2424
  const pickerArrival = useChunkArrival(loadModelPickerChunk);
@@ -2438,11 +2448,32 @@ window.__ModuleLoader__.load({
2438
2448
  locale: NS,
2439
2449
  inject: () => cardFace
2440
2450
  }, SettingsCardWrapper));
2451
+ const offRoutingSection = ctx.slots.inject("settings.section", () => ctx.slots.register({
2452
+ name: "settings.section",
2453
+ id: ROUTING_SECTION_ID,
2454
+ order: 41,
2455
+ label: () => t("routingTitle"),
2456
+ locale: NS,
2457
+ children: { [ROUTING_ITEM_SLOT]: {
2458
+ kind: "list",
2459
+ scope: "root"
2460
+ } }
2461
+ }, RoutingSectionWrapper));
2462
+ const offRoutingItem = ctx.slots.inject(ROUTING_ITEM_SLOT, () => ctx.slots.register({
2463
+ name: ROUTING_ITEM_SLOT,
2464
+ id: "weir-routing-config",
2465
+ order: 0,
2466
+ locale: NS,
2467
+ inject: () => routingCardFace
2468
+ }, RoutingCardWrapper));
2441
2469
  return () => {
2442
2470
  serving = false;
2443
2471
  controller?.dispose();
2472
+ routingController?.dispose();
2444
2473
  offSection();
2445
2474
  offItem();
2475
+ offRoutingSection();
2476
+ offRoutingItem();
2446
2477
  };
2447
2478
  }), "ui-weir-settings: page");
2448
2479
  }