dsh-home-hosted 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/docs/DESIGN.md +100 -4
- package/lib/client.js +1 -1
- package/lib/index.js +414 -155
- package/lib/index.js.map +4 -4
- package/lib/types/boot/common.d.ts +81 -4
- package/lib/types/boot/escape.d.ts +9 -0
- package/lib/types/boot/index.d.ts +3 -1
- package/lib/types/boot/systemd.d.ts +6 -2
- package/lib/types/boot/types.d.ts +43 -0
- package/lib/types/home-hosted/launch.d.ts +29 -0
- package/lib/types/home-hosted/launcher.d.ts +8 -3
- package/lib/types/service.d.ts +36 -2
- package/lib/types/shared/contracts.d.ts +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,10 +92,9 @@ running.
|
|
|
92
92
|
| `home_hosted_servers_lifecycle` | `start` · `stop` · `restart` |
|
|
93
93
|
| `home_hosted_servers_edit` | `create` · `update` · `delete` |
|
|
94
94
|
| `home_hosted_autostart_manage` | `install` · `uninstall` |
|
|
95
|
-
| `home_hosted_ui_manage` | `status` · `update` · `revert` · `switch`
|
|
95
|
+
| `home_hosted_ui_manage` | `status` · `update` · `revert` · `switch` (official asset or local zip) |
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
workspace the plugin manages.
|
|
97
|
+
Every server tool names its `workspace`, because an id is only unique inside one.
|
|
99
98
|
|
|
100
99
|
A tool that changes something asks for approval **only** when the session is not already Full access.
|
|
101
100
|
<sub>A refused token is re-enrolled on the spot and the tool retries — see **automatic regeneration** below.</sub>
|
|
@@ -115,6 +114,13 @@ A tool that changes something asks for approval **only** when the session is not
|
|
|
115
114
|
When the process cannot elevate, the page prints the exact commands instead — including the
|
|
116
115
|
`launchd-daemon` that starts a Mac **before** login.
|
|
117
116
|
|
|
117
|
+
A boot entry runs the panel as the person who installed it: the account comes from the login that
|
|
118
|
+
elevated (`SUDO_UID`) or from the panel root's owner, not from `$USER`.
|
|
119
|
+
<sub>An entry with no account to name runs the panel as root — that is the default, and the page
|
|
120
|
+
says so rather than hiding it. A `User=` systemd cannot resolve is refused too, because it makes
|
|
121
|
+
the unit fail to start. Moving an install from root to a user later needs
|
|
122
|
+
`chown -R <user> <home>`.</sub>
|
|
123
|
+
|
|
118
124
|
</details>
|
|
119
125
|
|
|
120
126
|
<details>
|
package/docs/DESIGN.md
CHANGED
|
@@ -115,11 +115,18 @@ artifact carrying this plugin's marker is ever removed.
|
|
|
115
115
|
Seven tools, not ten: `servers_lifecycle` carries start/stop/restart, `servers_edit`
|
|
116
116
|
carries create/update/delete, `autostart_manage` carries install/uninstall, and
|
|
117
117
|
`ui_manage` drives the panel's own UI (`ui-update` / `ui-revert` / `ui-switch`).
|
|
118
|
-
`workspaces_list` is the read-only way to see every workspace, and
|
|
119
|
-
|
|
118
|
+
`workspaces_list` is the read-only way to see every workspace, and every server
|
|
119
|
+
call names its `workspace` explicitly.
|
|
120
120
|
They are registered on by default; what gates a mutating call is the session's
|
|
121
121
|
own permission mode, not a plugin-level default.
|
|
122
122
|
|
|
123
|
+
A description is read at the approval prompt, so each one is a line a person can
|
|
124
|
+
glance at: what the tool does, and only the consequence they could not predict
|
|
125
|
+
(restarting this session's own entry ends it; installing an entry stops the
|
|
126
|
+
panel). Mechanics — which panel is reached how, which workspace a default means —
|
|
127
|
+
belong in the argument schemas and the docs, not in the sentence somebody has to
|
|
128
|
+
read before saying yes.
|
|
129
|
+
|
|
123
130
|
Structured tool parameters are declared as objects, never as `type: 'json'`: an
|
|
124
131
|
author-only `json` node projects to a schema with no `type` at all, and a real
|
|
125
132
|
session then delivers something the handler cannot read — `create`/`update` were
|
|
@@ -204,6 +211,12 @@ workspace files when it does not) and act on any of them by naming it
|
|
|
204
211
|
disk). Only `default` is *reconciled*; another workspace is managed the way a
|
|
205
212
|
person would manage it.
|
|
206
213
|
|
|
214
|
+
Every server-shaped tool call therefore carries an explicit `workspace`, required
|
|
215
|
+
in the JSON: it is one argument instead of a paragraph, and it keeps the same call
|
|
216
|
+
from meaning different things on two machines. The RPC endpoint still defaults an
|
|
217
|
+
absent value (the page always sends one, and a hand-written call should not break),
|
|
218
|
+
but a model is never left to guess.
|
|
219
|
+
|
|
207
220
|
A pre-0.7 root is not read or written at all. It is recognised (a `legacyRoot`
|
|
208
221
|
flag on the status), refused on every write, and fixed through one action that
|
|
209
222
|
runs `home-hosted migrate --yes` — the same relocation a first 0.7 start does on
|
|
@@ -279,6 +292,71 @@ The settings stamp moved to 3 for `instancesNotice`, while the tool-name
|
|
|
279
292
|
migration stays bound to the release that merged the tools: a stamp bump must
|
|
280
293
|
never re-read a current file's explicit two-tool allowlist as "nobody chose".
|
|
281
294
|
|
|
295
|
+
## Boot entries run the panel as a person
|
|
296
|
+
|
|
297
|
+
Two mechanisms drop privilege by name — a systemd `User=` and a launchd
|
|
298
|
+
`UserName` — and both used to take that name from `$USER`. That is right in the
|
|
299
|
+
common case and wrong in the one case it exists for: `sudo` and `pkexec` rewrite
|
|
300
|
+
`USER`, `LOGNAME` and `HOME` to the *target* account, so a panel started from a
|
|
301
|
+
root shell or a root unit read `USER=root`, and a mechanism that already runs as
|
|
302
|
+
root got an entry that either repeated root or (with the name dropped) silently
|
|
303
|
+
kept it. `os.userInfo()` is no help: it reports the euid.
|
|
304
|
+
|
|
305
|
+
So the account comes from whoever this process is. An elevating tool's
|
|
306
|
+
`SUDO_UID`/`PKEXEC_UID` is an instruction and is used while it resolves, so a
|
|
307
|
+
stale value inherited from an ancestor cannot collapse the entry to root;
|
|
308
|
+
otherwise this session's own login — its database row, else the row for this uid;
|
|
309
|
+
otherwise the owner of the state root or the panel root, which names the person a
|
|
310
|
+
root-launched panel belongs to; and only then, honestly, root.
|
|
311
|
+
|
|
312
|
+
The uid is the fact and `$UID` is a claim: it is a shell variable rather than an
|
|
313
|
+
exported one, so when it is present at all it was inherited, and it also feeds the
|
|
314
|
+
launchd domain (`gui/$UID`). It is read only when the platform gives no uid.
|
|
315
|
+
|
|
316
|
+
Two answers are refused rather than written, and both fail loudly:
|
|
317
|
+
|
|
318
|
+
- **`User=root`**, because an entry with no `User=` already runs as root — naming
|
|
319
|
+
it only dresses up the silent default this change exists to surface;
|
|
320
|
+
- **a name the user database cannot place.** systemd matches names
|
|
321
|
+
case-sensitively and cannot resolve what it does not know, so
|
|
322
|
+
`User=<such a name>` makes the unit refuse to start (`status=217/USER`) and
|
|
323
|
+
`Restart=always` turns that into a crash-loop that never mentions the account —
|
|
324
|
+
worse than running as root, and the same unexplained failure in a new costume.
|
|
325
|
+
An LDAP or NIS login has no `/etc/passwd` row, so those operators set `User=`
|
|
326
|
+
themselves; the warning says so.
|
|
327
|
+
|
|
328
|
+
`HOME` is written into every spec, because `Environment=HOME=` **overrides
|
|
329
|
+
`User=`** — verified on real systemd. So it has to be the account's home: left at
|
|
330
|
+
the installer's it is root's under `sudo`, and the panel would run as the person
|
|
331
|
+
with `~` pointing at `/root`, dying with a permission error that never mentions
|
|
332
|
+
its own user. It is written only when it differs, so an unchanged install stays
|
|
333
|
+
byte-identical and startup `reconcile()` does not rewrite the entry. When an
|
|
334
|
+
account resolves but its home is not knowable, the line is **omitted** instead:
|
|
335
|
+
systemd then supplies the right one from NSS, which leaving root's in place would
|
|
336
|
+
have prevented.
|
|
337
|
+
|
|
338
|
+
An installed entry that already runs as the wrong account is reported by
|
|
339
|
+
`status()`, and the `enabled-failing` repair heals it by installing again. A
|
|
340
|
+
*working* entry is deliberately left alone: re-installing stops the panel and
|
|
341
|
+
hands it to the entry, which is a person's decision and not a startup side
|
|
342
|
+
effect.
|
|
343
|
+
|
|
344
|
+
## KillMode=process: a restart must not take the entries with it
|
|
345
|
+
|
|
346
|
+
`persistent: true` puts an entry under a nanny the panel spawns, and the nanny is
|
|
347
|
+
what makes it outlive the panel: it owns the child's pipes, so a panel stop,
|
|
348
|
+
restart or kill cannot break them. The nanny is spawned `detached`, which gives it
|
|
349
|
+
its own session — but *not* its own cgroup, and systemd's default
|
|
350
|
+
`KillMode=control-group` signals every process in the unit's cgroup. So a
|
|
351
|
+
`systemctl stop`/`restart` — which is what this plugin's own activation, and any
|
|
352
|
+
`Restart=always`, runs — takes the nanny down with the panel, quietly falsifying
|
|
353
|
+
the guarantee the design depends on. `KillMode=process` signals the panel alone.
|
|
354
|
+
|
|
355
|
+
An ordinary entry is spawned `detached` too, so the same applies to every
|
|
356
|
+
supervised server and not only the nannies: the panel re-adopts a survivor by its
|
|
357
|
+
port, which is what makes keeping them the right answer rather than a leak.
|
|
358
|
+
It belongs on both units.
|
|
359
|
+
|
|
282
360
|
## macOS: agent or daemon
|
|
283
361
|
|
|
284
362
|
A `LaunchAgent` starts at login; starting before login means a `LaunchDaemon` in
|
|
@@ -286,8 +364,9 @@ A `LaunchAgent` starts at login; starting before login means a `LaunchDaemon` in
|
|
|
286
364
|
install. The daemon is therefore offered even when this process cannot elevate:
|
|
287
365
|
install stages the plist and returns the three commands to run. The daemon plist
|
|
288
366
|
names the invoking user in `UserName`, Apple's sanctioned way to avoid running
|
|
289
|
-
the panel as root
|
|
290
|
-
can install on its own so
|
|
367
|
+
the panel as root — resolved by the rule above, never from `$USER`. The
|
|
368
|
+
recommendation still prefers a mechanism this process can install on its own so
|
|
369
|
+
"Automatic" stays a single click.
|
|
291
370
|
|
|
292
371
|
## macOS: reachable launchd is not a requirement
|
|
293
372
|
|
|
@@ -452,6 +531,16 @@ Nothing is stopped then — leaving a working panel up beats killing it for an
|
|
|
452
531
|
entry that would not bring it back. A handover that could not be spawned is
|
|
453
532
|
reported with the exact commands, and the panel is still up.
|
|
454
533
|
|
|
534
|
+
## The panel's UI is changed by the panel's own CLI
|
|
535
|
+
|
|
536
|
+
`ui.manage` shells out to `ui-switch` / `ui-update` / `ui-revert` rather than
|
|
537
|
+
downloading a release and installing a file. An official UI is named by its
|
|
538
|
+
release asset (`--asset noc-console`, plus `--repo`/`--tag` when it lives
|
|
539
|
+
somewhere else), and the panel then picks the release matching its own version,
|
|
540
|
+
matches the asset name and verifies the archive — the version logic stays in one
|
|
541
|
+
place instead of being reimplemented against the GitHub API here. `--file` stays
|
|
542
|
+
for a local build, which is the case the CLI cannot cover.
|
|
543
|
+
|
|
455
544
|
Enabling and switching differ only in the retirement: a switch already has an
|
|
456
545
|
entry keeping the panel alive, so its plan carries the old mechanism's removal.
|
|
457
546
|
|
|
@@ -468,6 +557,13 @@ as the status moves: a person runs the commands and presses Re-check, and the no
|
|
|
468
557
|
must not outlive the state it described. The persisted last attempt follows the
|
|
469
558
|
same rule, so a failed install is not re-shown once an entry exists.
|
|
470
559
|
|
|
560
|
+
Switching those entries to a `User=` later is not just a unit edit. The moment a
|
|
561
|
+
panel runs as root, everything it writes — `<home>/.hh`, its workspaces, logs and
|
|
562
|
+
`snapshots.json` — is root-owned, so the unprivileged account the unit now names
|
|
563
|
+
cannot write its own state and the panel fails to boot with a permission error
|
|
564
|
+
that never mentions ownership. Moving an install from root to a user therefore
|
|
565
|
+
needs `chown -R <user> <home>` (and the plugin state dir) first.
|
|
566
|
+
|
|
471
567
|
## Tests
|
|
472
568
|
|
|
473
569
|
No fixed ports: every stub listener binds `127.0.0.1` with port 0 and reads the
|
package/lib/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({ id: "dsh-home-hosted", factory: (require) => {
|
|
2
2
|
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
-
"use strict";var Ee=Object.defineProperty;var Gt=Object.getOwnPropertyDescriptor;var Kt=Object.getOwnPropertyNames;var Yt=Object.prototype.hasOwnProperty;var qt=(e,t)=>{for(var n in t)Ee(e,n,{get:t[n],enumerable:!0})},Jt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Kt(t))!Yt.call(e,o)&&o!==n&&Ee(e,o,{get:()=>t[o],enumerable:!(r=Gt(t,o))||r.enumerable});return e};var Xt=e=>Jt(Ee({},"__esModule",{value:!0}),e);var Mn={};qt(Mn,{apply:()=>Hn,inject:()=>In});module.exports=Xt(Mn);var ve="homeHosted",Ne={tab:"Home Hosted",loading:"Loading\u2026",refresh:"Refresh",retry:"Retry",errorTitle:"Error",statusUnavailable:"The panel did not answer.",yes:"Yes",no:"No",copy:"Copy",copied:"Copied",details:"Details",uiStyleLabel:"Page style",uiStyleDetailed:"Detailed",uiStyleCompact:"Compact",workspacesTitle:"Workspaces",workspacesHint:"Every workspace this panel serves. Viewing one decides what this page lists.",workspacesViewLabel:"Workspace to view",workspacesEmpty:"The panel reports no workspaces yet.",workspacesManagedTag:"managed by the plugin",workspacesViewingTag:"viewing",workspacesCounts:"{servers} servers \xB7 {running} running",workspacesCountsFile:"{servers} in the config files",workspacesDegraded:"The panel is not answering, so these counts \u2014 and the entry list below \u2014 come from the workspace config files, not from live state.",workspaceLegacyTitle:"This state root still uses the pre-0.7 layout",workspaceLegacyBody:"The plugin cannot read or write its files until they move into .hh. Starting the panel once does the same move; this runs it directly.",workspaceMigrate:"Migrate state root",workspaceMigrateFailed:"The migration did not run.",workspaceMigrateDone:"The state root was migrated.",sigPanel:"Panel",sigAutostart:"Autostart",sigEntry:"{id} entry",stateAnswering:"answering",stateNotAnswering:"not answering",stateManaged:"managed",stateNotManaged:"not managed",panelTitle:"Panel",panelCopy:"Which copy runs the panel",panelCopyHint:"The pinned copy ships with this plugin; the global one is on PATH.",optionsPreferPinned:"Pinned dependency",optionsPreferGlobal:"Global install",optionsRecommended:"recommended",optionsConfigOverride:"The plugin row sets homeHostedCommand, and that always wins.",optionsInstallLabel:"Install a global copy",optionsInstallHint:"No global install was found. Install the pinned range, then choose it above:",optionsInstall:"Install globally",panelHome:"Panel root",panelUrl:"URL",panelVersion:"Version",panelPid:"PID",panelWriteVia:"Writes via",panelToken:"API token",panelCliSource:"CLI",panelCliPath:"CLI path",panelCliConfig:"configured command",panelCliDependency:"pinned dependency",panelCliPathSource:"global install (PATH)",panelCliMissing:"not found",panelCliNotPinned:"This host resolved a global home-hosted instead of the pinned copy ({range}).",panelCliUnsupported:"This home-hosted is older than the oldest release the plugin supports.",panelCliLauncherFailed:"The boot launcher did not answer, so a boot entry may fail to start the panel.",panelPort:"Panel port",panelPortHint:"Only changeable while the panel is stopped.",panelPortFree:"Leave empty to use the port in the config.",panelPortInvalid:"Enter a port between 1 and 65535.",panelStart:"Start the panel",panelStop:"Stop the panel",panelStopTitle:"Stop the running panel?",panelStopBody:"This stops the panel and every server it supervises \u2014 this session included, so the page may disconnect. An autostart entry starts them again at the next panel start.",panelStopping:"Stopping the panel\u2026",panelStopped:"The panel stopped.",panelStopFailed:"The panel did not stop: {message}",panelRootLegacy:"Adopted from ~/.home-hosted. Set HHOSTED_HOME to give this dsh its own panel.",confirmStop:"Stop",panelOutdated:"Outdated panel",panelReplace:"Restart with {copy}",panelCopyPinned:"pinned dependency",panelCopyGlobal:"global install",panelTakeoverTitle:"Restart the running panel?",panelTakeoverBody:"This stops the panel and every server it supervises \u2014 this session included, so the page disconnects. It needs the {id} entry adopted with autostart on.",confirmCancel:"Cancel",confirmReplace:"Restart",writeViaApi:"authenticated API",writeViaFile:"config file",writeViaNone:"unavailable",tokenEnrolled:"enrolled",tokenPresent:"present",tokenAbsent:"absent",tokenStale:"stale",tokenUnknown:"unknown",panelTokenWarningTitle:"The panel API token is missing or refused",panelTokenWarnAbsent:"This plugin has no API token for the panel, so it cannot read or write the panel; regenerate one.",panelTokenWarnPresent:"home-hosted holds an API token this plugin does not have, so the plugin cannot authenticate; regenerate one to replace it.",panelTokenWarnStale:"The panel refused this plugin's API token; regenerate it.",panelTokenWarnUnreachable:"The plugin could not reach the panel to check its API token, so it cannot read or write the panel; the panel may need starting.",panelTokenWarnPanelDown:"The panel is not answering right now, so it may need starting too.",panelTokenRegenerate:"Regenerate token",panelTokenRegenerated:"A fresh API token was enrolled for the panel.",panelTokenRegenerateFailed:"The token was not replaced: {message}",panelInstances:"{count} panels found",panelInstanceManaged:"managed by this plugin",panelInstanceOther:"another panel",panelInstanceHosts:"hosts this dsh",panelInstancesHint:"This plugin drives only the managed one; the others are read from their state roots and never written to.",bootTitle:"Autostart",bootEnabled:"Enable autostart",bootUninstall:"Uninstall",bootSwitchMode:"Switch autostart",bootRecheck:"Re-check",bootMechanism:"Mechanism",bootMechanismAuto:"Automatic",bootState:"State",bootStateNotInstalled:"not installed",bootStateInstalledDisabled:"installed, off",bootStateEnabledRunning:"enabled, running",bootStateEnabledFailing:"enabled, failing",bootStateUnsupported:"unsupported",bootBootCapable:"Starts before login",bootPrivileged:"This process can install it",bootUnitPath:"Unit path",bootCommandsLabel:"Install by hand",bootCommandsExplain:"This process cannot elevate. Run these commands to install autostart:",bootRequestedNotInstalled:"Autostart is requested, but no boot entry is installed.",bootHandover:"Enabling this stops the panel this plugin started and starts it through the entry, so this page disconnects and comes back.",bootSwitchRetires:"Switching stops the panel and removes the previous autostart entry, so this page disconnects and comes back.",bootActionInstall:"install",bootActionUninstall:"uninstall",bootAttemptFailed:"{action} failed",bootAttemptSucceeded:"{action} succeeded \u2014 {detail}",bootAttemptNoDetail:"The host did not explain the refusal.",bootAttemptCommands:"Run these yourself:",entriesTitle:"Managed entry",entriesManage:"Manage {id}",entriesManageNote:"Hands {id} to home-hosted: boot autostart, panel control, port reclaim.",entriesManageWinWarning:"On Windows, `{id}` is managed via the `kill` onPortConflict policy, so when it is restarted detached by another plugin it may briefly fail to boot while home-hosted reclaims the process and port.",entriesEmpty:"{id} is not managed yet.",entriesExists:"exists",entriesMissing:"missing",entriesManaged:"managed",entriesUnmanaged:"unmanaged",entriesDrift:"drift",entriesNotRunning:"not running",agentTitle:"Agent tools",agentCount:"{enabled} of {total} on",agentMaster:"Let the agent use these tools",agentApproval:"Tools that change something ask for approval first.",agentApprovalBadge:"approval",reclaimAutoLabel:"Regenerate token automatically",reclaimAutoHint:"A tool call that finds a refused token re-enrols one and retries instead of failing.",instancesNoticeLabel:"Tell the agent about other panels",instancesNoticeHint:"Adds the panel inventory to the agent's context, and asks which panel to act on when several exist.",agentToolStatus:"Status",agentToolWorkspacesList:"List workspaces",agentToolServersList:"List servers",agentToolServersLifecycle:"Start, stop, restart",agentToolServersEdit:"Create, update, delete",agentToolAutostartManage:"Manage boot autostart",agentToolUiManage:"Manage Panel UI",agentToolDescStatus:"Read the panel, the CLI copy in use and the managed entry. Nothing changes.",agentToolDescWorkspacesList:"List every workspace the panel serves, with its entry and running counts. A server id is only unique inside a workspace.",agentToolDescServersList:"List the servers of one workspace the panel supervises, with status, port and URL. A server id is only unique inside a workspace.",agentToolDescServersLifecycle:"Start, stop and restart supervised servers, in the workspace the call names.",agentToolDescServersEdit:"Create, update and delete server entries, in the workspace the call names.",agentToolDescAutostartManage:"Install or remove the boot entry that starts the panel.",agentToolDescUiManage:"Inspect, update, revert or switch the panel's own UI build.",serversTitle:"Servers",serversCount:"{running} of {total} running",serversHintPanel:"Entries are managed in the home-hosted panel:",serversHintNoPanel:"Entries cannot be managed right now: the panel is not running.",serversEmpty:"The panel reports no servers.",serversPid:"PID",serversUrl:"URL",serversCommand:"Command",serversArgs:"Args",serversCwd:"Working dir",serversPort:"Port",serversOnPortConflict:"On port conflict",serversAutostart:"Autostart",serversPersistent:"Persistent",serversPersistentHint:"Run by home-hosted's own nanny, so stopping or restarting the panel leaves it alive.",serversHealth:"Health",serversRestartPolicy:"Restart",serversConfiguration:"Configuration",serversRawConfig:"Raw config",serversDisabled:"disabled",serversEnabled:"enabled",serversHealthHttp:"HTTP {status} on {path}",serversHealthHttpBelow:"HTTP <{status} on {path}",serversHealthHttpProbe:"HTTP probe on {path}",serversHealthPort:"port {port}",serversHealthProbe:"port probe",serversHealthEvery:"every {seconds}",serversRestartSummary:"{retries} retries \xB7 {base} \u2192 \xD7{factor}",serversStart:"Start",serversStop:"Stop",serversRestart:"Restart",serversWorkspace:"Workspace",serversAdd:"Add server",serversEdit:"Edit",serversEditTitle:"Edit {id}",serversCreateTitle:"Add a server",serversEditorHint:"Only the fields you change are written; everything else keeps inheriting the workspace defaults.",serversCreate:"Create",serversSave:"Save",serversDelete:"Delete",serversDeleteTitle:"Delete {id}?",serversDeleteBody:"This removes the entry from workspace {workspace}. A running server is stopped with it.",serversDeleteGo:"Delete",serversFreePort:"Free port",serversFreePortTitle:"Free port {port}?",serversFreePortBody:"Stops whatever holds the port, unless the panel supervises it. Processes get SIGTERM first, then a forced stop.",serversFreePortGo:"Free",serversPortFreed:"Port {port} is free.",serversPortHeld:"Port {port} is still held.",serversPortSkipped:"The listener belongs to a server the panel supervises, so it was left alone.",serversPortRefused:"The port was not freed: {message}",fieldId:"Id",fieldIdHint:"Lowercase letters, digits, `_` and `-`; unique inside the workspace.",fieldIdInvalid:"An id starts with a lowercase letter or digit and uses only a-z, 0-9, _ and -.",fieldLabel:"Label",fieldCommand:"Command",fieldArgs:"Arguments",fieldArgsHint:"One argument per line.",fieldCwd:"Working directory",fieldPort:"Port",fieldPortHint:"Empty means the entry has no port.",fieldPortInvalid:"Enter a port between 1 and 65535, or leave it empty.",fieldAutostart:"Start with the panel",fieldOnPortConflict:"On port conflict",fieldInherit:"Inherit",fieldRequired:"Id and command are required."},_e={tab:"Home Hosted",loading:"\u52A0\u8F7D\u4E2D\u2026",refresh:"\u5237\u65B0",retry:"\u91CD\u8BD5",errorTitle:"\u9519\u8BEF",statusUnavailable:"\u9762\u677F\u6CA1\u6709\u54CD\u5E94\u3002",yes:"\u662F",no:"\u5426",copy:"\u590D\u5236",copied:"\u5DF2\u590D\u5236",details:"\u8BE6\u60C5",uiStyleLabel:"\u9875\u9762\u6837\u5F0F",uiStyleDetailed:"\u8BE6\u7EC6",uiStyleCompact:"\u7D27\u51D1",workspacesTitle:"\u5DE5\u4F5C\u533A",workspacesHint:"\u6B64\u9762\u677F\u63D0\u4F9B\u7684\u6240\u6709\u5DE5\u4F5C\u533A\u3002\u67E5\u770B\u54EA\u4E2A\u5C31\u5217\u51FA\u54EA\u4E2A\u3002",workspacesViewLabel:"\u8981\u67E5\u770B\u7684\u5DE5\u4F5C\u533A",workspacesEmpty:"\u9762\u677F\u5C1A\u672A\u62A5\u544A\u4EFB\u4F55\u5DE5\u4F5C\u533A\u3002",workspacesManagedTag:"\u7531\u63D2\u4EF6\u7BA1\u7406",workspacesViewingTag:"\u6B63\u5728\u67E5\u770B",workspacesCounts:"{servers} \u4E2A\u670D\u52A1\u5668 \xB7 {running} \u4E2A\u8FD0\u884C\u4E2D",workspacesCountsFile:"\u914D\u7F6E\u6587\u4EF6\u4E2D {servers} \u4E2A",workspacesDegraded:"\u9762\u677F\u6CA1\u6709\u54CD\u5E94\uFF0C\u56E0\u6B64\u8FD9\u4E9B\u8BA1\u6570\u2014\u2014\u4EE5\u53CA\u4E0B\u65B9\u7684\u6761\u76EE\u5217\u8868\u2014\u2014\u6765\u81EA\u5DE5\u4F5C\u533A\u914D\u7F6E\u6587\u4EF6\uFF0C\u800C\u4E0D\u662F\u5B9E\u65F6\u72B6\u6001\u3002",workspaceLegacyTitle:"\u8BE5\u72B6\u6001\u76EE\u5F55\u4ECD\u662F 0.7 \u4E4B\u524D\u7684\u5E03\u5C40",workspaceLegacyBody:"\u5728\u6587\u4EF6\u79FB\u5165 .hh \u4E4B\u524D\uFF0C\u63D2\u4EF6\u65E0\u6CD5\u8BFB\u53D6\u6216\u5199\u5165\u5B83\u4EEC\u3002\u542F\u52A8\u4E00\u6B21\u9762\u677F\u5373\u53EF\u5B8C\u6210\u540C\u6837\u7684\u8FC1\u79FB\uFF1B\u6B64\u6309\u94AE\u76F4\u63A5\u6267\u884C\u8BE5\u547D\u4EE4\u3002",workspaceMigrate:"\u8FC1\u79FB\u72B6\u6001\u76EE\u5F55",workspaceMigrateFailed:"\u8FC1\u79FB\u6CA1\u6709\u6267\u884C\u3002",workspaceMigrateDone:"\u72B6\u6001\u76EE\u5F55\u5DF2\u8FC1\u79FB\u3002",sigPanel:"\u9762\u677F",sigAutostart:"\u5F00\u673A\u81EA\u542F",sigEntry:"{id} \u6761\u76EE",stateAnswering:"\u54CD\u5E94\u4E2D",stateNotAnswering:"\u672A\u54CD\u5E94",stateManaged:"\u5DF2\u63A5\u7BA1",stateNotManaged:"\u672A\u63A5\u7BA1",panelTitle:"\u9762\u677F",panelCopy:"\u7531\u54EA\u4E2A\u526F\u672C\u8FD0\u884C\u9762\u677F",panelCopyHint:"\u56FA\u5B9A\u526F\u672C\u968F\u63D2\u4EF6\u4E00\u8D77\u5B89\u88C5\uFF1B\u5168\u5C40\u526F\u672C\u6765\u81EA PATH\u3002",optionsPreferPinned:"\u56FA\u5B9A\u4F9D\u8D56",optionsPreferGlobal:"\u5168\u5C40\u5B89\u88C5",optionsRecommended:"\u63A8\u8350",optionsConfigOverride:"\u63D2\u4EF6\u884C\u4E2D\u7684 homeHostedCommand \u4F18\u5148\u7EA7\u6700\u9AD8\uFF0C\u59CB\u7EC8\u751F\u6548\u3002",optionsInstallLabel:"\u5B89\u88C5\u5168\u5C40\u526F\u672C",optionsInstallHint:"\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u3002\u5B89\u88C5\u56FA\u5B9A\u7248\u672C\u8303\u56F4\u540E\uFF0C\u5728\u4E0A\u65B9\u9009\u62E9\u5B83\uFF1A",optionsInstall:"\u5168\u5C40\u5B89\u88C5",panelHome:"\u9762\u677F\u6839\u76EE\u5F55",panelUrl:"URL",panelVersion:"\u7248\u672C",panelPid:"PID",panelWriteVia:"\u5199\u5165\u65B9\u5F0F",panelToken:"API \u4EE4\u724C",panelCliSource:"CLI",panelCliPath:"CLI \u8DEF\u5F84",panelCliConfig:"\u914D\u7F6E\u7684\u547D\u4EE4",panelCliDependency:"\u56FA\u5B9A\u7684\u4F9D\u8D56\u7248\u672C",panelCliPathSource:"\u5168\u5C40\u5B89\u88C5\uFF08PATH\uFF09",panelCliMissing:"\u672A\u627E\u5230",panelCliNotPinned:"\u6B64\u5BBF\u4E3B\u89E3\u6790\u5230\u7684\u662F\u5168\u5C40 home-hosted\uFF0C\u800C\u4E0D\u662F\u56FA\u5B9A\u526F\u672C\uFF08{range}\uFF09\u3002",panelCliUnsupported:"\u6B64 home-hosted \u65E9\u4E8E\u63D2\u4EF6\u652F\u6301\u7684\u6700\u8001\u7248\u672C\u3002",panelCliLauncherFailed:"\u5F00\u673A\u542F\u52A8\u5668\u6CA1\u6709\u5E94\u7B54\uFF0C\u5F00\u673A\u9879\u53EF\u80FD\u65E0\u6CD5\u542F\u52A8\u9762\u677F\u3002",panelPort:"\u9762\u677F\u7AEF\u53E3",panelPortHint:"\u4EC5\u5728\u9762\u677F\u505C\u6B62\u65F6\u53EF\u4FEE\u6539\u3002",panelPortFree:"\u7559\u7A7A\u5219\u4F7F\u7528\u914D\u7F6E\u6587\u4EF6\u4E2D\u7684\u7AEF\u53E3\u3002",panelPortInvalid:"\u8BF7\u8F93\u5165 1 \u5230 65535 \u4E4B\u95F4\u7684\u7AEF\u53E3\u3002",panelStart:"\u542F\u52A8\u9762\u677F",panelStop:"\u505C\u6B62\u9762\u677F",panelStopTitle:"\u505C\u6B62\u6B63\u5728\u8FD0\u884C\u7684\u9762\u677F\uFF1F",panelStopBody:"\u8FD9\u4F1A\u505C\u6B62\u9762\u677F\u4EE5\u53CA\u5B83\u76D1\u7BA1\u7684\u6240\u6709\u670D\u52A1\u5668\u2014\u2014\u5305\u62EC\u672C\u4F1A\u8BDD\uFF0C\u56E0\u6B64\u672C\u9875\u9762\u53EF\u80FD\u4F1A\u65AD\u5F00\u8FDE\u63A5\u3002\u5E26\u6709\u81EA\u542F\u7684\u6761\u76EE\u4F1A\u5728\u4E0B\u6B21\u542F\u52A8\u9762\u677F\u65F6\u91CD\u65B0\u542F\u52A8\u3002",panelStopping:"\u6B63\u5728\u505C\u6B62\u9762\u677F\u2026",panelStopped:"\u9762\u677F\u5DF2\u505C\u6B62\u3002",panelStopFailed:"\u9762\u677F\u672A\u80FD\u505C\u6B62\uFF1A{message}",panelRootLegacy:"\u6CBF\u7528\u4E86 ~/.home-hosted\u3002\u8BBE\u7F6E HHOSTED_HOME \u53EF\u8BA9\u6B64 dsh \u4F7F\u7528\u81EA\u5DF1\u7684\u9762\u677F\u3002",confirmStop:"\u505C\u6B62",panelOutdated:"\u9762\u677F\u5DF2\u8FC7\u65F6",panelReplace:"\u4F7F\u7528{copy}\u91CD\u542F",panelCopyPinned:"\u56FA\u5B9A\u4F9D\u8D56",panelCopyGlobal:"\u5168\u5C40\u5B89\u88C5",panelTakeoverTitle:"\u91CD\u542F\u6B63\u5728\u8FD0\u884C\u7684\u9762\u677F\uFF1F",panelTakeoverBody:"\u8FD9\u4F1A\u505C\u6B62\u9762\u677F\u4EE5\u53CA\u5B83\u76D1\u7BA1\u7684\u6240\u6709\u670D\u52A1\u5668\u2014\u2014\u5305\u62EC\u672C\u4F1A\u8BDD\uFF0C\u56E0\u6B64\u672C\u9875\u9762\u4F1A\u65AD\u5F00\u8FDE\u63A5\u3002\u4EC5\u5F53 {id} \u6761\u76EE\u5DF2\u88AB\u63A5\u7BA1\u4E14\u542F\u7528\u81EA\u542F\u65F6\u624D\u53EF\u7528\u3002",confirmCancel:"\u53D6\u6D88",confirmReplace:"\u91CD\u542F",writeViaApi:"\u5DF2\u8BA4\u8BC1 API",writeViaFile:"\u914D\u7F6E\u6587\u4EF6",writeViaNone:"\u4E0D\u53EF\u7528",tokenEnrolled:"\u5DF2\u767B\u8BB0",tokenPresent:"\u5DF2\u5B58\u5728",tokenAbsent:"\u4E0D\u5B58\u5728",tokenStale:"\u5DF2\u5931\u6548",tokenUnknown:"\u672A\u77E5",panelTokenWarningTitle:"\u9762\u677F API \u4EE4\u724C\u7F3A\u5931\u6216\u5DF2\u88AB\u62D2\u7EDD",panelTokenWarnAbsent:"\u672C\u63D2\u4EF6\u6CA1\u6709\u6B64\u9762\u677F\u7684 API \u4EE4\u724C\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u6216\u5199\u5165\u9762\u677F\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u4E00\u4E2A\u3002",panelTokenWarnPresent:"home-hosted \u6301\u6709\u4E00\u4E2A\u672C\u63D2\u4EF6\u6CA1\u6709\u7684 API \u4EE4\u724C\uFF0C\u63D2\u4EF6\u65E0\u6CD5\u901A\u8FC7\u8BA4\u8BC1\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u4E00\u4E2A\u4EE5\u66FF\u6362\u5B83\u3002",panelTokenWarnStale:"\u9762\u677F\u62D2\u7EDD\u4E86\u672C\u63D2\u4EF6\u7684 API \u4EE4\u724C\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u3002",panelTokenWarnUnreachable:"\u672C\u63D2\u4EF6\u65E0\u6CD5\u8BBF\u95EE\u9762\u677F\u4EE5\u68C0\u67E5\u5176 API \u4EE4\u724C\uFF0C\u56E0\u6B64\u65E0\u6CD5\u8BFB\u53D6\u6216\u5199\u5165\u9762\u677F\uFF1B\u9762\u677F\u53EF\u80FD\u8FD8\u9700\u8981\u5148\u542F\u52A8\u3002",panelTokenWarnPanelDown:"\u9762\u677F\u5F53\u524D\u6CA1\u6709\u54CD\u5E94\uFF0C\u53EF\u80FD\u8FD8\u9700\u8981\u5148\u542F\u52A8\u9762\u677F\u3002",panelTokenRegenerate:"\u91CD\u65B0\u751F\u6210\u4EE4\u724C",panelTokenRegenerated:"\u5DF2\u4E3A\u9762\u677F\u767B\u8BB0\u65B0\u4EE4\u724C\u3002",panelTokenRegenerateFailed:"\u4EE4\u724C\u672A\u66FF\u6362\uFF1A{message}",panelInstances:"\u53D1\u73B0 {count} \u4E2A\u9762\u677F",panelInstanceManaged:"\u7531\u672C\u63D2\u4EF6\u7BA1\u7406",panelInstanceOther:"\u5176\u4ED6\u9762\u677F",panelInstanceHosts:"\u6258\u7BA1\u5F53\u524D dsh",panelInstancesHint:"\u672C\u63D2\u4EF6\u53EA\u9A71\u52A8\u88AB\u7BA1\u7406\u7684\u90A3\u4E00\u4E2A\uFF1B\u5176\u4ED6\u9762\u677F\u4EC5\u4ECE\u5176\u72B6\u6001\u76EE\u5F55\u8BFB\u53D6\uFF0C\u7EDD\u4E0D\u5199\u5165\u3002",bootTitle:"\u5F00\u673A\u81EA\u542F",bootEnabled:"\u542F\u7528\u5F00\u673A\u81EA\u542F",bootUninstall:"\u5378\u8F7D",bootSwitchMode:"\u5207\u6362\u81EA\u542F\u673A\u5236",bootRecheck:"\u91CD\u65B0\u68C0\u67E5",bootMechanism:"\u673A\u5236",bootMechanismAuto:"\u81EA\u52A8",bootState:"\u72B6\u6001",bootStateNotInstalled:"\u672A\u5B89\u88C5",bootStateInstalledDisabled:"\u5DF2\u5B89\u88C5\uFF0C\u672A\u542F\u7528",bootStateEnabledRunning:"\u5DF2\u542F\u7528\uFF0C\u8FD0\u884C\u4E2D",bootStateEnabledFailing:"\u5DF2\u542F\u7528\uFF0C\u542F\u52A8\u5931\u8D25",bootStateUnsupported:"\u4E0D\u652F\u6301",bootBootCapable:"\u767B\u5F55\u524D\u542F\u52A8",bootPrivileged:"\u672C\u8FDB\u7A0B\u53EF\u5B89\u88C5",bootUnitPath:"\u5355\u5143\u6587\u4EF6\u8DEF\u5F84",bootCommandsLabel:"\u624B\u52A8\u5B89\u88C5",bootCommandsExplain:"\u672C\u8FDB\u7A0B\u65E0\u6CD5\u63D0\u6743\u3002\u8BF7\u81EA\u884C\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5B89\u88C5\u81EA\u542F\uFF1A",bootRequestedNotInstalled:"\u5DF2\u8BF7\u6C42\u5F00\u673A\u81EA\u542F\uFF0C\u4F46\u5C1A\u672A\u5B89\u88C5\u4EFB\u4F55\u5F00\u673A\u9879\u3002",bootHandover:"\u542F\u7528\u540E\u4F1A\u505C\u6B62\u672C\u63D2\u4EF6\u542F\u52A8\u7684\u9762\u677F\uFF0C\u6539\u7531\u8BE5\u5F00\u673A\u9879\u542F\u52A8\uFF0C\u672C\u9875\u9762\u4F1A\u65AD\u5F00\u5E76\u81EA\u884C\u6062\u590D\u3002",bootSwitchRetires:"\u5207\u6362\u4F1A\u505C\u6B62\u9762\u677F\u5E76\u79FB\u9664\u5148\u524D\u7684\u81EA\u542F\u9879\uFF0C\u672C\u9875\u9762\u4F1A\u65AD\u5F00\u5E76\u81EA\u884C\u6062\u590D\u3002",bootActionInstall:"\u5B89\u88C5",bootActionUninstall:"\u5378\u8F7D",bootAttemptFailed:"{action}\u5931\u8D25",bootAttemptSucceeded:"{action}\u6210\u529F \u2014 {detail}",bootAttemptNoDetail:"\u5BBF\u4E3B\u6CA1\u6709\u8BF4\u660E\u5931\u8D25\u539F\u56E0\u3002",bootAttemptCommands:"\u4F60\u53EF\u4EE5\u81EA\u884C\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\uFF1A",entriesTitle:"\u53D7\u7BA1\u6761\u76EE",entriesManage:"\u63A5\u7BA1 {id}",entriesManageNote:"\u628A {id} \u4EA4\u7ED9 home-hosted\uFF1A\u5F00\u673A\u81EA\u542F\u3001\u9762\u677F\u63A7\u5236\u3001\u7AEF\u53E3\u56DE\u6536\u3002",entriesManageWinWarning:"\u5728 Windows \u4E0A\uFF0C`{id}` \u901A\u8FC7 `kill` \u7AEF\u53E3\u51B2\u7A81\u7B56\u7565\u7BA1\u7406\uFF1B\u5F53\u5B83\u88AB\u5176\u4ED6\u63D2\u4EF6\u4EE5\u5206\u79BB\u65B9\u5F0F\u91CD\u542F\u65F6\uFF0Chome-hosted \u56DE\u6536\u8FDB\u7A0B\u4E0E\u7AEF\u53E3\u671F\u95F4\u53EF\u80FD\u77ED\u6682\u65E0\u6CD5\u542F\u52A8\u3002",entriesEmpty:"\u5C1A\u672A\u63A5\u7BA1 {id}\u3002",entriesExists:"\u5B58\u5728",entriesMissing:"\u7F3A\u5931",entriesManaged:"\u5DF2\u63A5\u7BA1",entriesUnmanaged:"\u672A\u63A5\u7BA1",entriesDrift:"\u6F02\u79FB",entriesNotRunning:"\u672A\u8FD0\u884C",agentTitle:"Agent \u5DE5\u5177",agentCount:"\u5DF2\u5F00\u542F {enabled}/{total}",agentMaster:"\u5141\u8BB8 Agent \u8C03\u7528\u8FD9\u4E9B\u5DE5\u5177",agentApproval:"\u4F1A\u6539\u53D8\u72B6\u6001\u7684\u5DE5\u5177\u5728\u8FD0\u884C\u524D\u4F1A\u8BF7\u6C42\u6279\u51C6\u3002",agentApprovalBadge:"\u9700\u6279\u51C6",reclaimAutoLabel:"\u88AB\u62D2\u7EDD\u65F6\u81EA\u52A8\u91CD\u65B0\u751F\u6210\u4EE4\u724C",reclaimAutoHint:"\u5DE5\u5177\u8C03\u7528\u9047\u5230\u88AB\u62D2\u7EDD\u7684\u4EE4\u724C\u65F6\u4F1A\u91CD\u65B0\u767B\u8BB0\u5E76\u91CD\u8BD5\uFF0C\u800C\u4E0D\u662F\u76F4\u63A5\u5931\u8D25\u3002",instancesNoticeLabel:"\u5411 Agent \u8BF4\u660E\u5176\u4ED6\u9762\u677F",instancesNoticeHint:"\u628A\u9762\u677F\u6E05\u5355\u52A0\u5165 Agent \u4E0A\u4E0B\u6587\uFF1B\u5B58\u5728\u591A\u4E2A\u9762\u677F\u65F6\u4F1A\u5148\u8BE2\u95EE\u8981\u64CD\u4F5C\u54EA\u4E00\u4E2A\u3002",agentToolStatus:"\u67E5\u770B\u72B6\u6001",agentToolWorkspacesList:"\u5217\u51FA\u5DE5\u4F5C\u533A",agentToolServersList:"\u5217\u51FA\u670D\u52A1\u5668",agentToolServersLifecycle:"\u542F\u52A8\u3001\u505C\u6B62\u3001\u91CD\u542F",agentToolServersEdit:"\u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664",agentToolAutostartManage:"\u7BA1\u7406\u5F00\u673A\u81EA\u542F",agentToolUiManage:"\u7BA1\u7406\u9762\u677F UI",agentToolDescStatus:"\u8BFB\u53D6\u9762\u677F\u3001\u6B63\u5728\u4F7F\u7528\u7684 CLI \u526F\u672C\u548C\u53D7\u7BA1\u6761\u76EE\u3002\u4E0D\u6539\u53D8\u4EFB\u4F55\u72B6\u6001\u3002",agentToolDescWorkspacesList:"\u5217\u51FA\u9762\u677F\u63D0\u4F9B\u7684\u6240\u6709\u5DE5\u4F5C\u533A\u53CA\u5176\u6761\u76EE\u6570\u548C\u8FD0\u884C\u6570\u3002\u670D\u52A1\u5668 id \u53EA\u5728\u5DE5\u4F5C\u533A\u5185\u552F\u4E00\u3002",agentToolDescServersList:"\u5217\u51FA\u67D0\u4E2A\u5DE5\u4F5C\u533A\u4E2D\u88AB\u9762\u677F\u76D1\u7BA1\u7684\u670D\u52A1\u5668\u53CA\u5176\u72B6\u6001\u3001\u7AEF\u53E3\u548C URL\u3002\u670D\u52A1\u5668 id \u53EA\u5728\u5DE5\u4F5C\u533A\u5185\u552F\u4E00\u3002",agentToolDescServersLifecycle:"\u542F\u52A8\u3001\u505C\u6B62\u548C\u91CD\u542F\u53D7\u76D1\u7BA1\u7684\u670D\u52A1\u5668\uFF0C\u4F5C\u7528\u4E8E\u8C03\u7528\u6240\u6307\u5B9A\u7684\u5DE5\u4F5C\u533A\u3002",agentToolDescServersEdit:"\u521B\u5EFA\u3001\u66F4\u65B0\u548C\u5220\u9664\u670D\u52A1\u5668\u6761\u76EE\uFF0C\u4F5C\u7528\u4E8E\u8C03\u7528\u6240\u6307\u5B9A\u7684\u5DE5\u4F5C\u533A\u3002",agentToolDescAutostartManage:"\u5B89\u88C5\u6216\u79FB\u9664\u542F\u52A8\u9762\u677F\u7684\u5F00\u673A\u9879\u3002",agentToolDescUiManage:"\u67E5\u770B\u3001\u66F4\u65B0\u3001\u56DE\u9000\u6216\u5207\u6362\u9762\u677F\u81EA\u8EAB\u7684 UI \u6784\u5EFA\u3002",serversTitle:"\u670D\u52A1\u5668",serversCount:"{total} \u4E2A\u4E2D {running} \u4E2A\u8FD0\u884C\u4E2D",serversHintPanel:"\u5728 home-hosted \u9762\u677F\u4E2D\u7BA1\u7406\u6761\u76EE\uFF1A",serversHintNoPanel:"\u5F53\u524D\u65E0\u6CD5\u7BA1\u7406\u6761\u76EE\uFF1A\u9762\u677F\u6CA1\u6709\u8FD0\u884C\u3002",serversEmpty:"\u9762\u677F\u672A\u62A5\u544A\u4EFB\u4F55\u670D\u52A1\u5668\u3002",serversPid:"PID",serversUrl:"URL",serversCommand:"\u547D\u4EE4",serversArgs:"\u53C2\u6570",serversCwd:"\u5DE5\u4F5C\u76EE\u5F55",serversPort:"\u7AEF\u53E3",serversOnPortConflict:"\u7AEF\u53E3\u51B2\u7A81\u65F6",serversAutostart:"\u81EA\u542F",serversPersistent:"\u6301\u4E45\u5316",serversPersistentHint:"\u7531 home-hosted \u81EA\u5E26\u7684 nanny \u6258\u7BA1\uFF0C\u505C\u6B62\u6216\u91CD\u542F\u9762\u677F\u4E0D\u4F1A\u505C\u6B62\u5B83\u3002",serversHealth:"\u5065\u5EB7\u68C0\u67E5",serversRestartPolicy:"\u91CD\u542F",serversConfiguration:"\u914D\u7F6E",serversRawConfig:"\u539F\u59CB\u914D\u7F6E",serversDisabled:"\u5DF2\u505C\u7528",serversEnabled:"\u5DF2\u542F\u7528",serversHealthHttp:"HTTP {status} \u4E8E {path}",serversHealthHttpBelow:"HTTP <{status} \u4E8E {path}",serversHealthHttpProbe:"HTTP \u63A2\u6D4B {path}",serversHealthPort:"\u7AEF\u53E3 {port}",serversHealthProbe:"\u7AEF\u53E3\u63A2\u6D4B",serversHealthEvery:"\u6BCF {seconds}",serversRestartSummary:"{retries} \u6B21\u91CD\u8BD5 \xB7 {base} \u2192 \xD7{factor}",serversStart:"\u542F\u52A8",serversStop:"\u505C\u6B62",serversRestart:"\u91CD\u542F",serversWorkspace:"\u5DE5\u4F5C\u533A",serversAdd:"\u6DFB\u52A0\u670D\u52A1\u5668",serversEdit:"\u7F16\u8F91",serversEditTitle:"\u7F16\u8F91 {id}",serversCreateTitle:"\u6DFB\u52A0\u670D\u52A1\u5668",serversEditorHint:"\u53EA\u5199\u5165\u4F60\u6539\u52A8\u7684\u5B57\u6BB5\uFF0C\u5176\u4F59\u4ECD\u7EE7\u627F\u5DE5\u4F5C\u533A\u9ED8\u8BA4\u503C\u3002",serversCreate:"\u521B\u5EFA",serversSave:"\u4FDD\u5B58",serversDelete:"\u5220\u9664",serversDeleteTitle:"\u5220\u9664 {id}\uFF1F",serversDeleteBody:"\u8FD9\u4F1A\u4ECE\u5DE5\u4F5C\u533A {workspace} \u4E2D\u79FB\u9664\u8BE5\u6761\u76EE\uFF0C\u8FD0\u884C\u4E2D\u7684\u670D\u52A1\u5668\u4E5F\u4F1A\u968F\u4E4B\u505C\u6B62\u3002",serversDeleteGo:"\u5220\u9664",serversFreePort:"\u91CA\u653E\u7AEF\u53E3",serversFreePortTitle:"\u91CA\u653E\u7AEF\u53E3 {port}\uFF1F",serversFreePortBody:"\u505C\u6B62\u5360\u7528\u8BE5\u7AEF\u53E3\u7684\u8FDB\u7A0B\uFF0C\u9664\u975E\u5B83\u7531\u9762\u677F\u76D1\u7BA1\u3002\u8FDB\u7A0B\u5148\u6536\u5230 SIGTERM\uFF0C\u4E4B\u540E\u4F1A\u88AB\u5F3A\u5236\u505C\u6B62\u3002",serversFreePortGo:"\u91CA\u653E",serversPortFreed:"\u7AEF\u53E3 {port} \u5DF2\u91CA\u653E\u3002",serversPortHeld:"\u7AEF\u53E3 {port} \u4ECD\u88AB\u5360\u7528\u3002",serversPortSkipped:"\u8BE5\u76D1\u542C\u8005\u5C5E\u4E8E\u9762\u677F\u76D1\u7BA1\u7684\u670D\u52A1\u5668\uFF0C\u56E0\u6B64\u672A\u88AB\u52A8\u5B83\u3002",serversPortRefused:"\u7AEF\u53E3\u672A\u80FD\u91CA\u653E\uFF1A{message}",fieldId:"Id",fieldIdHint:"\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001`_` \u548C `-`\uFF1B\u5728\u5DE5\u4F5C\u533A\u5185\u552F\u4E00\u3002",fieldIdInvalid:"id \u4EE5\u5C0F\u5199\u5B57\u6BCD\u6216\u6570\u5B57\u5F00\u5934\uFF0C\u53EA\u80FD\u5305\u542B a-z\u30010-9\u3001_ \u548C -\u3002",fieldLabel:"\u6807\u7B7E",fieldCommand:"\u547D\u4EE4",fieldArgs:"\u53C2\u6570",fieldArgsHint:"\u6BCF\u884C\u4E00\u4E2A\u53C2\u6570\u3002",fieldCwd:"\u5DE5\u4F5C\u76EE\u5F55",fieldPort:"\u7AEF\u53E3",fieldPortHint:"\u7559\u7A7A\u8868\u793A\u8BE5\u6761\u76EE\u6CA1\u6709\u7AEF\u53E3\u3002",fieldPortInvalid:"\u8BF7\u8F93\u5165 1 \u5230 65535 \u4E4B\u95F4\u7684\u7AEF\u53E3\uFF0C\u6216\u7559\u7A7A\u3002",fieldAutostart:"\u968F\u9762\u677F\u542F\u52A8",fieldOnPortConflict:"\u7AEF\u53E3\u51B2\u7A81\u65F6",fieldInherit:"\u7EE7\u627F",fieldRequired:"Id \u548C\u547D\u4EE4\u4E3A\u5FC5\u586B\u3002"};function Zt(e,t){return t===void 0?e:e.replace(/\{(\w+)\}/g,(n,r)=>Object.prototype.hasOwnProperty.call(t,r)?String(t[r]):n)}var Ue=(e,t)=>Zt(Ne[e]??e,t);function We(e){if(e!==void 0)try{let t=e.bind(ve);if(typeof t=="function")return t}catch{}return Ue}function Ve(e,t=Ue){return e===void 0?t:(n,r)=>{let o;try{o=e(n,r)}catch{o=void 0}return o===void 0||o.length===0||o===n?t(n,r):o}}var U=require("react");var te=require("react");var $e="/home-hosted";var je="default";var ze=["block","warn","follow","reclaim","kill"];var se=["status","workspaces_list","servers_list","servers_lifecycle","servers_edit","autostart_manage","ui_manage"],Ge=["servers_lifecycle","servers_edit","autostart_manage","ui_manage"],Qt=3,Bn={version:Qt,autostart:{enabled:!1,mechanism:"auto"},manageDsh:!1,entries:[],agentTools:{enabled:!0,allow:[...se]},panel:{port:null},authNotice:!0,reclaimToken:!0,instancesNotice:!0,uiStyle:"detailed",cli:{prefer:"pinned"}};var en="/api";function Q(e,t,n){return{ok:!1,error:n===void 0?{code:e,message:t}:{code:e,message:t,detail:n}}}function Re(e){return typeof e=="object"&&e!==null}function tn(e){return e instanceof Error?e.message:String(e)}function nn(e){if(!Re(e))return Q("bad-response","The panel returned a non-object response");if(typeof e.v=="number"&&e.v!==1)return Q("version-mismatch",`Response protocol v${e.v} does not match the expected v${1}`);let t=e.result;if(!Re(t))return Q("bad-response","The panel returned no result");if(t.ok===!0)return"value"in t?{ok:!0,value:t.value}:Q("bad-response","A successful response carried no value");if(t.ok===!1){let n=t.error;return Re(n)&&typeof n.message=="string"?Q(typeof n.code=="string"?n.code:"error",n.message,n.detail):Q("error","The panel reported a failure without a message")}return Q("bad-response","The panel returned an unrecognised result")}async function C(e,t,n={}){let r=n.fetch??globalThis.fetch;if(typeof r!="function")return Q("no-fetch","No fetch implementation is available");let o={v:1,endpoint:e,payload:t},a;try{a=await r(`${en}${$e}`,{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify(o)})}catch(s){return Q("network",tn(s))}if(!a.ok){let s=a.statusText.length>0?` ${a.statusText}`:"";return Q("http",`HTTP ${a.status}${s}`)}let i;try{i=await a.json()}catch{return Q("bad-json","The panel returned invalid JSON")}return nn(i)}function Ke(e,t={}){return C("settings.update",{patch:e},t)}var on=5e3;function Ye(e=on){let[t,n]=(0,te.useState)(null),[r,o]=(0,te.useState)(null),[a,i]=(0,te.useState)(!0),s=(0,te.useRef)(!0),u=(0,te.useCallback)(async()=>{let c=await C("status",{});s.current&&(c.ok?(n(c.value),o(null)):o(c.error),i(!1))},[]);return(0,te.useEffect)(()=>{s.current=!0,u();let c=setInterval(()=>{u()},e);return()=>{s.current=!1,clearInterval(c)}},[u,e]),{data:t,error:r,loading:a,refresh:u}}var w=require("react/jsx-runtime");function ne({size:e=14,children:t}){return(0,w.jsx)("svg",{width:e,height:e,viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:t})}function qe(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("rect",{x:"2.2",y:"3",width:"11.6",height:"7.6",rx:"1.6"}),(0,w.jsx)("path",{d:"M6.6 13.4h2.8M8 10.6v2.8"})]})}function Je(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M8 2.4v5.2"}),(0,w.jsx)("path",{d:"M11.6 4.4a5 5 0 1 1-7.2 0"})]})}function Xe(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("rect",{x:"2.2",y:"2.8",width:"11.6",height:"10.4",rx:"1.6"}),(0,w.jsx)("path",{d:"M5.2 6.9l1.8 1.8-1.8 1.8M8.7 10.5h2.2"})]})}function Ze(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M2.4 5.4h11.2M2.4 10.6h11.2"}),(0,w.jsx)("circle",{cx:"6",cy:"5.4",r:"1.6",fill:"currentColor",stroke:"none"}),(0,w.jsx)("circle",{cx:"10.4",cy:"10.6",r:"1.6",fill:"currentColor",stroke:"none"})]})}function be(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M8 2.3l5.4 2.9L8 8.1 2.6 5.2z"}),(0,w.jsx)("path",{d:"M2.6 8.6l5.4 2.9 5.4-2.9"}),(0,w.jsx)("path",{d:"M2.6 11.4l5.4 2.9 5.4-2.9"})]})}function Qe(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M13.4 9.4A5.5 5.5 0 1 1 12.2 4.4"}),(0,w.jsx)("path",{d:"M12.8 1.7v2.9h-2.9"})]})}function et(e){return(0,w.jsx)(ne,{...e,children:(0,w.jsx)("path",{d:"M6.2 3.8L10.4 8l-4.2 4.2"})})}function tt(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M6.6 3.4H3.4v9.2h9.2V9.4"}),(0,w.jsx)("path",{d:"M9.4 3.4h3.2v3.2M12.6 3.4L7.8 8.2"})]})}function ye(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M8 2.6l5.7 10.2H2.3z"}),(0,w.jsx)("path",{d:"M8 6.4v3.1M8 11.5h.01"})]})}function nt(e){return(0,w.jsx)(ne,{...e,children:(0,w.jsx)("path",{d:"M3 8.4l3.3 3.3L13 5"})})}var q="\u2014";function I(e){if(e==null)return q;let t=String(e);return t.length>0?t:q}function ot(e){return e.length>0?e.join(", "):q}function Ie(e){return Ge.includes(e)}var He={status:"agentToolStatus",workspaces_list:"agentToolWorkspacesList",servers_list:"agentToolServersList",servers_lifecycle:"agentToolServersLifecycle",servers_edit:"agentToolServersEdit",autostart_manage:"agentToolAutostartManage",ui_manage:"agentToolUiManage"},rt={status:"agentToolDescStatus",workspaces_list:"agentToolDescWorkspacesList",servers_list:"agentToolDescServersList",servers_lifecycle:"agentToolDescServersLifecycle",servers_edit:"agentToolDescServersEdit",autostart_manage:"agentToolDescAutostartManage",ui_manage:"agentToolDescUiManage"},at={api:"writeViaApi",file:"writeViaFile",none:"writeViaNone"},it={enrolled:"tokenEnrolled",present:"tokenPresent",absent:"tokenAbsent",stale:"tokenStale",unknown:"tokenUnknown"},we={"not-installed":"bootStateNotInstalled","installed-disabled":"bootStateInstalledDisabled","enabled-running":"bootStateEnabledRunning","enabled-failing":"bootStateEnabledFailing",unsupported:"bootStateUnsupported"},st={config:"panelCliConfig",dependency:"panelCliDependency",path:"panelCliPathSource",none:"panelCliMissing"};function xe(e,t=52){if(e.length<=t)return e;let n=e.includes("\\")?"\\":"/",r=e.split(/[\\/]/).filter(s=>s.length>0);if(r.length<4)return e;let o=/^[A-Za-z]:$/.test(r[0]??"")?3:2;if(r.length<=o)return e;let i=`${/^[\\/]/.test(e)?n:""}${r.slice(0,o).join(n)}${n}\u2026${n}${r.slice(-2).join(n)}`;return i.length<e.length?i:e}function lt(e){let t=n=>e.source===n&&e.path!==null?{source:n,path:e.path,version:e.version}:null;return{dependency:e.dependency??t("dependency"),global:e.global??t("path")}}function dt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function rn(e,t){if(Object.is(e,t))return!0;try{return JSON.stringify(e)===JSON.stringify(t)}catch{return!1}}function ct(e,t){let n={};for(let r of Object.keys(t)){let o=e[r],a=t[r];if(dt(o)&&dt(a)){let i=ct(o,a);Object.keys(i).length>0&&(n[r]=i)}else rn(o,a)||(n[r]=a)}return n}function pt(e,t){return ct(e,t)}function ht(e,t,n){let r=new Set(e);return n?r.add(t):r.delete(t),se.filter(o=>r.has(o))}var gt=require("react");async function ut(e){try{if(typeof navigator<"u"&&navigator.clipboard!==void 0)return await navigator.clipboard.writeText(e),!0}catch{}return!1}var p=require("react/jsx-runtime");function an(...e){return e.filter(t=>typeof t=="string"&&t.length>0).join(" ")}function J({icon:e,title:t,action:n,children:r}){return(0,p.jsxs)("section",{className:"hh-section",children:[(0,p.jsxs)("header",{className:"hh-section-head",children:[e===void 0?null:(0,p.jsx)("span",{className:"hh-section-icon",children:e}),(0,p.jsx)("h3",{className:"hh-section-title",children:t}),(0,p.jsx)("span",{className:"hh-section-rule","aria-hidden":"true"}),n===void 0?null:(0,p.jsx)("span",{className:"hh-section-action",children:n})]}),(0,p.jsx)("div",{className:"hh-section-body",children:r})]})}function N({label:e,children:t}){return(0,p.jsxs)("div",{className:"hh-spec",children:[(0,p.jsx)("span",{className:"hh-spec-label",children:e}),(0,p.jsx)("span",{className:"hh-spec-value",children:t})]})}function ee({children:e}){return(0,p.jsx)("code",{className:"hh-code",children:e})}function m({children:e}){return typeof e=="string"&&e.length===0?null:(0,p.jsx)("p",{className:"hh-hint",children:e})}function D({tone:e,children:t}){return(0,p.jsx)("span",{className:"hh-chip","data-tone":e??"idle",children:t})}function re({href:e,children:t}){return(0,p.jsxs)("a",{className:"hh-link",href:e,target:"_blank",rel:"noreferrer noopener",children:[t??e,(0,p.jsx)("span",{className:"hh-link-icon","aria-hidden":"true",children:(0,p.jsx)(tt,{size:11})})]})}function oe({label:e,open:t=!1,children:n}){return(0,p.jsxs)("details",{className:"hh-details",open:t||void 0,children:[(0,p.jsxs)("summary",{className:"hh-summary",children:[(0,p.jsx)("span",{className:"hh-chevron","aria-hidden":"true",children:(0,p.jsx)(et,{size:12})}),e]}),(0,p.jsx)("div",{className:"hh-details-body",children:n})]})}function z({tone:e="bad",icon:t=!0,title:n,children:r}){return(0,p.jsxs)("div",{className:"hh-note","data-tone":e,role:e==="bad"?"alert":"note",children:[t?(0,p.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,p.jsx)(ye,{size:13})}):null,(0,p.jsxs)("div",{className:"hh-note-body",children:[n===void 0?null:(0,p.jsx)("span",{className:"hh-note-title",children:n}),typeof r=="string"?(0,p.jsx)("p",{children:r}):r]})]})}function ke({title:e,detail:t}){return(0,p.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,p.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,p.jsx)(ye,{size:13})}),(0,p.jsxs)("div",{className:"hh-note-body",children:[(0,p.jsx)("strong",{children:e}),t.length>0?(0,p.jsx)("p",{children:t}):null]})]})}function ge({error:e,title:t}){return e===null?null:(0,p.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,p.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,p.jsx)(ye,{size:13})}),(0,p.jsxs)("div",{className:"hh-note-body",children:[(0,p.jsx)("strong",{children:t}),(0,p.jsxs)("p",{children:[(0,p.jsx)("code",{children:e.code})," \u2014 ",e.message]})]})]})}function sn(){return(0,p.jsx)("span",{className:"hh-spinner","aria-hidden":"true"})}function y({children:e,onClick:t,disabled:n,busy:r,variant:o="default",icon:a,title:i}){let s=n===!0||r===!0;return(0,p.jsxs)("button",{type:"button",className:an("hh-btn",o!=="default"&&`hh-btn-${o}`),onClick:t,disabled:s,title:i,children:[r===!0?(0,p.jsx)(sn,{}):a,e]})}function pe({label:e,checked:t,disabled:n,onChange:r}){return(0,p.jsxs)("button",{type:"button",role:"switch",className:"hh-switch","aria-checked":t,disabled:n,onClick:()=>r(!t),children:[(0,p.jsx)("span",{className:"hh-switch-track","aria-hidden":"true",children:(0,p.jsx)("span",{className:"hh-switch-knob"})}),(0,p.jsx)("span",{className:"hh-check-label",children:e})]})}function mt({label:e,checked:t,disabled:n,onChange:r}){return(0,p.jsxs)("label",{className:"hh-check",children:[(0,p.jsx)("input",{type:"checkbox",checked:t,disabled:n,onChange:o=>r(o.target.checked)}),(0,p.jsx)("span",{className:"hh-check-label",children:e})]})}function ce({value:e,options:t,disabled:n,label:r,onChange:o}){return(0,p.jsx)("select",{className:"hh-select",value:e,disabled:n,"aria-label":r,onChange:a=>o(a.target.value),children:t.map(a=>(0,p.jsx)("option",{value:a.value,children:a.label},a.value))})}function me({label:e,meta:t,path:n,hint:r,checked:o,disabled:a,onChange:i}){return(0,p.jsxs)("label",{className:"hh-choice-option","data-disabled":a===!0,children:[(0,p.jsx)("input",{type:"radio",checked:o,disabled:a,onChange:()=>i()}),(0,p.jsxs)("span",{className:"hh-choice-label",children:[(0,p.jsx)("span",{children:e}),r]}),t===void 0?null:(0,p.jsx)("span",{className:"hh-choice-meta",children:t}),n===void 0?null:(0,p.jsx)("span",{className:"hh-choice-path",title:n,children:xe(n)})]})}function Se({children:e}){return(0,p.jsxs)(D,{tone:"accent",children:[(0,p.jsx)(nt,{size:10}),e]})}function fe({text:e,copyLabel:t,copiedLabel:n}){let[r,o]=(0,gt.useState)(!1);return(0,p.jsxs)("div",{className:"hh-code-box",children:[(0,p.jsx)("textarea",{className:"hh-code-text",readOnly:!0,value:e,rows:Math.min(e.split(`
|
|
3
|
+
"use strict";var Ee=Object.defineProperty;var Gt=Object.getOwnPropertyDescriptor;var Kt=Object.getOwnPropertyNames;var Yt=Object.prototype.hasOwnProperty;var qt=(e,t)=>{for(var n in t)Ee(e,n,{get:t[n],enumerable:!0})},Jt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Kt(t))!Yt.call(e,o)&&o!==n&&Ee(e,o,{get:()=>t[o],enumerable:!(r=Gt(t,o))||r.enumerable});return e};var Xt=e=>Jt(Ee({},"__esModule",{value:!0}),e);var Mn={};qt(Mn,{apply:()=>Hn,inject:()=>In});module.exports=Xt(Mn);var ve="homeHosted",Ne={tab:"Home Hosted",loading:"Loading\u2026",refresh:"Refresh",retry:"Retry",errorTitle:"Error",statusUnavailable:"The panel did not answer.",yes:"Yes",no:"No",copy:"Copy",copied:"Copied",details:"Details",uiStyleLabel:"Page style",uiStyleDetailed:"Detailed",uiStyleCompact:"Compact",workspacesTitle:"Workspaces",workspacesHint:"Every workspace this panel serves. Viewing one decides what this page lists.",workspacesViewLabel:"Workspace to view",workspacesEmpty:"The panel reports no workspaces yet.",workspacesManagedTag:"managed by the plugin",workspacesViewingTag:"viewing",workspacesCounts:"{servers} servers \xB7 {running} running",workspacesCountsFile:"{servers} in the config files",workspacesDegraded:"The panel is not answering, so these counts \u2014 and the entry list below \u2014 come from the workspace config files, not from live state.",workspaceLegacyTitle:"This state root still uses the pre-0.7 layout",workspaceLegacyBody:"The plugin cannot read or write its files until they move into .hh. Starting the panel once does the same move; this runs it directly.",workspaceMigrate:"Migrate state root",workspaceMigrateFailed:"The migration did not run.",workspaceMigrateDone:"The state root was migrated.",sigPanel:"Panel",sigAutostart:"Autostart",sigEntry:"{id} entry",stateAnswering:"answering",stateNotAnswering:"not answering",stateManaged:"managed",stateNotManaged:"not managed",panelTitle:"Panel",panelCopy:"Which copy runs the panel",panelCopyHint:"The pinned copy ships with this plugin; the global one is on PATH.",optionsPreferPinned:"Pinned dependency",optionsPreferGlobal:"Global install",optionsRecommended:"recommended",optionsConfigOverride:"The plugin row sets homeHostedCommand, and that always wins.",optionsInstallLabel:"Install a global copy",optionsInstallHint:"No global install was found. Install the pinned range, then choose it above:",optionsInstall:"Install globally",panelHome:"Panel root",panelUrl:"URL",panelVersion:"Version",panelPid:"PID",panelWriteVia:"Writes via",panelToken:"API token",panelCliSource:"CLI",panelCliPath:"CLI path",panelCliConfig:"configured command",panelCliDependency:"pinned dependency",panelCliPathSource:"global install (PATH)",panelCliMissing:"not found",panelCliNotPinned:"This host resolved a global home-hosted instead of the pinned copy ({range}).",panelCliUnsupported:"This home-hosted is older than the oldest release the plugin supports.",panelCliLauncherFailed:"The boot launcher did not answer, so a boot entry may fail to start the panel.",panelPort:"Panel port",panelPortHint:"Only changeable while the panel is stopped.",panelPortFree:"Leave empty to use the port in the config.",panelPortInvalid:"Enter a port between 1 and 65535.",panelStart:"Start the panel",panelStop:"Stop the panel",panelStopTitle:"Stop the running panel?",panelStopBody:"This stops the panel and every server it supervises \u2014 this session included, so the page may disconnect. An autostart entry starts them again at the next panel start.",panelStopping:"Stopping the panel\u2026",panelStopped:"The panel stopped.",panelStopFailed:"The panel did not stop: {message}",panelRootLegacy:"Adopted from ~/.home-hosted. Set HHOSTED_HOME to give this dsh its own panel.",confirmStop:"Stop",panelOutdated:"Outdated panel",panelReplace:"Restart with {copy}",panelCopyPinned:"pinned dependency",panelCopyGlobal:"global install",panelTakeoverTitle:"Restart the running panel?",panelTakeoverBody:"This stops the panel and every server it supervises \u2014 this session included, so the page disconnects. It needs the {id} entry adopted with autostart on.",confirmCancel:"Cancel",confirmReplace:"Restart",writeViaApi:"authenticated API",writeViaFile:"config file",writeViaNone:"unavailable",tokenEnrolled:"enrolled",tokenPresent:"present",tokenAbsent:"absent",tokenStale:"stale",tokenUnknown:"unknown",panelTokenWarningTitle:"The panel API token is missing or refused",panelTokenWarnAbsent:"This plugin has no API token for the panel, so it cannot read or write the panel; regenerate one.",panelTokenWarnPresent:"home-hosted holds an API token this plugin does not have, so the plugin cannot authenticate; regenerate one to replace it.",panelTokenWarnStale:"The panel refused this plugin's API token; regenerate it.",panelTokenWarnUnreachable:"The plugin could not reach the panel to check its API token, so it cannot read or write the panel; the panel may need starting.",panelTokenWarnPanelDown:"The panel is not answering right now, so it may need starting too.",panelTokenRegenerate:"Regenerate token",panelTokenRegenerated:"A fresh API token was enrolled for the panel.",panelTokenRegenerateFailed:"The token was not replaced: {message}",panelInstances:"{count} panels found",panelInstanceManaged:"managed by this plugin",panelInstanceOther:"another panel",panelInstanceHosts:"hosts this dsh",panelInstancesHint:"This plugin drives only the managed one; the others are read from their state roots and never written to.",bootTitle:"Autostart",bootEnabled:"Enable autostart",bootUninstall:"Uninstall",bootSwitchMode:"Switch autostart",bootRecheck:"Re-check",bootMechanism:"Mechanism",bootMechanismAuto:"Automatic",bootState:"State",bootStateNotInstalled:"not installed",bootStateInstalledDisabled:"installed, off",bootStateEnabledRunning:"enabled, running",bootStateEnabledFailing:"enabled, failing",bootStateUnsupported:"unsupported",bootBootCapable:"Starts before login",bootPrivileged:"This process can install it",bootUnitPath:"Unit path",bootCommandsLabel:"Install by hand",bootCommandsExplain:"This process cannot elevate. Run these commands to install autostart:",bootRequestedNotInstalled:"Autostart is requested, but no boot entry is installed.",bootHandover:"Enabling this stops the panel this plugin started and starts it through the entry, so this page disconnects and comes back.",bootSwitchRetires:"Switching stops the panel and removes the previous autostart entry, so this page disconnects and comes back.",bootActionInstall:"install",bootActionUninstall:"uninstall",bootAttemptFailed:"{action} failed",bootAttemptSucceeded:"{action} succeeded \u2014 {detail}",bootAttemptNoDetail:"The host did not explain the refusal.",bootAttemptCommands:"Run these yourself:",entriesTitle:"Managed entry",entriesManage:"Manage {id}",entriesManageNote:"Hands {id} to home-hosted: boot autostart, panel control, port reclaim.",entriesManageWinWarning:"On Windows, `{id}` is managed via the `kill` onPortConflict policy, so when it is restarted detached by another plugin it may briefly fail to boot while home-hosted reclaims the process and port.",entriesEmpty:"{id} is not managed yet.",entriesExists:"exists",entriesMissing:"missing",entriesManaged:"managed",entriesUnmanaged:"unmanaged",entriesDrift:"drift",entriesNotRunning:"not running",agentTitle:"Agent tools",agentCount:"{enabled} of {total} on",agentMaster:"Let the agent use these tools",agentApproval:"Tools that change something ask for approval first.",agentApprovalBadge:"approval",reclaimAutoLabel:"Regenerate token automatically",reclaimAutoHint:"A tool call that finds a refused token re-enrols one and retries instead of failing.",instancesNoticeLabel:"Tell the agent about other panels",instancesNoticeHint:"Adds the panel inventory to the agent's context, and asks which panel to act on when several exist.",agentToolStatus:"Status",agentToolWorkspacesList:"List workspaces",agentToolServersList:"List servers",agentToolServersLifecycle:"Start, stop, restart",agentToolServersEdit:"Create, update, delete",agentToolAutostartManage:"Manage boot autostart",agentToolUiManage:"Manage Panel UI",agentToolDescStatus:"Read the panel, the CLI copy in use and the managed entry. Nothing changes.",agentToolDescWorkspacesList:"List every workspace the panel serves, with its entry and running counts. A server id is only unique inside a workspace.",agentToolDescServersList:"List the servers of one workspace, with status, port and URL.",agentToolDescServersLifecycle:"Start, stop and restart supervised servers.",agentToolDescServersEdit:"Create, update and delete server entries.",agentToolDescAutostartManage:"Install or remove the boot entry that starts the panel.",agentToolDescUiManage:"Inspect, update, revert or install an official UI build.",serversTitle:"Servers",serversCount:"{running} of {total} running",serversHintPanel:"Entries are managed in the home-hosted panel:",serversHintNoPanel:"Entries cannot be managed right now: the panel is not running.",serversEmpty:"The panel reports no servers.",serversPid:"PID",serversUrl:"URL",serversCommand:"Command",serversArgs:"Args",serversCwd:"Working dir",serversPort:"Port",serversOnPortConflict:"On port conflict",serversAutostart:"Autostart",serversPersistent:"Persistent",serversPersistentHint:"Run by home-hosted's own nanny, so stopping or restarting the panel leaves it alive.",serversHealth:"Health",serversRestartPolicy:"Restart",serversConfiguration:"Configuration",serversRawConfig:"Raw config",serversDisabled:"disabled",serversEnabled:"enabled",serversHealthHttp:"HTTP {status} on {path}",serversHealthHttpBelow:"HTTP <{status} on {path}",serversHealthHttpProbe:"HTTP probe on {path}",serversHealthPort:"port {port}",serversHealthProbe:"port probe",serversHealthEvery:"every {seconds}",serversRestartSummary:"{retries} retries \xB7 {base} \u2192 \xD7{factor}",serversStart:"Start",serversStop:"Stop",serversRestart:"Restart",serversWorkspace:"Workspace",serversAdd:"Add server",serversEdit:"Edit",serversEditTitle:"Edit {id}",serversCreateTitle:"Add a server",serversEditorHint:"Only the fields you change are written; everything else keeps inheriting the workspace defaults.",serversCreate:"Create",serversSave:"Save",serversDelete:"Delete",serversDeleteTitle:"Delete {id}?",serversDeleteBody:"This removes the entry from workspace {workspace}. A running server is stopped with it.",serversDeleteGo:"Delete",serversFreePort:"Free port",serversFreePortTitle:"Free port {port}?",serversFreePortBody:"Stops whatever holds the port, unless the panel supervises it. Processes get SIGTERM first, then a forced stop.",serversFreePortGo:"Free",serversPortFreed:"Port {port} is free.",serversPortHeld:"Port {port} is still held.",serversPortSkipped:"The listener belongs to a server the panel supervises, so it was left alone.",serversPortRefused:"The port was not freed: {message}",fieldId:"Id",fieldIdHint:"Lowercase letters, digits, `_` and `-`; unique inside the workspace.",fieldIdInvalid:"An id starts with a lowercase letter or digit and uses only a-z, 0-9, _ and -.",fieldLabel:"Label",fieldCommand:"Command",fieldArgs:"Arguments",fieldArgsHint:"One argument per line.",fieldCwd:"Working directory",fieldPort:"Port",fieldPortHint:"Empty means the entry has no port.",fieldPortInvalid:"Enter a port between 1 and 65535, or leave it empty.",fieldAutostart:"Start with the panel",fieldOnPortConflict:"On port conflict",fieldInherit:"Inherit",fieldRequired:"Id and command are required."},_e={tab:"Home Hosted",loading:"\u52A0\u8F7D\u4E2D\u2026",refresh:"\u5237\u65B0",retry:"\u91CD\u8BD5",errorTitle:"\u9519\u8BEF",statusUnavailable:"\u9762\u677F\u6CA1\u6709\u54CD\u5E94\u3002",yes:"\u662F",no:"\u5426",copy:"\u590D\u5236",copied:"\u5DF2\u590D\u5236",details:"\u8BE6\u60C5",uiStyleLabel:"\u9875\u9762\u6837\u5F0F",uiStyleDetailed:"\u8BE6\u7EC6",uiStyleCompact:"\u7D27\u51D1",workspacesTitle:"\u5DE5\u4F5C\u533A",workspacesHint:"\u6B64\u9762\u677F\u63D0\u4F9B\u7684\u6240\u6709\u5DE5\u4F5C\u533A\u3002\u67E5\u770B\u54EA\u4E2A\u5C31\u5217\u51FA\u54EA\u4E2A\u3002",workspacesViewLabel:"\u8981\u67E5\u770B\u7684\u5DE5\u4F5C\u533A",workspacesEmpty:"\u9762\u677F\u5C1A\u672A\u62A5\u544A\u4EFB\u4F55\u5DE5\u4F5C\u533A\u3002",workspacesManagedTag:"\u7531\u63D2\u4EF6\u7BA1\u7406",workspacesViewingTag:"\u6B63\u5728\u67E5\u770B",workspacesCounts:"{servers} \u4E2A\u670D\u52A1\u5668 \xB7 {running} \u4E2A\u8FD0\u884C\u4E2D",workspacesCountsFile:"\u914D\u7F6E\u6587\u4EF6\u4E2D {servers} \u4E2A",workspacesDegraded:"\u9762\u677F\u6CA1\u6709\u54CD\u5E94\uFF0C\u56E0\u6B64\u8FD9\u4E9B\u8BA1\u6570\u2014\u2014\u4EE5\u53CA\u4E0B\u65B9\u7684\u6761\u76EE\u5217\u8868\u2014\u2014\u6765\u81EA\u5DE5\u4F5C\u533A\u914D\u7F6E\u6587\u4EF6\uFF0C\u800C\u4E0D\u662F\u5B9E\u65F6\u72B6\u6001\u3002",workspaceLegacyTitle:"\u8BE5\u72B6\u6001\u76EE\u5F55\u4ECD\u662F 0.7 \u4E4B\u524D\u7684\u5E03\u5C40",workspaceLegacyBody:"\u5728\u6587\u4EF6\u79FB\u5165 .hh \u4E4B\u524D\uFF0C\u63D2\u4EF6\u65E0\u6CD5\u8BFB\u53D6\u6216\u5199\u5165\u5B83\u4EEC\u3002\u542F\u52A8\u4E00\u6B21\u9762\u677F\u5373\u53EF\u5B8C\u6210\u540C\u6837\u7684\u8FC1\u79FB\uFF1B\u6B64\u6309\u94AE\u76F4\u63A5\u6267\u884C\u8BE5\u547D\u4EE4\u3002",workspaceMigrate:"\u8FC1\u79FB\u72B6\u6001\u76EE\u5F55",workspaceMigrateFailed:"\u8FC1\u79FB\u6CA1\u6709\u6267\u884C\u3002",workspaceMigrateDone:"\u72B6\u6001\u76EE\u5F55\u5DF2\u8FC1\u79FB\u3002",sigPanel:"\u9762\u677F",sigAutostart:"\u5F00\u673A\u81EA\u542F",sigEntry:"{id} \u6761\u76EE",stateAnswering:"\u54CD\u5E94\u4E2D",stateNotAnswering:"\u672A\u54CD\u5E94",stateManaged:"\u5DF2\u63A5\u7BA1",stateNotManaged:"\u672A\u63A5\u7BA1",panelTitle:"\u9762\u677F",panelCopy:"\u7531\u54EA\u4E2A\u526F\u672C\u8FD0\u884C\u9762\u677F",panelCopyHint:"\u56FA\u5B9A\u526F\u672C\u968F\u63D2\u4EF6\u4E00\u8D77\u5B89\u88C5\uFF1B\u5168\u5C40\u526F\u672C\u6765\u81EA PATH\u3002",optionsPreferPinned:"\u56FA\u5B9A\u4F9D\u8D56",optionsPreferGlobal:"\u5168\u5C40\u5B89\u88C5",optionsRecommended:"\u63A8\u8350",optionsConfigOverride:"\u63D2\u4EF6\u884C\u4E2D\u7684 homeHostedCommand \u4F18\u5148\u7EA7\u6700\u9AD8\uFF0C\u59CB\u7EC8\u751F\u6548\u3002",optionsInstallLabel:"\u5B89\u88C5\u5168\u5C40\u526F\u672C",optionsInstallHint:"\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u3002\u5B89\u88C5\u56FA\u5B9A\u7248\u672C\u8303\u56F4\u540E\uFF0C\u5728\u4E0A\u65B9\u9009\u62E9\u5B83\uFF1A",optionsInstall:"\u5168\u5C40\u5B89\u88C5",panelHome:"\u9762\u677F\u6839\u76EE\u5F55",panelUrl:"URL",panelVersion:"\u7248\u672C",panelPid:"PID",panelWriteVia:"\u5199\u5165\u65B9\u5F0F",panelToken:"API \u4EE4\u724C",panelCliSource:"CLI",panelCliPath:"CLI \u8DEF\u5F84",panelCliConfig:"\u914D\u7F6E\u7684\u547D\u4EE4",panelCliDependency:"\u56FA\u5B9A\u7684\u4F9D\u8D56\u7248\u672C",panelCliPathSource:"\u5168\u5C40\u5B89\u88C5\uFF08PATH\uFF09",panelCliMissing:"\u672A\u627E\u5230",panelCliNotPinned:"\u6B64\u5BBF\u4E3B\u89E3\u6790\u5230\u7684\u662F\u5168\u5C40 home-hosted\uFF0C\u800C\u4E0D\u662F\u56FA\u5B9A\u526F\u672C\uFF08{range}\uFF09\u3002",panelCliUnsupported:"\u6B64 home-hosted \u65E9\u4E8E\u63D2\u4EF6\u652F\u6301\u7684\u6700\u8001\u7248\u672C\u3002",panelCliLauncherFailed:"\u5F00\u673A\u542F\u52A8\u5668\u6CA1\u6709\u5E94\u7B54\uFF0C\u5F00\u673A\u9879\u53EF\u80FD\u65E0\u6CD5\u542F\u52A8\u9762\u677F\u3002",panelPort:"\u9762\u677F\u7AEF\u53E3",panelPortHint:"\u4EC5\u5728\u9762\u677F\u505C\u6B62\u65F6\u53EF\u4FEE\u6539\u3002",panelPortFree:"\u7559\u7A7A\u5219\u4F7F\u7528\u914D\u7F6E\u6587\u4EF6\u4E2D\u7684\u7AEF\u53E3\u3002",panelPortInvalid:"\u8BF7\u8F93\u5165 1 \u5230 65535 \u4E4B\u95F4\u7684\u7AEF\u53E3\u3002",panelStart:"\u542F\u52A8\u9762\u677F",panelStop:"\u505C\u6B62\u9762\u677F",panelStopTitle:"\u505C\u6B62\u6B63\u5728\u8FD0\u884C\u7684\u9762\u677F\uFF1F",panelStopBody:"\u8FD9\u4F1A\u505C\u6B62\u9762\u677F\u4EE5\u53CA\u5B83\u76D1\u7BA1\u7684\u6240\u6709\u670D\u52A1\u5668\u2014\u2014\u5305\u62EC\u672C\u4F1A\u8BDD\uFF0C\u56E0\u6B64\u672C\u9875\u9762\u53EF\u80FD\u4F1A\u65AD\u5F00\u8FDE\u63A5\u3002\u5E26\u6709\u81EA\u542F\u7684\u6761\u76EE\u4F1A\u5728\u4E0B\u6B21\u542F\u52A8\u9762\u677F\u65F6\u91CD\u65B0\u542F\u52A8\u3002",panelStopping:"\u6B63\u5728\u505C\u6B62\u9762\u677F\u2026",panelStopped:"\u9762\u677F\u5DF2\u505C\u6B62\u3002",panelStopFailed:"\u9762\u677F\u672A\u80FD\u505C\u6B62\uFF1A{message}",panelRootLegacy:"\u6CBF\u7528\u4E86 ~/.home-hosted\u3002\u8BBE\u7F6E HHOSTED_HOME \u53EF\u8BA9\u6B64 dsh \u4F7F\u7528\u81EA\u5DF1\u7684\u9762\u677F\u3002",confirmStop:"\u505C\u6B62",panelOutdated:"\u9762\u677F\u5DF2\u8FC7\u65F6",panelReplace:"\u4F7F\u7528{copy}\u91CD\u542F",panelCopyPinned:"\u56FA\u5B9A\u4F9D\u8D56",panelCopyGlobal:"\u5168\u5C40\u5B89\u88C5",panelTakeoverTitle:"\u91CD\u542F\u6B63\u5728\u8FD0\u884C\u7684\u9762\u677F\uFF1F",panelTakeoverBody:"\u8FD9\u4F1A\u505C\u6B62\u9762\u677F\u4EE5\u53CA\u5B83\u76D1\u7BA1\u7684\u6240\u6709\u670D\u52A1\u5668\u2014\u2014\u5305\u62EC\u672C\u4F1A\u8BDD\uFF0C\u56E0\u6B64\u672C\u9875\u9762\u4F1A\u65AD\u5F00\u8FDE\u63A5\u3002\u4EC5\u5F53 {id} \u6761\u76EE\u5DF2\u88AB\u63A5\u7BA1\u4E14\u542F\u7528\u81EA\u542F\u65F6\u624D\u53EF\u7528\u3002",confirmCancel:"\u53D6\u6D88",confirmReplace:"\u91CD\u542F",writeViaApi:"\u5DF2\u8BA4\u8BC1 API",writeViaFile:"\u914D\u7F6E\u6587\u4EF6",writeViaNone:"\u4E0D\u53EF\u7528",tokenEnrolled:"\u5DF2\u767B\u8BB0",tokenPresent:"\u5DF2\u5B58\u5728",tokenAbsent:"\u4E0D\u5B58\u5728",tokenStale:"\u5DF2\u5931\u6548",tokenUnknown:"\u672A\u77E5",panelTokenWarningTitle:"\u9762\u677F API \u4EE4\u724C\u7F3A\u5931\u6216\u5DF2\u88AB\u62D2\u7EDD",panelTokenWarnAbsent:"\u672C\u63D2\u4EF6\u6CA1\u6709\u6B64\u9762\u677F\u7684 API \u4EE4\u724C\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u6216\u5199\u5165\u9762\u677F\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u4E00\u4E2A\u3002",panelTokenWarnPresent:"home-hosted \u6301\u6709\u4E00\u4E2A\u672C\u63D2\u4EF6\u6CA1\u6709\u7684 API \u4EE4\u724C\uFF0C\u63D2\u4EF6\u65E0\u6CD5\u901A\u8FC7\u8BA4\u8BC1\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u4E00\u4E2A\u4EE5\u66FF\u6362\u5B83\u3002",panelTokenWarnStale:"\u9762\u677F\u62D2\u7EDD\u4E86\u672C\u63D2\u4EF6\u7684 API \u4EE4\u724C\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u3002",panelTokenWarnUnreachable:"\u672C\u63D2\u4EF6\u65E0\u6CD5\u8BBF\u95EE\u9762\u677F\u4EE5\u68C0\u67E5\u5176 API \u4EE4\u724C\uFF0C\u56E0\u6B64\u65E0\u6CD5\u8BFB\u53D6\u6216\u5199\u5165\u9762\u677F\uFF1B\u9762\u677F\u53EF\u80FD\u8FD8\u9700\u8981\u5148\u542F\u52A8\u3002",panelTokenWarnPanelDown:"\u9762\u677F\u5F53\u524D\u6CA1\u6709\u54CD\u5E94\uFF0C\u53EF\u80FD\u8FD8\u9700\u8981\u5148\u542F\u52A8\u9762\u677F\u3002",panelTokenRegenerate:"\u91CD\u65B0\u751F\u6210\u4EE4\u724C",panelTokenRegenerated:"\u5DF2\u4E3A\u9762\u677F\u767B\u8BB0\u65B0\u4EE4\u724C\u3002",panelTokenRegenerateFailed:"\u4EE4\u724C\u672A\u66FF\u6362\uFF1A{message}",panelInstances:"\u53D1\u73B0 {count} \u4E2A\u9762\u677F",panelInstanceManaged:"\u7531\u672C\u63D2\u4EF6\u7BA1\u7406",panelInstanceOther:"\u5176\u4ED6\u9762\u677F",panelInstanceHosts:"\u6258\u7BA1\u5F53\u524D dsh",panelInstancesHint:"\u672C\u63D2\u4EF6\u53EA\u9A71\u52A8\u88AB\u7BA1\u7406\u7684\u90A3\u4E00\u4E2A\uFF1B\u5176\u4ED6\u9762\u677F\u4EC5\u4ECE\u5176\u72B6\u6001\u76EE\u5F55\u8BFB\u53D6\uFF0C\u7EDD\u4E0D\u5199\u5165\u3002",bootTitle:"\u5F00\u673A\u81EA\u542F",bootEnabled:"\u542F\u7528\u5F00\u673A\u81EA\u542F",bootUninstall:"\u5378\u8F7D",bootSwitchMode:"\u5207\u6362\u81EA\u542F\u673A\u5236",bootRecheck:"\u91CD\u65B0\u68C0\u67E5",bootMechanism:"\u673A\u5236",bootMechanismAuto:"\u81EA\u52A8",bootState:"\u72B6\u6001",bootStateNotInstalled:"\u672A\u5B89\u88C5",bootStateInstalledDisabled:"\u5DF2\u5B89\u88C5\uFF0C\u672A\u542F\u7528",bootStateEnabledRunning:"\u5DF2\u542F\u7528\uFF0C\u8FD0\u884C\u4E2D",bootStateEnabledFailing:"\u5DF2\u542F\u7528\uFF0C\u542F\u52A8\u5931\u8D25",bootStateUnsupported:"\u4E0D\u652F\u6301",bootBootCapable:"\u767B\u5F55\u524D\u542F\u52A8",bootPrivileged:"\u672C\u8FDB\u7A0B\u53EF\u5B89\u88C5",bootUnitPath:"\u5355\u5143\u6587\u4EF6\u8DEF\u5F84",bootCommandsLabel:"\u624B\u52A8\u5B89\u88C5",bootCommandsExplain:"\u672C\u8FDB\u7A0B\u65E0\u6CD5\u63D0\u6743\u3002\u8BF7\u81EA\u884C\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u6765\u5B89\u88C5\u81EA\u542F\uFF1A",bootRequestedNotInstalled:"\u5DF2\u8BF7\u6C42\u5F00\u673A\u81EA\u542F\uFF0C\u4F46\u5C1A\u672A\u5B89\u88C5\u4EFB\u4F55\u5F00\u673A\u9879\u3002",bootHandover:"\u542F\u7528\u540E\u4F1A\u505C\u6B62\u672C\u63D2\u4EF6\u542F\u52A8\u7684\u9762\u677F\uFF0C\u6539\u7531\u8BE5\u5F00\u673A\u9879\u542F\u52A8\uFF0C\u672C\u9875\u9762\u4F1A\u65AD\u5F00\u5E76\u81EA\u884C\u6062\u590D\u3002",bootSwitchRetires:"\u5207\u6362\u4F1A\u505C\u6B62\u9762\u677F\u5E76\u79FB\u9664\u5148\u524D\u7684\u81EA\u542F\u9879\uFF0C\u672C\u9875\u9762\u4F1A\u65AD\u5F00\u5E76\u81EA\u884C\u6062\u590D\u3002",bootActionInstall:"\u5B89\u88C5",bootActionUninstall:"\u5378\u8F7D",bootAttemptFailed:"{action}\u5931\u8D25",bootAttemptSucceeded:"{action}\u6210\u529F \u2014 {detail}",bootAttemptNoDetail:"\u5BBF\u4E3B\u6CA1\u6709\u8BF4\u660E\u5931\u8D25\u539F\u56E0\u3002",bootAttemptCommands:"\u4F60\u53EF\u4EE5\u81EA\u884C\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\uFF1A",entriesTitle:"\u53D7\u7BA1\u6761\u76EE",entriesManage:"\u63A5\u7BA1 {id}",entriesManageNote:"\u628A {id} \u4EA4\u7ED9 home-hosted\uFF1A\u5F00\u673A\u81EA\u542F\u3001\u9762\u677F\u63A7\u5236\u3001\u7AEF\u53E3\u56DE\u6536\u3002",entriesManageWinWarning:"\u5728 Windows \u4E0A\uFF0C`{id}` \u901A\u8FC7 `kill` \u7AEF\u53E3\u51B2\u7A81\u7B56\u7565\u7BA1\u7406\uFF1B\u5F53\u5B83\u88AB\u5176\u4ED6\u63D2\u4EF6\u4EE5\u5206\u79BB\u65B9\u5F0F\u91CD\u542F\u65F6\uFF0Chome-hosted \u56DE\u6536\u8FDB\u7A0B\u4E0E\u7AEF\u53E3\u671F\u95F4\u53EF\u80FD\u77ED\u6682\u65E0\u6CD5\u542F\u52A8\u3002",entriesEmpty:"\u5C1A\u672A\u63A5\u7BA1 {id}\u3002",entriesExists:"\u5B58\u5728",entriesMissing:"\u7F3A\u5931",entriesManaged:"\u5DF2\u63A5\u7BA1",entriesUnmanaged:"\u672A\u63A5\u7BA1",entriesDrift:"\u6F02\u79FB",entriesNotRunning:"\u672A\u8FD0\u884C",agentTitle:"Agent \u5DE5\u5177",agentCount:"\u5DF2\u5F00\u542F {enabled}/{total}",agentMaster:"\u5141\u8BB8 Agent \u8C03\u7528\u8FD9\u4E9B\u5DE5\u5177",agentApproval:"\u4F1A\u6539\u53D8\u72B6\u6001\u7684\u5DE5\u5177\u5728\u8FD0\u884C\u524D\u4F1A\u8BF7\u6C42\u6279\u51C6\u3002",agentApprovalBadge:"\u9700\u6279\u51C6",reclaimAutoLabel:"\u88AB\u62D2\u7EDD\u65F6\u81EA\u52A8\u91CD\u65B0\u751F\u6210\u4EE4\u724C",reclaimAutoHint:"\u5DE5\u5177\u8C03\u7528\u9047\u5230\u88AB\u62D2\u7EDD\u7684\u4EE4\u724C\u65F6\u4F1A\u91CD\u65B0\u767B\u8BB0\u5E76\u91CD\u8BD5\uFF0C\u800C\u4E0D\u662F\u76F4\u63A5\u5931\u8D25\u3002",instancesNoticeLabel:"\u5411 Agent \u8BF4\u660E\u5176\u4ED6\u9762\u677F",instancesNoticeHint:"\u628A\u9762\u677F\u6E05\u5355\u52A0\u5165 Agent \u4E0A\u4E0B\u6587\uFF1B\u5B58\u5728\u591A\u4E2A\u9762\u677F\u65F6\u4F1A\u5148\u8BE2\u95EE\u8981\u64CD\u4F5C\u54EA\u4E00\u4E2A\u3002",agentToolStatus:"\u67E5\u770B\u72B6\u6001",agentToolWorkspacesList:"\u5217\u51FA\u5DE5\u4F5C\u533A",agentToolServersList:"\u5217\u51FA\u670D\u52A1\u5668",agentToolServersLifecycle:"\u542F\u52A8\u3001\u505C\u6B62\u3001\u91CD\u542F",agentToolServersEdit:"\u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664",agentToolAutostartManage:"\u7BA1\u7406\u5F00\u673A\u81EA\u542F",agentToolUiManage:"\u7BA1\u7406\u9762\u677F UI",agentToolDescStatus:"\u8BFB\u53D6\u9762\u677F\u3001\u6B63\u5728\u4F7F\u7528\u7684 CLI \u526F\u672C\u548C\u53D7\u7BA1\u6761\u76EE\u3002\u4E0D\u6539\u53D8\u4EFB\u4F55\u72B6\u6001\u3002",agentToolDescWorkspacesList:"\u5217\u51FA\u9762\u677F\u63D0\u4F9B\u7684\u6240\u6709\u5DE5\u4F5C\u533A\u53CA\u5176\u6761\u76EE\u6570\u548C\u8FD0\u884C\u6570\u3002\u670D\u52A1\u5668 id \u53EA\u5728\u5DE5\u4F5C\u533A\u5185\u552F\u4E00\u3002",agentToolDescServersList:"\u5217\u51FA\u67D0\u4E2A\u5DE5\u4F5C\u533A\u4E2D\u88AB\u76D1\u7BA1\u7684\u670D\u52A1\u5668\u53CA\u5176\u72B6\u6001\u3001\u7AEF\u53E3\u548C URL\u3002",agentToolDescServersLifecycle:"\u542F\u52A8\u3001\u505C\u6B62\u548C\u91CD\u542F\u53D7\u76D1\u7BA1\u7684\u670D\u52A1\u5668\u3002",agentToolDescServersEdit:"\u521B\u5EFA\u3001\u66F4\u65B0\u548C\u5220\u9664\u670D\u52A1\u5668\u6761\u76EE\u3002",agentToolDescAutostartManage:"\u5B89\u88C5\u6216\u79FB\u9664\u542F\u52A8\u9762\u677F\u7684\u5F00\u673A\u9879\u3002",agentToolDescUiManage:"\u67E5\u770B\u3001\u66F4\u65B0\u3001\u56DE\u9000\u6216\u5B89\u88C5\u5B98\u65B9 UI \u6784\u5EFA\u3002",serversTitle:"\u670D\u52A1\u5668",serversCount:"{total} \u4E2A\u4E2D {running} \u4E2A\u8FD0\u884C\u4E2D",serversHintPanel:"\u5728 home-hosted \u9762\u677F\u4E2D\u7BA1\u7406\u6761\u76EE\uFF1A",serversHintNoPanel:"\u5F53\u524D\u65E0\u6CD5\u7BA1\u7406\u6761\u76EE\uFF1A\u9762\u677F\u6CA1\u6709\u8FD0\u884C\u3002",serversEmpty:"\u9762\u677F\u672A\u62A5\u544A\u4EFB\u4F55\u670D\u52A1\u5668\u3002",serversPid:"PID",serversUrl:"URL",serversCommand:"\u547D\u4EE4",serversArgs:"\u53C2\u6570",serversCwd:"\u5DE5\u4F5C\u76EE\u5F55",serversPort:"\u7AEF\u53E3",serversOnPortConflict:"\u7AEF\u53E3\u51B2\u7A81\u65F6",serversAutostart:"\u81EA\u542F",serversPersistent:"\u6301\u4E45\u5316",serversPersistentHint:"\u7531 home-hosted \u81EA\u5E26\u7684 nanny \u6258\u7BA1\uFF0C\u505C\u6B62\u6216\u91CD\u542F\u9762\u677F\u4E0D\u4F1A\u505C\u6B62\u5B83\u3002",serversHealth:"\u5065\u5EB7\u68C0\u67E5",serversRestartPolicy:"\u91CD\u542F",serversConfiguration:"\u914D\u7F6E",serversRawConfig:"\u539F\u59CB\u914D\u7F6E",serversDisabled:"\u5DF2\u505C\u7528",serversEnabled:"\u5DF2\u542F\u7528",serversHealthHttp:"HTTP {status} \u4E8E {path}",serversHealthHttpBelow:"HTTP <{status} \u4E8E {path}",serversHealthHttpProbe:"HTTP \u63A2\u6D4B {path}",serversHealthPort:"\u7AEF\u53E3 {port}",serversHealthProbe:"\u7AEF\u53E3\u63A2\u6D4B",serversHealthEvery:"\u6BCF {seconds}",serversRestartSummary:"{retries} \u6B21\u91CD\u8BD5 \xB7 {base} \u2192 \xD7{factor}",serversStart:"\u542F\u52A8",serversStop:"\u505C\u6B62",serversRestart:"\u91CD\u542F",serversWorkspace:"\u5DE5\u4F5C\u533A",serversAdd:"\u6DFB\u52A0\u670D\u52A1\u5668",serversEdit:"\u7F16\u8F91",serversEditTitle:"\u7F16\u8F91 {id}",serversCreateTitle:"\u6DFB\u52A0\u670D\u52A1\u5668",serversEditorHint:"\u53EA\u5199\u5165\u4F60\u6539\u52A8\u7684\u5B57\u6BB5\uFF0C\u5176\u4F59\u4ECD\u7EE7\u627F\u5DE5\u4F5C\u533A\u9ED8\u8BA4\u503C\u3002",serversCreate:"\u521B\u5EFA",serversSave:"\u4FDD\u5B58",serversDelete:"\u5220\u9664",serversDeleteTitle:"\u5220\u9664 {id}\uFF1F",serversDeleteBody:"\u8FD9\u4F1A\u4ECE\u5DE5\u4F5C\u533A {workspace} \u4E2D\u79FB\u9664\u8BE5\u6761\u76EE\uFF0C\u8FD0\u884C\u4E2D\u7684\u670D\u52A1\u5668\u4E5F\u4F1A\u968F\u4E4B\u505C\u6B62\u3002",serversDeleteGo:"\u5220\u9664",serversFreePort:"\u91CA\u653E\u7AEF\u53E3",serversFreePortTitle:"\u91CA\u653E\u7AEF\u53E3 {port}\uFF1F",serversFreePortBody:"\u505C\u6B62\u5360\u7528\u8BE5\u7AEF\u53E3\u7684\u8FDB\u7A0B\uFF0C\u9664\u975E\u5B83\u7531\u9762\u677F\u76D1\u7BA1\u3002\u8FDB\u7A0B\u5148\u6536\u5230 SIGTERM\uFF0C\u4E4B\u540E\u4F1A\u88AB\u5F3A\u5236\u505C\u6B62\u3002",serversFreePortGo:"\u91CA\u653E",serversPortFreed:"\u7AEF\u53E3 {port} \u5DF2\u91CA\u653E\u3002",serversPortHeld:"\u7AEF\u53E3 {port} \u4ECD\u88AB\u5360\u7528\u3002",serversPortSkipped:"\u8BE5\u76D1\u542C\u8005\u5C5E\u4E8E\u9762\u677F\u76D1\u7BA1\u7684\u670D\u52A1\u5668\uFF0C\u56E0\u6B64\u672A\u88AB\u52A8\u5B83\u3002",serversPortRefused:"\u7AEF\u53E3\u672A\u80FD\u91CA\u653E\uFF1A{message}",fieldId:"Id",fieldIdHint:"\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001`_` \u548C `-`\uFF1B\u5728\u5DE5\u4F5C\u533A\u5185\u552F\u4E00\u3002",fieldIdInvalid:"id \u4EE5\u5C0F\u5199\u5B57\u6BCD\u6216\u6570\u5B57\u5F00\u5934\uFF0C\u53EA\u80FD\u5305\u542B a-z\u30010-9\u3001_ \u548C -\u3002",fieldLabel:"\u6807\u7B7E",fieldCommand:"\u547D\u4EE4",fieldArgs:"\u53C2\u6570",fieldArgsHint:"\u6BCF\u884C\u4E00\u4E2A\u53C2\u6570\u3002",fieldCwd:"\u5DE5\u4F5C\u76EE\u5F55",fieldPort:"\u7AEF\u53E3",fieldPortHint:"\u7559\u7A7A\u8868\u793A\u8BE5\u6761\u76EE\u6CA1\u6709\u7AEF\u53E3\u3002",fieldPortInvalid:"\u8BF7\u8F93\u5165 1 \u5230 65535 \u4E4B\u95F4\u7684\u7AEF\u53E3\uFF0C\u6216\u7559\u7A7A\u3002",fieldAutostart:"\u968F\u9762\u677F\u542F\u52A8",fieldOnPortConflict:"\u7AEF\u53E3\u51B2\u7A81\u65F6",fieldInherit:"\u7EE7\u627F",fieldRequired:"Id \u548C\u547D\u4EE4\u4E3A\u5FC5\u586B\u3002"};function Zt(e,t){return t===void 0?e:e.replace(/\{(\w+)\}/g,(n,r)=>Object.prototype.hasOwnProperty.call(t,r)?String(t[r]):n)}var Ue=(e,t)=>Zt(Ne[e]??e,t);function We(e){if(e!==void 0)try{let t=e.bind(ve);if(typeof t=="function")return t}catch{}return Ue}function Ve(e,t=Ue){return e===void 0?t:(n,r)=>{let o;try{o=e(n,r)}catch{o=void 0}return o===void 0||o.length===0||o===n?t(n,r):o}}var U=require("react");var te=require("react");var $e="/home-hosted";var je="default";var ze=["block","warn","follow","reclaim","kill"];var se=["status","workspaces_list","servers_list","servers_lifecycle","servers_edit","autostart_manage","ui_manage"],Ge=["servers_lifecycle","servers_edit","autostart_manage","ui_manage"],Qt=3,Bn={version:Qt,autostart:{enabled:!1,mechanism:"auto"},manageDsh:!1,entries:[],agentTools:{enabled:!0,allow:[...se]},panel:{port:null},authNotice:!0,reclaimToken:!0,instancesNotice:!0,uiStyle:"detailed",cli:{prefer:"pinned"}};var en="/api";function Q(e,t,n){return{ok:!1,error:n===void 0?{code:e,message:t}:{code:e,message:t,detail:n}}}function Re(e){return typeof e=="object"&&e!==null}function tn(e){return e instanceof Error?e.message:String(e)}function nn(e){if(!Re(e))return Q("bad-response","The panel returned a non-object response");if(typeof e.v=="number"&&e.v!==1)return Q("version-mismatch",`Response protocol v${e.v} does not match the expected v${1}`);let t=e.result;if(!Re(t))return Q("bad-response","The panel returned no result");if(t.ok===!0)return"value"in t?{ok:!0,value:t.value}:Q("bad-response","A successful response carried no value");if(t.ok===!1){let n=t.error;return Re(n)&&typeof n.message=="string"?Q(typeof n.code=="string"?n.code:"error",n.message,n.detail):Q("error","The panel reported a failure without a message")}return Q("bad-response","The panel returned an unrecognised result")}async function C(e,t,n={}){let r=n.fetch??globalThis.fetch;if(typeof r!="function")return Q("no-fetch","No fetch implementation is available");let o={v:1,endpoint:e,payload:t},a;try{a=await r(`${en}${$e}`,{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify(o)})}catch(s){return Q("network",tn(s))}if(!a.ok){let s=a.statusText.length>0?` ${a.statusText}`:"";return Q("http",`HTTP ${a.status}${s}`)}let i;try{i=await a.json()}catch{return Q("bad-json","The panel returned invalid JSON")}return nn(i)}function Ke(e,t={}){return C("settings.update",{patch:e},t)}var on=5e3;function Ye(e=on){let[t,n]=(0,te.useState)(null),[r,o]=(0,te.useState)(null),[a,i]=(0,te.useState)(!0),s=(0,te.useRef)(!0),u=(0,te.useCallback)(async()=>{let c=await C("status",{});s.current&&(c.ok?(n(c.value),o(null)):o(c.error),i(!1))},[]);return(0,te.useEffect)(()=>{s.current=!0,u();let c=setInterval(()=>{u()},e);return()=>{s.current=!1,clearInterval(c)}},[u,e]),{data:t,error:r,loading:a,refresh:u}}var w=require("react/jsx-runtime");function ne({size:e=14,children:t}){return(0,w.jsx)("svg",{width:e,height:e,viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:t})}function qe(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("rect",{x:"2.2",y:"3",width:"11.6",height:"7.6",rx:"1.6"}),(0,w.jsx)("path",{d:"M6.6 13.4h2.8M8 10.6v2.8"})]})}function Je(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M8 2.4v5.2"}),(0,w.jsx)("path",{d:"M11.6 4.4a5 5 0 1 1-7.2 0"})]})}function Xe(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("rect",{x:"2.2",y:"2.8",width:"11.6",height:"10.4",rx:"1.6"}),(0,w.jsx)("path",{d:"M5.2 6.9l1.8 1.8-1.8 1.8M8.7 10.5h2.2"})]})}function Ze(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M2.4 5.4h11.2M2.4 10.6h11.2"}),(0,w.jsx)("circle",{cx:"6",cy:"5.4",r:"1.6",fill:"currentColor",stroke:"none"}),(0,w.jsx)("circle",{cx:"10.4",cy:"10.6",r:"1.6",fill:"currentColor",stroke:"none"})]})}function be(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M8 2.3l5.4 2.9L8 8.1 2.6 5.2z"}),(0,w.jsx)("path",{d:"M2.6 8.6l5.4 2.9 5.4-2.9"}),(0,w.jsx)("path",{d:"M2.6 11.4l5.4 2.9 5.4-2.9"})]})}function Qe(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M13.4 9.4A5.5 5.5 0 1 1 12.2 4.4"}),(0,w.jsx)("path",{d:"M12.8 1.7v2.9h-2.9"})]})}function et(e){return(0,w.jsx)(ne,{...e,children:(0,w.jsx)("path",{d:"M6.2 3.8L10.4 8l-4.2 4.2"})})}function tt(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M6.6 3.4H3.4v9.2h9.2V9.4"}),(0,w.jsx)("path",{d:"M9.4 3.4h3.2v3.2M12.6 3.4L7.8 8.2"})]})}function ye(e){return(0,w.jsxs)(ne,{...e,children:[(0,w.jsx)("path",{d:"M8 2.6l5.7 10.2H2.3z"}),(0,w.jsx)("path",{d:"M8 6.4v3.1M8 11.5h.01"})]})}function nt(e){return(0,w.jsx)(ne,{...e,children:(0,w.jsx)("path",{d:"M3 8.4l3.3 3.3L13 5"})})}var q="\u2014";function I(e){if(e==null)return q;let t=String(e);return t.length>0?t:q}function ot(e){return e.length>0?e.join(", "):q}function Ie(e){return Ge.includes(e)}var He={status:"agentToolStatus",workspaces_list:"agentToolWorkspacesList",servers_list:"agentToolServersList",servers_lifecycle:"agentToolServersLifecycle",servers_edit:"agentToolServersEdit",autostart_manage:"agentToolAutostartManage",ui_manage:"agentToolUiManage"},rt={status:"agentToolDescStatus",workspaces_list:"agentToolDescWorkspacesList",servers_list:"agentToolDescServersList",servers_lifecycle:"agentToolDescServersLifecycle",servers_edit:"agentToolDescServersEdit",autostart_manage:"agentToolDescAutostartManage",ui_manage:"agentToolDescUiManage"},at={api:"writeViaApi",file:"writeViaFile",none:"writeViaNone"},it={enrolled:"tokenEnrolled",present:"tokenPresent",absent:"tokenAbsent",stale:"tokenStale",unknown:"tokenUnknown"},we={"not-installed":"bootStateNotInstalled","installed-disabled":"bootStateInstalledDisabled","enabled-running":"bootStateEnabledRunning","enabled-failing":"bootStateEnabledFailing",unsupported:"bootStateUnsupported"},st={config:"panelCliConfig",dependency:"panelCliDependency",path:"panelCliPathSource",none:"panelCliMissing"};function xe(e,t=52){if(e.length<=t)return e;let n=e.includes("\\")?"\\":"/",r=e.split(/[\\/]/).filter(s=>s.length>0);if(r.length<4)return e;let o=/^[A-Za-z]:$/.test(r[0]??"")?3:2;if(r.length<=o)return e;let i=`${/^[\\/]/.test(e)?n:""}${r.slice(0,o).join(n)}${n}\u2026${n}${r.slice(-2).join(n)}`;return i.length<e.length?i:e}function lt(e){let t=n=>e.source===n&&e.path!==null?{source:n,path:e.path,version:e.version}:null;return{dependency:e.dependency??t("dependency"),global:e.global??t("path")}}function dt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function rn(e,t){if(Object.is(e,t))return!0;try{return JSON.stringify(e)===JSON.stringify(t)}catch{return!1}}function ct(e,t){let n={};for(let r of Object.keys(t)){let o=e[r],a=t[r];if(dt(o)&&dt(a)){let i=ct(o,a);Object.keys(i).length>0&&(n[r]=i)}else rn(o,a)||(n[r]=a)}return n}function pt(e,t){return ct(e,t)}function ht(e,t,n){let r=new Set(e);return n?r.add(t):r.delete(t),se.filter(o=>r.has(o))}var gt=require("react");async function ut(e){try{if(typeof navigator<"u"&&navigator.clipboard!==void 0)return await navigator.clipboard.writeText(e),!0}catch{}return!1}var p=require("react/jsx-runtime");function an(...e){return e.filter(t=>typeof t=="string"&&t.length>0).join(" ")}function J({icon:e,title:t,action:n,children:r}){return(0,p.jsxs)("section",{className:"hh-section",children:[(0,p.jsxs)("header",{className:"hh-section-head",children:[e===void 0?null:(0,p.jsx)("span",{className:"hh-section-icon",children:e}),(0,p.jsx)("h3",{className:"hh-section-title",children:t}),(0,p.jsx)("span",{className:"hh-section-rule","aria-hidden":"true"}),n===void 0?null:(0,p.jsx)("span",{className:"hh-section-action",children:n})]}),(0,p.jsx)("div",{className:"hh-section-body",children:r})]})}function N({label:e,children:t}){return(0,p.jsxs)("div",{className:"hh-spec",children:[(0,p.jsx)("span",{className:"hh-spec-label",children:e}),(0,p.jsx)("span",{className:"hh-spec-value",children:t})]})}function ee({children:e}){return(0,p.jsx)("code",{className:"hh-code",children:e})}function m({children:e}){return typeof e=="string"&&e.length===0?null:(0,p.jsx)("p",{className:"hh-hint",children:e})}function D({tone:e,children:t}){return(0,p.jsx)("span",{className:"hh-chip","data-tone":e??"idle",children:t})}function re({href:e,children:t}){return(0,p.jsxs)("a",{className:"hh-link",href:e,target:"_blank",rel:"noreferrer noopener",children:[t??e,(0,p.jsx)("span",{className:"hh-link-icon","aria-hidden":"true",children:(0,p.jsx)(tt,{size:11})})]})}function oe({label:e,open:t=!1,children:n}){return(0,p.jsxs)("details",{className:"hh-details",open:t||void 0,children:[(0,p.jsxs)("summary",{className:"hh-summary",children:[(0,p.jsx)("span",{className:"hh-chevron","aria-hidden":"true",children:(0,p.jsx)(et,{size:12})}),e]}),(0,p.jsx)("div",{className:"hh-details-body",children:n})]})}function z({tone:e="bad",icon:t=!0,title:n,children:r}){return(0,p.jsxs)("div",{className:"hh-note","data-tone":e,role:e==="bad"?"alert":"note",children:[t?(0,p.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,p.jsx)(ye,{size:13})}):null,(0,p.jsxs)("div",{className:"hh-note-body",children:[n===void 0?null:(0,p.jsx)("span",{className:"hh-note-title",children:n}),typeof r=="string"?(0,p.jsx)("p",{children:r}):r]})]})}function ke({title:e,detail:t}){return(0,p.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,p.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,p.jsx)(ye,{size:13})}),(0,p.jsxs)("div",{className:"hh-note-body",children:[(0,p.jsx)("strong",{children:e}),t.length>0?(0,p.jsx)("p",{children:t}):null]})]})}function ge({error:e,title:t}){return e===null?null:(0,p.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,p.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,p.jsx)(ye,{size:13})}),(0,p.jsxs)("div",{className:"hh-note-body",children:[(0,p.jsx)("strong",{children:t}),(0,p.jsxs)("p",{children:[(0,p.jsx)("code",{children:e.code})," \u2014 ",e.message]})]})]})}function sn(){return(0,p.jsx)("span",{className:"hh-spinner","aria-hidden":"true"})}function y({children:e,onClick:t,disabled:n,busy:r,variant:o="default",icon:a,title:i}){let s=n===!0||r===!0;return(0,p.jsxs)("button",{type:"button",className:an("hh-btn",o!=="default"&&`hh-btn-${o}`),onClick:t,disabled:s,title:i,children:[r===!0?(0,p.jsx)(sn,{}):a,e]})}function pe({label:e,checked:t,disabled:n,onChange:r}){return(0,p.jsxs)("button",{type:"button",role:"switch",className:"hh-switch","aria-checked":t,disabled:n,onClick:()=>r(!t),children:[(0,p.jsx)("span",{className:"hh-switch-track","aria-hidden":"true",children:(0,p.jsx)("span",{className:"hh-switch-knob"})}),(0,p.jsx)("span",{className:"hh-check-label",children:e})]})}function mt({label:e,checked:t,disabled:n,onChange:r}){return(0,p.jsxs)("label",{className:"hh-check",children:[(0,p.jsx)("input",{type:"checkbox",checked:t,disabled:n,onChange:o=>r(o.target.checked)}),(0,p.jsx)("span",{className:"hh-check-label",children:e})]})}function ce({value:e,options:t,disabled:n,label:r,onChange:o}){return(0,p.jsx)("select",{className:"hh-select",value:e,disabled:n,"aria-label":r,onChange:a=>o(a.target.value),children:t.map(a=>(0,p.jsx)("option",{value:a.value,children:a.label},a.value))})}function me({label:e,meta:t,path:n,hint:r,checked:o,disabled:a,onChange:i}){return(0,p.jsxs)("label",{className:"hh-choice-option","data-disabled":a===!0,children:[(0,p.jsx)("input",{type:"radio",checked:o,disabled:a,onChange:()=>i()}),(0,p.jsxs)("span",{className:"hh-choice-label",children:[(0,p.jsx)("span",{children:e}),r]}),t===void 0?null:(0,p.jsx)("span",{className:"hh-choice-meta",children:t}),n===void 0?null:(0,p.jsx)("span",{className:"hh-choice-path",title:n,children:xe(n)})]})}function Se({children:e}){return(0,p.jsxs)(D,{tone:"accent",children:[(0,p.jsx)(nt,{size:10}),e]})}function fe({text:e,copyLabel:t,copiedLabel:n}){let[r,o]=(0,gt.useState)(!1);return(0,p.jsxs)("div",{className:"hh-code-box",children:[(0,p.jsx)("textarea",{className:"hh-code-text",readOnly:!0,value:e,rows:Math.min(e.split(`
|
|
4
4
|
`).length,4)}),(0,p.jsx)("div",{className:"hh-btn-row",children:(0,p.jsx)(y,{variant:"ghost",onClick:()=>{ut(e).then(o)},children:r?n:t})})]})}var P=require("react/jsx-runtime");function ft({t:e,status:t,updateSettings:n,busy:r,uiStyle:o}){let a=t.settings.agentTools,i=a.allow??[],s=se.filter(c=>i.includes(c)).length,u=(c,g)=>{n(T=>({...T,agentTools:{...T.agentTools,allow:ht(T.agentTools.allow??[],c,g)}}))};return(0,P.jsxs)(J,{icon:(0,P.jsx)(Ze,{}),title:e("agentTitle"),action:(0,P.jsx)(D,{children:e("agentCount",{enabled:s,total:se.length})}),children:[(0,P.jsx)(pe,{label:e("agentMaster"),checked:a.enabled,onChange:c=>n(g=>({...g,agentTools:{...g.agentTools,enabled:c}}))}),(0,P.jsxs)("div",{className:"hh-field-block",children:[(0,P.jsx)(pe,{label:e("reclaimAutoLabel"),checked:t.settings.reclaimToken!==!1,disabled:r==="settings",onChange:c=>n(g=>({...g,reclaimToken:c}))}),(0,P.jsx)(m,{children:e("reclaimAutoHint")})]}),(0,P.jsxs)("div",{className:"hh-field-block",children:[(0,P.jsx)(pe,{label:e("instancesNoticeLabel"),checked:t.settings.instancesNotice!==!1,disabled:r==="settings",onChange:c=>n(g=>({...g,instancesNotice:c}))}),(0,P.jsx)(m,{children:e("instancesNoticeHint")})]}),(0,P.jsx)(m,{children:e("agentApproval")}),o==="detailed"?(0,P.jsx)("div",{className:"hh-tool-cards",children:se.map(c=>(0,P.jsxs)("label",{className:"hh-tool-card",children:[(0,P.jsx)("input",{type:"checkbox",checked:i.includes(c),disabled:!a.enabled,onChange:g=>u(c,g.target.checked)}),(0,P.jsxs)("span",{className:"hh-tool-card-body",children:[(0,P.jsxs)("span",{className:"hh-tool-card-head",children:[(0,P.jsx)("span",{className:"hh-tool-card-name",children:e(He[c])}),Ie(c)?(0,P.jsx)(D,{tone:"warn",children:e("agentApprovalBadge")}):null]}),(0,P.jsx)("span",{className:"hh-tool-card-desc",children:e(rt[c])})]})]},c))}):(0,P.jsx)("div",{className:"hh-tools",children:se.map(c=>(0,P.jsx)(mt,{label:(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)("span",{className:"hh-check-text",children:e(He[c])}),Ie(c)?(0,P.jsx)(D,{tone:"warn",children:e("agentApprovalBadge")}):null]}),checked:i.includes(c),disabled:!a.enabled,onChange:g=>u(c,g)},c))})]})}var St=require("react");function vt(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function bt(e){if(typeof e!="object"||e===null)return null;let t=e.result;if(typeof t!="object"||t===null)return null;let{ok:n,detail:r,commands:o}=t;return n!==!1?null:{detail:typeof r=="string"?r:"",commands:vt(o)}}function yt(e){return e===void 0?null:{ok:e.ok===!0,action:e.action==="uninstall"?"uninstall":"install",detail:typeof e.detail=="string"?e.detail:"",commands:vt(e.commands)}}var ln=["enabled-running","enabled-failing","installed-disabled"];function wt(e,t){let n=e.filter(a=>a.available).map(a=>a.mechanism),r=n.filter(a=>a!=="unsupported"),o=["auto",...r.length>0?r:n];return o.includes(t)||o.push(t),o}function xt(e,t){return e!==null&&e!==t}function dn(e,t){return e===null||e.ok?!1:e.action==="install"?ln.includes(t):t==="not-installed"}function kt(e,t,n,r){return e!==null&&e.state===n&&e.mechanism===r?e:dn(t,n)?null:t}var k=require("react/jsx-runtime");function Tt({t:e,status:t,run:n,updateSettings:r,busy:o,uiStyle:a}){let i=t.boot,s=t.settings.autostart,u=i.candidates??[],c=i.commands??[],[g,T]=(0,St.useState)(null),M=o==="boot.install"||o==="boot.uninstall",R=wt(u,s.mechanism).map(H=>({value:H,label:H==="auto"?e("bootMechanismAuto"):H})),A=xt(i.mechanism,s.mechanism),W=i.mechanism!==null,V=t.panel.reachable&&!A&&!W,x=t.panel.reachable&&A,B=H=>e(H==="install"?"bootActionInstall":"bootActionUninstall"),Y=async H=>{let $=await n(`boot.${H}`,async()=>H==="install"?C("boot.install",s.mechanism==="auto"?{}:{mechanism:s.mechanism}):C("boot.uninstall",{}));if(!$.ok){T(null);return}let G=bt($.value);T(G===null?null:{ok:!1,action:H,detail:G.detail,commands:G.commands,state:i.state,mechanism:i.mechanism})},Z=yt(s.lastAttempt),L=kt(g,Z,i.state,i.mechanism);return(0,k.jsxs)(J,{icon:(0,k.jsx)(Je,{}),title:e("bootTitle"),action:(0,k.jsx)(ce,{value:s.mechanism,options:R,label:e("bootMechanism"),disabled:o==="settings"||M,onChange:H=>r($=>({...$,autostart:{...$.autostart,mechanism:H}}))}),children:[V?(0,k.jsx)(m,{children:e("bootHandover")}):null,x?(0,k.jsx)(z,{tone:"warn",children:e("bootSwitchRetires")}):null,(0,k.jsxs)("div",{className:"hh-btn-row",children:[(0,k.jsx)(y,{variant:W?"default":"primary",disabled:s.mechanism==="unsupported",busy:o==="boot.install",onClick:()=>{Y("install")},children:e(A?"bootSwitchMode":"bootEnabled")}),(0,k.jsx)(y,{disabled:!W,busy:o==="boot.uninstall",onClick:()=>{Y("uninstall")},children:e("bootUninstall")}),(0,k.jsx)(y,{variant:"ghost",busy:o==="boot.verify",onClick:()=>{n("boot.verify",()=>C("boot.verify",{}))},children:e("bootRecheck")})]}),s.enabled&&i.state==="not-installed"?(0,k.jsx)(z,{tone:"warn",children:e("bootRequestedNotInstalled")}):null,L!==null&&!L.ok?(0,k.jsxs)("div",{className:"hh-section-body",children:[(0,k.jsx)(ke,{title:e("bootAttemptFailed",{action:B(L.action)}),detail:L.detail.length>0?L.detail:e("bootAttemptNoDetail")}),L.commands.length>0?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(m,{children:e("bootAttemptCommands")}),(0,k.jsx)(fe,{text:L.commands.join(`
|
|
5
5
|
`),copyLabel:e("copy"),copiedLabel:e("copied")})]}):null]}):null,L!==null&&L.ok?(0,k.jsx)(m,{children:e("bootAttemptSucceeded",{action:B(L.action),detail:L.detail})}):null,c.length>0?(0,k.jsxs)(oe,{label:e("bootCommandsLabel"),open:a==="detailed",children:[(0,k.jsx)(m,{children:e("bootCommandsExplain")}),(0,k.jsx)(fe,{text:c.join(`
|
|
6
6
|
`),copyLabel:e("copy"),copiedLabel:e("copied")})]}):null,(0,k.jsxs)(oe,{label:e("details"),open:a==="detailed",children:[(0,k.jsx)(N,{label:e("bootState"),children:e(we[i.state]??"bootStateUnsupported")}),(0,k.jsx)(N,{label:e("bootBootCapable"),children:i.bootCapable?e("yes"):e("no")}),(0,k.jsx)(N,{label:e("bootPrivileged"),children:i.privileged?e("yes"):e("no")}),(0,k.jsx)(N,{label:e("bootUnitPath"),children:(0,k.jsx)(ee,{children:I(i.unitPath)})}),i.detail.length>0?(0,k.jsx)(m,{children:i.detail}):null]})]})}var O=require("react/jsx-runtime");function cn(e){return e.defaultEntryId??"dsh"}function Ct({t:e,status:t,run:n,busy:r}){let o=t.entries??[],a=t.settings.manageDsh===!0,i=t.boot.platform==="win32",s=cn(t),u=c=>{if(c){let g={id:s,autostart:!0};n("entries.apply",()=>C("entries.apply",{intents:[g]}))}else n("entries.remove",()=>C("entries.remove",{id:s}))};return(0,O.jsxs)(J,{icon:(0,O.jsx)(Xe,{}),title:e("entriesTitle"),children:[(0,O.jsx)(pe,{label:e("entriesManage",{id:s}),checked:a,disabled:r!==null,onChange:u}),(0,O.jsx)(m,{children:e("entriesManageNote",{id:s})}),i?(0,O.jsx)(z,{tone:"warn",children:e("entriesManageWinWarning",{id:s})}):null,o.length===0?(0,O.jsx)(m,{children:e("entriesEmpty",{id:s})}):(0,O.jsx)("div",{className:"hh-list",children:o.map(c=>{let g=c.live;return(0,O.jsxs)("div",{className:"hh-item",children:[(0,O.jsxs)("span",{className:"hh-item-main",children:[(0,O.jsx)("span",{className:"hh-item-name",children:c.intent.id}),(0,O.jsx)(D,{tone:c.exists?"ok":"bad",children:c.exists?e("entriesExists"):e("entriesMissing")}),(0,O.jsx)(D,{children:c.managed?e("entriesManaged"):e("entriesUnmanaged")}),c.drift.length>0?(0,O.jsx)(D,{tone:"warn",children:`${e("entriesDrift")} ${ot(c.drift)}`}):null]}),(0,O.jsx)("span",{className:"hh-item-spacer"}),(0,O.jsx)("span",{className:"hh-item-meta",children:g===null?e("entriesNotRunning"):`${I(g.status)}${g.pid===null?"":` \xB7 pid ${g.pid}`}`})]},c.intent.id)})})]})}var ae=require("react");var l=require("react/jsx-runtime"),pn={absent:"panelTokenWarnAbsent",present:"panelTokenWarnPresent",stale:"panelTokenWarnStale"};function hn(e){if(e.token!=="enrolled")return e.token!=="unknown"?pn[e.token]:e.url===null?void 0:"panelTokenWarnUnreachable"}function un(e,t){if(!e.ok)return t("panelTokenRegenerateFailed",{message:e.error.message});let n=e.value?.panel;return n!==void 0&&n.detail.length>0?n.detail:t("panelTokenRegenerated")}function gn(e,t){return e.ok?e.value?.detail||t("panelStopped"):e.error.code==="client"?t("panelStopping"):t("panelStopFailed",{message:e.error.message})}function mn({value:e,label:t,hint:n,invalidLabel:r,placeholder:o,disabled:a,onChange:i}){let[s,u]=(0,ae.useState)(e===null?"":String(e));(0,ae.useEffect)(()=>{u(e===null?"":String(e))},[e]);let c=s.trim()===""?null:Number(s),g=c!==null&&(!Number.isInteger(c)||c<1||c>65535),T=()=>{if(g){u(e===null?"":String(e));return}c!==e&&i(c)};return(0,l.jsxs)("div",{className:"hh-field-block",children:[(0,l.jsxs)("div",{className:"hh-field",children:[(0,l.jsx)("label",{className:"hh-field-label",htmlFor:"hh-panel-port",children:t}),(0,l.jsx)("input",{id:"hh-panel-port",className:"hh-input",type:"number",value:s,placeholder:o,disabled:a,onChange:M=>u(M.target.value),onBlur:T,onKeyDown:M=>{M.key==="Enter"&&T()}})]}),(0,l.jsx)(m,{children:g?r:n})]})}function Pt({t:e,status:t,run:n,updateSettings:r,busy:o,uiStyle:a}){let i=t.panel,s=t.cli,u=t.instances??[],c=s?.prefer??t.settings.cli?.prefer??"pinned",[g,T]=(0,ae.useState)(!1),[M,F]=(0,ae.useState)(null),[R,A]=(0,ae.useState)(null),[W,V]=(0,ae.useState)(!1),[x,B]=(0,ae.useState)(null),Y=hn(i),Z=s?.version??null,L=Z!==null&&i.version!==null,H=i.reachable&&L&&Z!==i.version,{dependency:$,global:G}=s===void 0?{dependency:null,global:null}:lt(s),ue=s===void 0?[]:[`pnpm add -g home-hosted@${s.expectedRange}`,`npm install -g home-hosted@${s.expectedRange}`],K=b=>{r(j=>({...j,cli:{...j.cli,prefer:b}}))},h=async()=>{let b=await n("cli.installGlobal",()=>C("cli.installGlobal",{}));if(!b.ok)return;let j=b.value;F(typeof j?.output=="string"?j.output:null)},E=async()=>{A(un(await n("panel.reclaimToken",()=>C("panel.reclaimToken",{})),e))},v=async()=>{V(!1),B(e("panelStopping")),B(gn(await n("panel.stop",()=>C("panel.stop",{})),e))};return(0,l.jsxs)(J,{icon:(0,l.jsx)(qe,{}),title:e("panelTitle"),children:[Y===void 0?null:(0,l.jsxs)(z,{tone:"warn",title:e("panelTokenWarningTitle"),children:[(0,l.jsx)("p",{children:e(Y)}),i.reachable||i.token==="unknown"?null:(0,l.jsx)("p",{children:e("panelTokenWarnPanelDown")}),(0,l.jsx)("div",{className:"hh-note-actions",children:(0,l.jsx)(y,{variant:"primary",busy:o==="panel.reclaimToken",onClick:()=>{E()},children:e("panelTokenRegenerate")})})]}),R===null?null:(0,l.jsx)(m,{children:R}),s===void 0?null:(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("div",{className:"hh-choice",role:"radiogroup","aria-label":e("panelCopy"),children:[(0,l.jsx)(me,{label:e("optionsPreferPinned"),hint:(0,l.jsx)(Se,{children:e("optionsRecommended")}),meta:$===null?void 0:I($.version),path:$?.path??void 0,checked:c==="pinned",disabled:$===null||o==="settings",onChange:()=>K("pinned")}),(0,l.jsx)(me,{label:e("optionsPreferGlobal"),meta:G===null?void 0:I(G.version),path:G?.path??void 0,checked:c==="global",disabled:G===null||o==="settings",onChange:()=>K("global")})]}),(0,l.jsx)(m,{children:e("panelCopyHint")}),s.source==="config"?(0,l.jsx)(m,{children:e("optionsConfigOverride")}):null,s.source==="path"&&c!=="global"?(0,l.jsx)(m,{children:e("panelCliNotPinned",{range:s.expectedRange})}):null,s.supported?null:(0,l.jsx)(z,{tone:"warn",children:e("panelCliUnsupported")}),s.launcherPath!=null&&s.launcherVersion==null?(0,l.jsx)(z,{tone:"warn",children:e("panelCliLauncherFailed")}):null]}),(0,l.jsx)(mn,{value:t.settings.panel?.port??null,label:e("panelPort"),hint:i.reachable?e("panelPortHint"):e("panelPortFree"),invalidLabel:e("panelPortInvalid"),placeholder:i.configPort==null?void 0:String(i.configPort),disabled:i.reachable||o!==null,onChange:b=>r(j=>({...j,panel:{...j.panel,port:b}}))}),t.panelRootSource!=="legacy"?null:(0,l.jsx)(m,{children:e("panelRootLegacy")}),u.length<=1?null:(0,l.jsxs)(oe,{label:e("panelInstances",{count:u.length}),open:a==="detailed",children:[u.map(b=>(0,l.jsxs)(N,{label:b.managed?e("panelInstanceManaged"):e("panelInstanceOther"),children:[(0,l.jsx)(ee,{children:b.home}),b.url===null?null:(0,l.jsxs)(l.Fragment,{children:[" \xB7 ",(0,l.jsx)(re,{href:b.url,children:b.url})]}),` \xB7 ${b.running?e("stateAnswering"):e("stateNotAnswering")}`,b.version===null?null:` \xB7 ${b.version}`,b.hosting?` \xB7 ${e("panelInstanceHosts")}`:null]},b.home)),(0,l.jsx)(m,{children:e("panelInstancesHint")})]}),H?(0,l.jsx)(m,{children:e("panelOutdated")}):null,(0,l.jsxs)("div",{className:"hh-btn-row",children:[i.reachable?null:(0,l.jsx)(y,{variant:"primary",busy:o==="panel.start",onClick:()=>{n("panel.start",()=>C("panel.start",{}))},children:e("panelStart")}),i.reachable?(0,l.jsx)(y,{variant:"danger",disabled:o!==null,onClick:()=>V(!0),children:e("panelStop")}):null,H&&!g?(0,l.jsx)(y,{variant:"primary",onClick:()=>T(!0),children:e("panelReplace",{copy:e(c==="global"?"panelCopyGlobal":"panelCopyPinned")})}):null]}),x===null?null:(0,l.jsx)(m,{children:x}),W?(0,l.jsx)("div",{className:"hh-note",role:"alertdialog","aria-label":e("panelStopTitle"),children:(0,l.jsxs)("div",{className:"hh-note-body",children:[(0,l.jsx)("strong",{children:e("panelStopTitle")}),(0,l.jsx)("p",{children:e("panelStopBody")}),(0,l.jsxs)("div",{className:"hh-note-actions",children:[(0,l.jsx)(y,{onClick:()=>V(!1),children:e("confirmCancel")}),(0,l.jsx)(y,{variant:"danger",busy:o==="panel.stop",onClick:()=>{v()},children:e("confirmStop")})]})]})}):null,H&&g?(0,l.jsx)("div",{className:"hh-note",role:"alertdialog","aria-label":e("panelTakeoverTitle"),children:(0,l.jsxs)("div",{className:"hh-note-body",children:[(0,l.jsx)("strong",{children:e("panelTakeoverTitle")}),(0,l.jsx)("p",{children:e("panelTakeoverBody",{id:t.defaultEntryId??"dsh"})}),(0,l.jsxs)("div",{className:"hh-note-actions",children:[(0,l.jsx)(y,{onClick:()=>T(!1),children:e("confirmCancel")}),(0,l.jsx)(y,{variant:"danger",busy:o==="panel.takeover",onClick:()=>{T(!1),n("panel.takeover",()=>C("panel.takeover",{}))},children:e("confirmReplace")})]})]})}):null,s!==void 0&&G===null?(0,l.jsxs)(oe,{label:e("optionsInstallLabel"),open:a==="detailed",children:[(0,l.jsx)(m,{children:e("optionsInstallHint")}),(0,l.jsx)(fe,{text:ue.join(`
|