dsh-home-hosted 0.2.2 → 0.3.1
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 +105 -17
- package/docs/DESIGN.md +16 -0
- package/lib/client.js +6 -6
- package/lib/index.js +687 -185
- package/lib/index.js.map +4 -4
- package/lib/types/home-hosted/dsh-entry.d.ts +65 -2
- package/lib/types/home-hosted/launcher.d.ts +48 -0
- package/lib/types/home-hosted/panel.d.ts +12 -0
- package/lib/types/home-hosted/token.d.ts +21 -0
- package/lib/types/service.d.ts +29 -0
- package/lib/types/shared/contracts.d.ts +21 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# 📌 dsh-home-hosted
|
|
4
4
|
|
|
5
|
-
**Your
|
|
5
|
+
**Your whole home stack, up after every reboot — your `dsh` web server included.**
|
|
6
|
+
|
|
7
|
+
A [DeepSeek Harness](https://github.com/deepseek-ai/dsh) plugin for
|
|
8
|
+
[home-hosted](https://github.com/NamesMT/home-hosted), the panel that supervises your services.
|
|
9
|
+
Declare the servers once; this page manages the panel, the boot entry and the entries.
|
|
10
|
+
<sub>Nothing is installed or started until you say so.</sub>
|
|
6
11
|
|
|
7
12
|
[](https://www.npmjs.com/package/dsh-home-hosted)
|
|
8
13
|
[](https://github.com/NamesMT/dsh-home-hosted/actions/workflows/ci.yml)
|
|
@@ -10,27 +15,72 @@
|
|
|
10
15
|
[](https://nodejs.org)
|
|
11
16
|
[](https://github.com/deepseek-ai/dsh)
|
|
12
17
|
|
|
18
|
+
[🚀 Quick start](#-quick-start) · [🎛️ What the plugin does](#-what-the-plugin-does) · [🤖 Agent tools](#-agent-tools) · [🧩 Depth](#-depth)
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div align="center">
|
|
23
|
+
|
|
13
24
|

|
|
14
25
|
|
|
15
|
-
|
|
26
|
+
<sub>The Detailed style, then the same sections in Compact — both switchable from the page header.</sub>
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🚀 Quick start
|
|
16
33
|
|
|
17
34
|
```sh
|
|
18
35
|
dsh plugin --profile web add dsh-home-hosted
|
|
19
36
|
```
|
|
20
37
|
|
|
21
|
-
|
|
38
|
+
Open **Settings → Home Hosted**, turn on **Manage dsh**, and enable autostart.
|
|
39
|
+
<sub>Reboot once; `dsh` comes back without you touching anything.</sub>
|
|
40
|
+
|
|
41
|
+
## 🤔 Why
|
|
42
|
+
|
|
43
|
+
A panel restart shouldn't kill a prompt mid-flight, and a reboot shouldn't cost you an SSH session.
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
reboot
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
OS boot entry ──▶ home-hosted panel ──▶ ┌─────────────┐
|
|
50
|
+
systemd · │ │ dsh web ✓ │
|
|
51
|
+
launchd · │ └─────────────┘
|
|
52
|
+
XDG · Run key │
|
|
53
|
+
├────────▶ ┌─────────────┐
|
|
54
|
+
│ │ docker │
|
|
55
|
+
│ │ compose │
|
|
56
|
+
│ └─────────────┘
|
|
57
|
+
│
|
|
58
|
+
└────────▶ ┌─────────────┐
|
|
59
|
+
│ postgres │
|
|
60
|
+
│ :5432 │
|
|
61
|
+
└─────────────┘
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**`dsh` is one entry in the panel, not the whole product.** The panel is the supervisor: it starts
|
|
65
|
+
each entry, watches it, restarts what dies and reclaims its port. Add your compose stack, your
|
|
66
|
+
database, your bot — manage them from the page, or hand the entry ids to an agent.
|
|
67
|
+
|
|
68
|
+
A plugin cannot run at boot, so this one writes the OS entry while dsh runs and the OS takes over.
|
|
69
|
+
One managed entry (`dsh`) is kept alive under home-hosted's nanny, so a panel restart leaves it
|
|
70
|
+
running.
|
|
71
|
+
|
|
72
|
+
## 🎛️ What the plugin does
|
|
22
73
|
|
|
23
74
|
| | |
|
|
24
75
|
|---|---|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
| 🛡️ **Survives a panel restart** | The managed entry runs under home-hosted's nanny, so a panel restart leaves it running. |
|
|
76
|
+
| 🚀 **Boot autostart** | Installs, verifies and removes the OS entry. Opt in per machine. |
|
|
77
|
+
| 🛡️ **Survives a panel restart** | The managed entry runs under home-hosted's nanny, so restarting the panel leaves it running. |
|
|
28
78
|
| 📦 **Ships its own panel** | The pinned `home-hosted` is a dependency, so boot runs the version this plugin is tested against. |
|
|
29
79
|
| 🖥️ **Server control** | Add, edit, start, stop and restart entries — written through the panel's API, so nothing restarts behind your back. |
|
|
30
|
-
| 🧭 **
|
|
31
|
-
| 🤖 **Agent tools** | On by default
|
|
80
|
+
| 🧭 **Token warnings that mean something** | A missing or refused API token is called out on the page, with one click to mint a working one. |
|
|
81
|
+
| 🤖 **Agent tools** | On by default, session permissions still gate every write. |
|
|
32
82
|
|
|
33
|
-
## Agent tools
|
|
83
|
+
## 🤖 Agent tools
|
|
34
84
|
|
|
35
85
|
| Tool | Does |
|
|
36
86
|
|---|---|
|
|
@@ -42,6 +92,9 @@ Then open **Settings → Home Hosted** and turn on **Manage dsh** — with the p
|
|
|
42
92
|
| `home_hosted_ui_manage` | `status` · `update` · `revert` · `switch` the panel's own UI |
|
|
43
93
|
|
|
44
94
|
A tool that changes something asks for approval **only** when the session is not already Full access.
|
|
95
|
+
<sub>A refused token is re-enrolled on the spot and the tool retries — see **Auto reclaim** below.</sub>
|
|
96
|
+
|
|
97
|
+
## 🧩 Depth
|
|
45
98
|
|
|
46
99
|
<details>
|
|
47
100
|
<summary><b>Boot autostart, per platform</b></summary>
|
|
@@ -52,26 +105,55 @@ A tool that changes something asks for approval **only** when the session is not
|
|
|
52
105
|
| macOS | `launchd-agent`, `launchd-daemon` | login, or boot with the daemon (one-time `sudo`) |
|
|
53
106
|
| Windows | Run key, Task Scheduler | login |
|
|
54
107
|
|
|
55
|
-
|
|
108
|
+
When the process cannot elevate, the page prints the exact commands instead — including the
|
|
109
|
+
`launchd-daemon` that starts a Mac **before** login.
|
|
56
110
|
|
|
57
111
|
</details>
|
|
58
112
|
|
|
59
113
|
<details>
|
|
60
114
|
<summary><b>Which home-hosted runs</b></summary>
|
|
61
115
|
|
|
62
|
-
The pinned dependency by default
|
|
116
|
+
The pinned dependency by default; the page can switch to a global install, or install the pinned
|
|
117
|
+
range globally for you. Boot entries run a small stable launcher the plugin writes, so a
|
|
118
|
+
`node_modules` path that moves never breaks boot.
|
|
119
|
+
|
|
120
|
+
</details>
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary><b>dsh from a local clone</b></summary>
|
|
124
|
+
|
|
125
|
+
A `dsh` you cloned and built yourself is supported: the managed entry starts a stable launcher that
|
|
126
|
+
re-finds your build at boot, so a rebuild, a moved checkout or a fresh profile does not strand it.
|
|
127
|
+
<sub>Falls back to whatever `dsh` is on PATH, and fails with the reason when it finds neither.</sub>
|
|
63
128
|
|
|
64
129
|
</details>
|
|
65
130
|
|
|
66
131
|
<details>
|
|
67
132
|
<summary><b>Managed entry and port policy</b></summary>
|
|
68
133
|
|
|
69
|
-
One entry (`dsh`)
|
|
134
|
+
One entry (`dsh`), one toggle: the panel keeps it alive, restarts it and reclaims its port. A
|
|
135
|
+
detached restart is recognised on macOS and Linux (`follow`); Windows cannot prove identity through
|
|
136
|
+
a `.cmd` shim, so it uses `onPortConflict: kill` — needing home-hosted 0.6.0+, and the plugin
|
|
137
|
+
refuses that write against an older panel rather than producing a config it cannot parse.
|
|
70
138
|
|
|
71
139
|
</details>
|
|
72
140
|
|
|
73
141
|
<details>
|
|
74
|
-
<summary><b>
|
|
142
|
+
<summary><b>API tokens and Auto reclaim</b></summary>
|
|
143
|
+
|
|
144
|
+
The plugin needs its own home-hosted API token to read and write the panel. home-hosted keeps only
|
|
145
|
+
the token's hash, so a token it did not mint can never be recovered — `<stateDir>/panel-token` is
|
|
146
|
+
`0600`, never rendered or logged, and **Regenerate** clears the old hash and enrols a new one.
|
|
147
|
+
|
|
148
|
+
A token that stops working (someone ran `home-hosted set-token`, or cleared it) shows on the page as
|
|
149
|
+
a warning with that button. **Auto reclaim**, on by default, does the same thing automatically when a
|
|
150
|
+
panel call is refused: the tool re-enrols and retries once instead of failing. Turn it off to be
|
|
151
|
+
asked instead of having a working token silently replaced.
|
|
152
|
+
|
|
153
|
+
</details>
|
|
154
|
+
|
|
155
|
+
<details>
|
|
156
|
+
<summary><b>Operator config</b></summary>
|
|
75
157
|
|
|
76
158
|
The Cordis row config is for operator overrides only:
|
|
77
159
|
|
|
@@ -84,7 +166,7 @@ The Cordis row config is for operator overrides only:
|
|
|
84
166
|
defaultEntryId: dsh
|
|
85
167
|
```
|
|
86
168
|
|
|
87
|
-
Everything a person toggles lives in `<stateDir>/settings.json`.
|
|
169
|
+
Everything a person toggles lives in `<stateDir>/settings.json`.
|
|
88
170
|
|
|
89
171
|
</details>
|
|
90
172
|
|
|
@@ -96,8 +178,14 @@ pnpm install
|
|
|
96
178
|
pnpm typecheck && pnpm test && pnpm build
|
|
97
179
|
```
|
|
98
180
|
|
|
99
|
-
Node 24+, pnpm
|
|
181
|
+
Node 24+, pnpm. The same commands CI runs.
|
|
100
182
|
|
|
101
183
|
</details>
|
|
102
184
|
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
<div align="center">
|
|
188
|
+
|
|
103
189
|
MIT · [npm](https://www.npmjs.com/package/dsh-home-hosted) · [releases](https://github.com/NamesMT/dsh-home-hosted/releases) · [issues](https://github.com/NamesMT/dsh-home-hosted/issues) · built on [home-hosted](https://github.com/NamesMT/home-hosted)
|
|
190
|
+
|
|
191
|
+
</div>
|
package/docs/DESIGN.md
CHANGED
|
@@ -164,6 +164,22 @@ one, passes it to `home-hosted set-token` through `HHOSTED_TOKEN` (the CLI print
|
|
|
164
164
|
nothing), and keeps it 0600 in its own state directory. It is never rendered,
|
|
165
165
|
logged, or embedded in a unit file.
|
|
166
166
|
|
|
167
|
+
The token state the page shows is measured, not assumed. When the panel answers,
|
|
168
|
+
the plugin proves its token with a non-mutating `listServers()`: a refusal is
|
|
169
|
+
`stale` and the write path drops to the config file, while a panel that never
|
|
170
|
+
answered leaves the state `unknown` — a timeout is not a refusal, and
|
|
171
|
+
`tokenVerified` records whether a proof actually happened.
|
|
172
|
+
|
|
173
|
+
A refused token, or a hash this plugin never had, is replaced by
|
|
174
|
+
`panel.reclaimToken`: it clears the old hash first (`set-token --clear`, without
|
|
175
|
+
which `set-token` refuses to overwrite one), mints and enrols a fresh token
|
|
176
|
+
through the same `HHOSTED_TOKEN` path, and proves it against the panel before
|
|
177
|
+
returning the refreshed status. Every token operation on one state directory is
|
|
178
|
+
serialised; two concurrent mints used to leave the stored plaintext and the
|
|
179
|
+
panel's hash disagreeing, and nothing could ever recover. If the CLI cannot run
|
|
180
|
+
nothing is written; if it fails after the clear, the stored token is removed,
|
|
181
|
+
because home-hosted no longer accepts it and a stored plaintext would only lie.
|
|
182
|
+
|
|
167
183
|
## Privilege
|
|
168
184
|
|
|
169
185
|
Boot scope needs privilege somewhere on every platform: a system unit, or
|
package/lib/client.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({ id: "dsh-home-hosted", factory: (require) => {
|
|
2
2
|
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
-
"use strict";var se=Object.defineProperty;var bt=Object.getOwnPropertyDescriptor;var vt=Object.getOwnPropertyNames;var yt=Object.prototype.hasOwnProperty;var xt=(e,t)=>{for(var n in t)se(e,n,{get:t[n],enumerable:!0})},wt=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of vt(t))!yt.call(e,o)&&o!==n&&se(e,o,{get:()=>t[o],enumerable:!(a=bt(t,o))||a.enumerable});return e};var St=e=>wt(se({},"__esModule",{value:!0}),e);var Gt={};xt(Gt,{apply:()=>zt,inject:()=>jt});module.exports=St(Gt);var ee="homeHosted",le={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",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:"$HHOSTED_HOME",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",panelReplace:"Replace with {copy}",panelCopyPinned:"pinned dependency",panelCopyGlobal:"global install",panelTakeoverTitle:"Replace 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:"Replace",writeViaApi:"authenticated API",writeViaFile:"config file",writeViaNone:"unavailable",tokenEnrolled:"enrolled",tokenPresent:"present",tokenAbsent:"absent",tokenUnknown:"unknown",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.",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",agentToolStatus:"Status",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.",agentToolDescServersList:"List the servers the panel supervises, with status, port and URL.",agentToolDescServersLifecycle:"Start, stop and restart supervised servers.",agentToolDescServersEdit:"Create, update and delete the panel's server entries.",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"},fe={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",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:"$HHOSTED_HOME",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",panelReplace:"\u66FF\u6362\u4E3A{copy}",panelCopyPinned:"\u56FA\u5B9A\u4F9D\u8D56",panelCopyGlobal:"\u5168\u5C40\u5B89\u88C5",panelTakeoverTitle:"\u66FF\u6362\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:"\u66FF\u6362",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",tokenUnknown:"\u672A\u77E5",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",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",agentToolStatus:"\u67E5\u770B\u72B6\u6001",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",agentToolDescServersList:"\u5217\u51FA\u9762\u677F\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\u9762\u677F\u7684\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\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"};function kt(e,t){return t===void 0?e:e.replace(/\{(\w+)\}/g,(n,a)=>Object.prototype.hasOwnProperty.call(t,a)?String(t[a]):n)}var be=(e,t)=>kt(le[e]??e,t);function ve(e){if(e!==void 0)try{let t=e.bind(ee);if(typeof t=="function")return t}catch{}return be}function ye(e,t=be){return e===void 0?t:(n,a)=>{let o;try{o=e(n,a)}catch{o=void 0}return o===void 0||o.length===0||o===n?t(n,a):o}}var F=require("react");var B=require("react");var xe="/home-hosted";var j=["status","servers_list","servers_lifecycle","servers_edit","autostart_manage","ui_manage"],we=["servers_lifecycle","servers_edit","autostart_manage","ui_manage"],Ct=2,Yt={version:Ct,autostart:{enabled:!1,mechanism:"auto"},manageDsh:!1,entries:[],agentTools:{enabled:!0,allow:[...j]},panel:{port:null},authNotice:!0,uiStyle:"detailed",cli:{prefer:"pinned"}};var Tt="/api";function I(e,t,n){return{ok:!1,error:n===void 0?{code:e,message:t}:{code:e,message:t,detail:n}}}function ce(e){return typeof e=="object"&&e!==null}function Pt(e){return e instanceof Error?e.message:String(e)}function Nt(e){if(!ce(e))return I("bad-response","The panel returned a non-object response");if(typeof e.v=="number"&&e.v!==1)return I("version-mismatch",`Response protocol v${e.v} does not match the expected v${1}`);let t=e.result;if(!ce(t))return I("bad-response","The panel returned no result");if(t.ok===!0)return"value"in t?{ok:!0,value:t.value}:I("bad-response","A successful response carried no value");if(t.ok===!1){let n=t.error;return ce(n)&&typeof n.message=="string"?I(typeof n.code=="string"?n.code:"error",n.message,n.detail):I("error","The panel reported a failure without a message")}return I("bad-response","The panel returned an unrecognised result")}async function k(e,t,n={}){let a=n.fetch??globalThis.fetch;if(typeof a!="function")return I("no-fetch","No fetch implementation is available");let o={v:1,endpoint:e,payload:t},r;try{r=await a(`${Tt}${xe}`,{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify(o)})}catch(i){return I("network",Pt(i))}if(!r.ok){let i=r.statusText.length>0?` ${r.statusText}`:"";return I("http",`HTTP ${r.status}${i}`)}let l;try{l=await r.json()}catch{return I("bad-json","The panel returned invalid JSON")}return Nt(l)}function Se(e,t={}){return k("settings.update",{patch:e},t)}var Et=5e3;function ke(e=Et){let[t,n]=(0,B.useState)(null),[a,o]=(0,B.useState)(null),[r,l]=(0,B.useState)(!0),i=(0,B.useRef)(!0),s=(0,B.useCallback)(async()=>{let h=await k("status",{});i.current&&(h.ok?(n(h.value),o(null)):o(h.error),l(!1))},[]);return(0,B.useEffect)(()=>{i.current=!0,s();let h=setInterval(()=>{s()},e);return()=>{i.current=!1,clearInterval(h)}},[s,e]),{data:t,error:a,loading:r,refresh:s}}var m=require("react/jsx-runtime");function O({size:e=14,children:t}){return(0,m.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 Ce(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("rect",{x:"2.2",y:"3",width:"11.6",height:"7.6",rx:"1.6"}),(0,m.jsx)("path",{d:"M6.6 13.4h2.8M8 10.6v2.8"})]})}function Te(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("path",{d:"M8 2.4v5.2"}),(0,m.jsx)("path",{d:"M11.6 4.4a5 5 0 1 1-7.2 0"})]})}function Pe(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("rect",{x:"2.2",y:"2.8",width:"11.6",height:"10.4",rx:"1.6"}),(0,m.jsx)("path",{d:"M5.2 6.9l1.8 1.8-1.8 1.8M8.7 10.5h2.2"})]})}function Ne(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("path",{d:"M2.4 5.4h11.2M2.4 10.6h11.2"}),(0,m.jsx)("circle",{cx:"6",cy:"5.4",r:"1.6",fill:"currentColor",stroke:"none"}),(0,m.jsx)("circle",{cx:"10.4",cy:"10.6",r:"1.6",fill:"currentColor",stroke:"none"})]})}function Ee(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("path",{d:"M8 2.3l5.4 2.9L8 8.1 2.6 5.2z"}),(0,m.jsx)("path",{d:"M2.6 8.6l5.4 2.9 5.4-2.9"}),(0,m.jsx)("path",{d:"M2.6 11.4l5.4 2.9 5.4-2.9"})]})}function Re(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("path",{d:"M13.4 9.4A5.5 5.5 0 1 1 12.2 4.4"}),(0,m.jsx)("path",{d:"M12.8 1.7v2.9h-2.9"})]})}function Ae(e){return(0,m.jsx)(O,{...e,children:(0,m.jsx)("path",{d:"M6.2 3.8L10.4 8l-4.2 4.2"})})}function He(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("path",{d:"M6.6 3.4H3.4v9.2h9.2V9.4"}),(0,m.jsx)("path",{d:"M9.4 3.4h3.2v3.2M12.6 3.4L7.8 8.2"})]})}function te(e){return(0,m.jsxs)(O,{...e,children:[(0,m.jsx)("path",{d:"M8 2.6l5.7 10.2H2.3z"}),(0,m.jsx)("path",{d:"M8 6.4v3.1M8 11.5h.01"})]})}function Me(e){return(0,m.jsx)(O,{...e,children:(0,m.jsx)("path",{d:"M3 8.4l3.3 3.3L13 5"})})}var L="\u2014";function v(e){if(e==null)return L;let t=String(e);return t.length>0?t:L}function Ie(e){return e.length>0?e.join(", "):L}function he(e){return we.includes(e)}var pe={status:"agentToolStatus",servers_list:"agentToolServersList",servers_lifecycle:"agentToolServersLifecycle",servers_edit:"agentToolServersEdit",autostart_manage:"agentToolAutostartManage",ui_manage:"agentToolUiManage"},Le={status:"agentToolDescStatus",servers_list:"agentToolDescServersList",servers_lifecycle:"agentToolDescServersLifecycle",servers_edit:"agentToolDescServersEdit",autostart_manage:"agentToolDescAutostartManage",ui_manage:"agentToolDescUiManage"},Be={api:"writeViaApi",file:"writeViaFile",none:"writeViaNone"},Oe={enrolled:"tokenEnrolled",present:"tokenPresent",absent:"tokenAbsent",unknown:"tokenUnknown"},ne={"not-installed":"bootStateNotInstalled","installed-disabled":"bootStateInstalledDisabled","enabled-running":"bootStateEnabledRunning","enabled-failing":"bootStateEnabledFailing",unsupported:"bootStateUnsupported"},_e={config:"panelCliConfig",dependency:"panelCliDependency",path:"panelCliPathSource",none:"panelCliMissing"};function oe(e,t=52){if(e.length<=t)return e;let n=e.includes("\\")?"\\":"/",a=e.split(/[\\/]/).filter(i=>i.length>0);if(a.length<4)return e;let o=/^[A-Za-z]:$/.test(a[0]??"")?3:2;if(a.length<=o)return e;let l=`${/^[\\/]/.test(e)?n:""}${a.slice(0,o).join(n)}${n}\u2026${n}${a.slice(-2).join(n)}`;return l.length<e.length?l:e}function Ue(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 De(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Rt(e,t){if(Object.is(e,t))return!0;try{return JSON.stringify(e)===JSON.stringify(t)}catch{return!1}}function Fe(e,t){let n={};for(let a of Object.keys(t)){let o=e[a],r=t[a];if(De(o)&&De(r)){let l=Fe(o,r);Object.keys(l).length>0&&(n[a]=l)}else Rt(o,r)||(n[a]=r)}return n}function Ve(e,t){return Fe(e,t)}function $e(e,t,n){let a=new Set(e);return n?a.add(t):a.delete(t),j.filter(o=>a.has(o))}var ze=require("react");async function je(e){try{if(typeof navigator<"u"&&navigator.clipboard!==void 0)return await navigator.clipboard.writeText(e),!0}catch{}return!1}var c=require("react/jsx-runtime");function At(...e){return e.filter(t=>typeof t=="string"&&t.length>0).join(" ")}function _({icon:e,title:t,action:n,children:a}){return(0,c.jsxs)("section",{className:"hh-section",children:[(0,c.jsxs)("header",{className:"hh-section-head",children:[e===void 0?null:(0,c.jsx)("span",{className:"hh-section-icon",children:e}),(0,c.jsx)("h3",{className:"hh-section-title",children:t}),(0,c.jsx)("span",{className:"hh-section-rule","aria-hidden":"true"}),n===void 0?null:(0,c.jsx)("span",{className:"hh-section-action",children:n})]}),(0,c.jsx)("div",{className:"hh-section-body",children:a})]})}function b({label:e,children:t}){return(0,c.jsxs)("div",{className:"hh-spec",children:[(0,c.jsx)("span",{className:"hh-spec-label",children:e}),(0,c.jsx)("span",{className:"hh-spec-value",children:t})]})}function U({children:e}){return(0,c.jsx)("code",{className:"hh-code",children:e})}function y({children:e}){return typeof e=="string"&&e.length===0?null:(0,c.jsx)("p",{className:"hh-hint",children:e})}function E({tone:e,children:t}){return(0,c.jsx)("span",{className:"hh-chip","data-tone":e??"idle",children:t})}function z({href:e,children:t}){return(0,c.jsxs)("a",{className:"hh-link",href:e,target:"_blank",rel:"noreferrer noopener",children:[t??e,(0,c.jsx)("span",{className:"hh-link-icon","aria-hidden":"true",children:(0,c.jsx)(He,{size:11})})]})}function D({label:e,open:t=!1,children:n}){return(0,c.jsxs)("details",{className:"hh-details",open:t||void 0,children:[(0,c.jsxs)("summary",{className:"hh-summary",children:[(0,c.jsx)("span",{className:"hh-chevron","aria-hidden":"true",children:(0,c.jsx)(Ae,{size:12})}),e]}),(0,c.jsx)("div",{className:"hh-details-body",children:n})]})}function G({tone:e="bad",icon:t=!0,title:n,children:a}){return(0,c.jsxs)("div",{className:"hh-note","data-tone":e,role:e==="bad"?"alert":"note",children:[t?(0,c.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,c.jsx)(te,{size:13})}):null,(0,c.jsxs)("div",{className:"hh-note-body",children:[n===void 0?null:(0,c.jsx)("span",{className:"hh-note-title",children:n}),typeof a=="string"?(0,c.jsx)("p",{children:a}):a]})]})}function Ge({title:e,detail:t}){return(0,c.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,c.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,c.jsx)(te,{size:13})}),(0,c.jsxs)("div",{className:"hh-note-body",children:[(0,c.jsx)("strong",{children:e}),t.length>0?(0,c.jsx)("p",{children:t}):null]})]})}function Z({error:e,title:t}){return e===null?null:(0,c.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,c.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,c.jsx)(te,{size:13})}),(0,c.jsxs)("div",{className:"hh-note-body",children:[(0,c.jsx)("strong",{children:t}),(0,c.jsxs)("p",{children:[(0,c.jsx)("code",{children:e.code})," \u2014 ",e.message]})]})]})}function Ht(){return(0,c.jsx)("span",{className:"hh-spinner","aria-hidden":"true"})}function T({children:e,onClick:t,disabled:n,busy:a,variant:o="default",icon:r,title:l}){let i=n===!0||a===!0;return(0,c.jsxs)("button",{type:"button",className:At("hh-btn",o!=="default"&&`hh-btn-${o}`),onClick:t,disabled:i,title:l,children:[a===!0?(0,c.jsx)(Ht,{}):r,e]})}function ae({label:e,checked:t,disabled:n,onChange:a}){return(0,c.jsxs)("button",{type:"button",role:"switch",className:"hh-switch","aria-checked":t,disabled:n,onClick:()=>a(!t),children:[(0,c.jsx)("span",{className:"hh-switch-track","aria-hidden":"true",children:(0,c.jsx)("span",{className:"hh-switch-knob"})}),(0,c.jsx)("span",{className:"hh-check-label",children:e})]})}function Ke({label:e,checked:t,disabled:n,onChange:a}){return(0,c.jsxs)("label",{className:"hh-check",children:[(0,c.jsx)("input",{type:"checkbox",checked:t,disabled:n,onChange:o=>a(o.target.checked)}),(0,c.jsx)("span",{className:"hh-check-label",children:e})]})}function re({value:e,options:t,disabled:n,label:a,onChange:o}){return(0,c.jsx)("select",{className:"hh-select",value:e,disabled:n,"aria-label":a,onChange:r=>o(r.target.value),children:t.map(r=>(0,c.jsx)("option",{value:r.value,children:r.label},r.value))})}function ue({label:e,meta:t,path:n,hint:a,checked:o,disabled:r,onChange:l}){return(0,c.jsxs)("label",{className:"hh-choice-option","data-disabled":r===!0,children:[(0,c.jsx)("input",{type:"radio",checked:o,disabled:r,onChange:()=>l()}),(0,c.jsxs)("span",{className:"hh-choice-label",children:[(0,c.jsx)("span",{children:e}),a]}),t===void 0?null:(0,c.jsx)("span",{className:"hh-choice-meta",children:t}),n===void 0?null:(0,c.jsx)("span",{className:"hh-choice-path",title:n,children:oe(n)})]})}function We({children:e}){return(0,c.jsxs)(E,{tone:"accent",children:[(0,c.jsx)(Me,{size:10}),e]})}function Q({text:e,copyLabel:t,copiedLabel:n}){let[a,o]=(0,ze.useState)(!1);return(0,c.jsxs)("div",{className:"hh-code-box",children:[(0,c.jsx)("textarea",{className:"hh-code-text",readOnly:!0,value:e,rows:Math.min(e.split(`
|
|
4
|
-
`).length,4)}),(0,c.jsx)("div",{className:"hh-btn-row",children:(0,c.jsx)(
|
|
5
|
-
`),copyLabel:e("copy"),copiedLabel:e("copied")})]}):null]}):null,
|
|
6
|
-
`),copyLabel:e("copy"),copiedLabel:e("copied")})]}):null,(0,f.jsxs)(
|
|
7
|
-
`),copyLabel:e("copy"),copiedLabel:e("copied")}),(0,
|
|
3
|
+
"use strict";var ce=Object.defineProperty;var yt=Object.getOwnPropertyDescriptor;var xt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var St=(e,t)=>{for(var n in t)ce(e,n,{get:t[n],enumerable:!0})},kt=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of xt(t))!wt.call(e,o)&&o!==n&&ce(e,o,{get:()=>t[o],enumerable:!(a=yt(t,o))||a.enumerable});return e};var Tt=e=>kt(ce({},"__esModule",{value:!0}),e);var Yt={};St(Yt,{apply:()=>Kt,inject:()=>Wt});module.exports=Tt(Yt);var ae="homeHosted",de={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",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:"$HHOSTED_HOME",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",panelReplace:"Replace with {copy}",panelCopyPinned:"pinned dependency",panelCopyGlobal:"global install",panelTakeoverTitle:"Replace 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:"Replace",writeViaApi:"authenticated API",writeViaFile:"config file",writeViaNone:"unavailable",tokenEnrolled:"enrolled",tokenPresent:"present",tokenAbsent:"absent",tokenStale:"stale",tokenUnknown:"unknown",panelTokenWarningTitle:"The panel API token needs attention",panelTokenWarnAbsent:"The panel is answering, but no API token is enrolled yet; regenerate one to write through the API instead of the config file.",panelTokenWarnPresent:"home-hosted holds an API token this plugin does not have, so it cannot authenticate; regenerate one to replace it.",panelTokenWarnStale:"The panel refused this plugin's API token, so writes fall back to the config file; regenerate it.",panelTokenRegenerate:"Regenerate",panelTokenRegenerated:"A fresh API token was enrolled and the panel accepted it.",panelTokenRegenerateFailed:"The token was not replaced: {message}",panelReclaimAuto:"Regenerate automatically when refused",panelReclaimAutoHint:"A tool call that finds a refused token re-enrols one instead of failing.",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.",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",agentToolStatus:"Status",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.",agentToolDescServersList:"List the servers the panel supervises, with status, port and URL.",agentToolDescServersLifecycle:"Start, stop and restart supervised servers.",agentToolDescServersEdit:"Create, update and delete the panel's server entries.",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"},ve={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",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:"$HHOSTED_HOME",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",panelReplace:"\u66FF\u6362\u4E3A{copy}",panelCopyPinned:"\u56FA\u5B9A\u4F9D\u8D56",panelCopyGlobal:"\u5168\u5C40\u5B89\u88C5",panelTakeoverTitle:"\u66FF\u6362\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:"\u66FF\u6362",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\u9700\u8981\u5904\u7406",panelTokenWarnAbsent:"\u9762\u677F\u6709\u54CD\u5E94\uFF0C\u4F46\u8FD8\u6CA1\u6709\u767B\u8BB0 API \u4EE4\u724C\uFF1B\u91CD\u65B0\u751F\u6210\u4E00\u4E2A\u5373\u53EF\u901A\u8FC7 API \u5199\u5165\uFF0C\u800C\u4E0D\u5FC5\u76F4\u63A5\u6539\u914D\u7F6E\u6587\u4EF6\u3002",panelTokenWarnPresent:"home-hosted \u6301\u6709\u4E00\u4E2A\u672C\u63D2\u4EF6\u6CA1\u6709\u7684 API \u4EE4\u724C\uFF0C\u56E0\u6B64\u65E0\u6CD5\u8BA4\u8BC1\uFF1B\u91CD\u65B0\u751F\u6210\u4E00\u4E2A\u4EE5\u66FF\u6362\u5B83\u3002",panelTokenWarnStale:"\u9762\u677F\u62D2\u7EDD\u4E86\u672C\u63D2\u4EF6\u7684 API \u4EE4\u724C\uFF0C\u5199\u5165\u4F1A\u9000\u56DE\u914D\u7F6E\u6587\u4EF6\uFF1B\u8BF7\u91CD\u65B0\u751F\u6210\u3002",panelTokenRegenerate:"\u91CD\u65B0\u751F\u6210",panelTokenRegenerated:"\u5DF2\u767B\u8BB0\u65B0\u4EE4\u724C\uFF0C\u9762\u677F\u63A5\u53D7\u4E86\u5B83\u3002",panelTokenRegenerateFailed:"\u4EE4\u724C\u672A\u66FF\u6362\uFF1A{message}",panelReclaimAuto:"\u88AB\u62D2\u65F6\u81EA\u52A8\u91CD\u65B0\u751F\u6210",panelReclaimAutoHint:"\u5DE5\u5177\u8C03\u7528\u9047\u5230\u88AB\u62D2\u7EDD\u7684\u4EE4\u724C\u65F6\u4F1A\u91CD\u65B0\u767B\u8BB0\uFF0C\u800C\u4E0D\u662F\u76F4\u63A5\u5931\u8D25\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",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",agentToolStatus:"\u67E5\u770B\u72B6\u6001",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",agentToolDescServersList:"\u5217\u51FA\u9762\u677F\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\u9762\u677F\u7684\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\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"};function Ct(e,t){return t===void 0?e:e.replace(/\{(\w+)\}/g,(n,a)=>Object.prototype.hasOwnProperty.call(t,a)?String(t[a]):n)}var ye=(e,t)=>Ct(de[e]??e,t);function xe(e){if(e!==void 0)try{let t=e.bind(ae);if(typeof t=="function")return t}catch{}return ye}function we(e,t=ye){return e===void 0?t:(n,a)=>{let o;try{o=e(n,a)}catch{o=void 0}return o===void 0||o.length===0||o===n?t(n,a):o}}var j=require("react");var U=require("react");var Se="/home-hosted";var W=["status","servers_list","servers_lifecycle","servers_edit","autostart_manage","ui_manage"],ke=["servers_lifecycle","servers_edit","autostart_manage","ui_manage"],Pt=2,Xt={version:Pt,autostart:{enabled:!1,mechanism:"auto"},manageDsh:!1,entries:[],agentTools:{enabled:!0,allow:[...W]},panel:{port:null},authNotice:!0,reclaimToken:!0,uiStyle:"detailed",cli:{prefer:"pinned"}};var Nt="/api";function L(e,t,n){return{ok:!1,error:n===void 0?{code:e,message:t}:{code:e,message:t,detail:n}}}function he(e){return typeof e=="object"&&e!==null}function Et(e){return e instanceof Error?e.message:String(e)}function Rt(e){if(!he(e))return L("bad-response","The panel returned a non-object response");if(typeof e.v=="number"&&e.v!==1)return L("version-mismatch",`Response protocol v${e.v} does not match the expected v${1}`);let t=e.result;if(!he(t))return L("bad-response","The panel returned no result");if(t.ok===!0)return"value"in t?{ok:!0,value:t.value}:L("bad-response","A successful response carried no value");if(t.ok===!1){let n=t.error;return he(n)&&typeof n.message=="string"?L(typeof n.code=="string"?n.code:"error",n.message,n.detail):L("error","The panel reported a failure without a message")}return L("bad-response","The panel returned an unrecognised result")}async function w(e,t,n={}){let a=n.fetch??globalThis.fetch;if(typeof a!="function")return L("no-fetch","No fetch implementation is available");let o={v:1,endpoint:e,payload:t},r;try{r=await a(`${Nt}${Se}`,{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify(o)})}catch(i){return L("network",Et(i))}if(!r.ok){let i=r.statusText.length>0?` ${r.statusText}`:"";return L("http",`HTTP ${r.status}${i}`)}let l;try{l=await r.json()}catch{return L("bad-json","The panel returned invalid JSON")}return Rt(l)}function Te(e,t={}){return w("settings.update",{patch:e},t)}var At=5e3;function Ce(e=At){let[t,n]=(0,U.useState)(null),[a,o]=(0,U.useState)(null),[r,l]=(0,U.useState)(!0),i=(0,U.useRef)(!0),s=(0,U.useCallback)(async()=>{let p=await w("status",{});i.current&&(p.ok?(n(p.value),o(null)):o(p.error),l(!1))},[]);return(0,U.useEffect)(()=>{i.current=!0,s();let p=setInterval(()=>{s()},e);return()=>{i.current=!1,clearInterval(p)}},[s,e]),{data:t,error:a,loading:r,refresh:s}}var m=require("react/jsx-runtime");function D({size:e=14,children:t}){return(0,m.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 Pe(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("rect",{x:"2.2",y:"3",width:"11.6",height:"7.6",rx:"1.6"}),(0,m.jsx)("path",{d:"M6.6 13.4h2.8M8 10.6v2.8"})]})}function Ne(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("path",{d:"M8 2.4v5.2"}),(0,m.jsx)("path",{d:"M11.6 4.4a5 5 0 1 1-7.2 0"})]})}function Ee(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("rect",{x:"2.2",y:"2.8",width:"11.6",height:"10.4",rx:"1.6"}),(0,m.jsx)("path",{d:"M5.2 6.9l1.8 1.8-1.8 1.8M8.7 10.5h2.2"})]})}function Re(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("path",{d:"M2.4 5.4h11.2M2.4 10.6h11.2"}),(0,m.jsx)("circle",{cx:"6",cy:"5.4",r:"1.6",fill:"currentColor",stroke:"none"}),(0,m.jsx)("circle",{cx:"10.4",cy:"10.6",r:"1.6",fill:"currentColor",stroke:"none"})]})}function Ae(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("path",{d:"M8 2.3l5.4 2.9L8 8.1 2.6 5.2z"}),(0,m.jsx)("path",{d:"M2.6 8.6l5.4 2.9 5.4-2.9"}),(0,m.jsx)("path",{d:"M2.6 11.4l5.4 2.9 5.4-2.9"})]})}function He(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("path",{d:"M13.4 9.4A5.5 5.5 0 1 1 12.2 4.4"}),(0,m.jsx)("path",{d:"M12.8 1.7v2.9h-2.9"})]})}function Ie(e){return(0,m.jsx)(D,{...e,children:(0,m.jsx)("path",{d:"M6.2 3.8L10.4 8l-4.2 4.2"})})}function Me(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("path",{d:"M6.6 3.4H3.4v9.2h9.2V9.4"}),(0,m.jsx)("path",{d:"M9.4 3.4h3.2v3.2M12.6 3.4L7.8 8.2"})]})}function re(e){return(0,m.jsxs)(D,{...e,children:[(0,m.jsx)("path",{d:"M8 2.6l5.7 10.2H2.3z"}),(0,m.jsx)("path",{d:"M8 6.4v3.1M8 11.5h.01"})]})}function Le(e){return(0,m.jsx)(D,{...e,children:(0,m.jsx)("path",{d:"M3 8.4l3.3 3.3L13 5"})})}var B="\u2014";function y(e){if(e==null)return B;let t=String(e);return t.length>0?t:B}function Be(e){return e.length>0?e.join(", "):B}function ue(e){return ke.includes(e)}var ge={status:"agentToolStatus",servers_list:"agentToolServersList",servers_lifecycle:"agentToolServersLifecycle",servers_edit:"agentToolServersEdit",autostart_manage:"agentToolAutostartManage",ui_manage:"agentToolUiManage"},Oe={status:"agentToolDescStatus",servers_list:"agentToolDescServersList",servers_lifecycle:"agentToolDescServersLifecycle",servers_edit:"agentToolDescServersEdit",autostart_manage:"agentToolDescAutostartManage",ui_manage:"agentToolDescUiManage"},_e={api:"writeViaApi",file:"writeViaFile",none:"writeViaNone"},Ue={enrolled:"tokenEnrolled",present:"tokenPresent",absent:"tokenAbsent",stale:"tokenStale",unknown:"tokenUnknown"},ie={"not-installed":"bootStateNotInstalled","installed-disabled":"bootStateInstalledDisabled","enabled-running":"bootStateEnabledRunning","enabled-failing":"bootStateEnabledFailing",unsupported:"bootStateUnsupported"},De={config:"panelCliConfig",dependency:"panelCliDependency",path:"panelCliPathSource",none:"panelCliMissing"};function se(e,t=52){if(e.length<=t)return e;let n=e.includes("\\")?"\\":"/",a=e.split(/[\\/]/).filter(i=>i.length>0);if(a.length<4)return e;let o=/^[A-Za-z]:$/.test(a[0]??"")?3:2;if(a.length<=o)return e;let l=`${/^[\\/]/.test(e)?n:""}${a.slice(0,o).join(n)}${n}\u2026${n}${a.slice(-2).join(n)}`;return l.length<e.length?l:e}function Fe(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 Ve(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ht(e,t){if(Object.is(e,t))return!0;try{return JSON.stringify(e)===JSON.stringify(t)}catch{return!1}}function $e(e,t){let n={};for(let a of Object.keys(t)){let o=e[a],r=t[a];if(Ve(o)&&Ve(r)){let l=$e(o,r);Object.keys(l).length>0&&(n[a]=l)}else Ht(o,r)||(n[a]=r)}return n}function je(e,t){return $e(e,t)}function ze(e,t,n){let a=new Set(e);return n?a.add(t):a.delete(t),W.filter(o=>a.has(o))}var We=require("react");async function Ge(e){try{if(typeof navigator<"u"&&navigator.clipboard!==void 0)return await navigator.clipboard.writeText(e),!0}catch{}return!1}var c=require("react/jsx-runtime");function It(...e){return e.filter(t=>typeof t=="string"&&t.length>0).join(" ")}function F({icon:e,title:t,action:n,children:a}){return(0,c.jsxs)("section",{className:"hh-section",children:[(0,c.jsxs)("header",{className:"hh-section-head",children:[e===void 0?null:(0,c.jsx)("span",{className:"hh-section-icon",children:e}),(0,c.jsx)("h3",{className:"hh-section-title",children:t}),(0,c.jsx)("span",{className:"hh-section-rule","aria-hidden":"true"}),n===void 0?null:(0,c.jsx)("span",{className:"hh-section-action",children:n})]}),(0,c.jsx)("div",{className:"hh-section-body",children:a})]})}function b({label:e,children:t}){return(0,c.jsxs)("div",{className:"hh-spec",children:[(0,c.jsx)("span",{className:"hh-spec-label",children:e}),(0,c.jsx)("span",{className:"hh-spec-value",children:t})]})}function V({children:e}){return(0,c.jsx)("code",{className:"hh-code",children:e})}function v({children:e}){return typeof e=="string"&&e.length===0?null:(0,c.jsx)("p",{className:"hh-hint",children:e})}function E({tone:e,children:t}){return(0,c.jsx)("span",{className:"hh-chip","data-tone":e??"idle",children:t})}function K({href:e,children:t}){return(0,c.jsxs)("a",{className:"hh-link",href:e,target:"_blank",rel:"noreferrer noopener",children:[t??e,(0,c.jsx)("span",{className:"hh-link-icon","aria-hidden":"true",children:(0,c.jsx)(Me,{size:11})})]})}function $({label:e,open:t=!1,children:n}){return(0,c.jsxs)("details",{className:"hh-details",open:t||void 0,children:[(0,c.jsxs)("summary",{className:"hh-summary",children:[(0,c.jsx)("span",{className:"hh-chevron","aria-hidden":"true",children:(0,c.jsx)(Ie,{size:12})}),e]}),(0,c.jsx)("div",{className:"hh-details-body",children:n})]})}function Y({tone:e="bad",icon:t=!0,title:n,children:a}){return(0,c.jsxs)("div",{className:"hh-note","data-tone":e,role:e==="bad"?"alert":"note",children:[t?(0,c.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,c.jsx)(re,{size:13})}):null,(0,c.jsxs)("div",{className:"hh-note-body",children:[n===void 0?null:(0,c.jsx)("span",{className:"hh-note-title",children:n}),typeof a=="string"?(0,c.jsx)("p",{children:a}):a]})]})}function Ke({title:e,detail:t}){return(0,c.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,c.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,c.jsx)(re,{size:13})}),(0,c.jsxs)("div",{className:"hh-note-body",children:[(0,c.jsx)("strong",{children:e}),t.length>0?(0,c.jsx)("p",{children:t}):null]})]})}function ne({error:e,title:t}){return e===null?null:(0,c.jsxs)("div",{className:"hh-note",role:"alert",children:[(0,c.jsx)("span",{className:"hh-note-icon","aria-hidden":"true",children:(0,c.jsx)(re,{size:13})}),(0,c.jsxs)("div",{className:"hh-note-body",children:[(0,c.jsx)("strong",{children:t}),(0,c.jsxs)("p",{children:[(0,c.jsx)("code",{children:e.code})," \u2014 ",e.message]})]})]})}function Mt(){return(0,c.jsx)("span",{className:"hh-spinner","aria-hidden":"true"})}function S({children:e,onClick:t,disabled:n,busy:a,variant:o="default",icon:r,title:l}){let i=n===!0||a===!0;return(0,c.jsxs)("button",{type:"button",className:It("hh-btn",o!=="default"&&`hh-btn-${o}`),onClick:t,disabled:i,title:l,children:[a===!0?(0,c.jsx)(Mt,{}):r,e]})}function Q({label:e,checked:t,disabled:n,onChange:a}){return(0,c.jsxs)("button",{type:"button",role:"switch",className:"hh-switch","aria-checked":t,disabled:n,onClick:()=>a(!t),children:[(0,c.jsx)("span",{className:"hh-switch-track","aria-hidden":"true",children:(0,c.jsx)("span",{className:"hh-switch-knob"})}),(0,c.jsx)("span",{className:"hh-check-label",children:e})]})}function Ye({label:e,checked:t,disabled:n,onChange:a}){return(0,c.jsxs)("label",{className:"hh-check",children:[(0,c.jsx)("input",{type:"checkbox",checked:t,disabled:n,onChange:o=>a(o.target.checked)}),(0,c.jsx)("span",{className:"hh-check-label",children:e})]})}function le({value:e,options:t,disabled:n,label:a,onChange:o}){return(0,c.jsx)("select",{className:"hh-select",value:e,disabled:n,"aria-label":a,onChange:r=>o(r.target.value),children:t.map(r=>(0,c.jsx)("option",{value:r.value,children:r.label},r.value))})}function me({label:e,meta:t,path:n,hint:a,checked:o,disabled:r,onChange:l}){return(0,c.jsxs)("label",{className:"hh-choice-option","data-disabled":r===!0,children:[(0,c.jsx)("input",{type:"radio",checked:o,disabled:r,onChange:()=>l()}),(0,c.jsxs)("span",{className:"hh-choice-label",children:[(0,c.jsx)("span",{children:e}),a]}),t===void 0?null:(0,c.jsx)("span",{className:"hh-choice-meta",children:t}),n===void 0?null:(0,c.jsx)("span",{className:"hh-choice-path",title:n,children:se(n)})]})}function qe({children:e}){return(0,c.jsxs)(E,{tone:"accent",children:[(0,c.jsx)(Le,{size:10}),e]})}function oe({text:e,copyLabel:t,copiedLabel:n}){let[a,o]=(0,We.useState)(!1);return(0,c.jsxs)("div",{className:"hh-code-box",children:[(0,c.jsx)("textarea",{className:"hh-code-text",readOnly:!0,value:e,rows:Math.min(e.split(`
|
|
4
|
+
`).length,4)}),(0,c.jsx)("div",{className:"hh-btn-row",children:(0,c.jsx)(S,{variant:"ghost",onClick:()=>{Ge(e).then(o)},children:a?n:t})})]})}var x=require("react/jsx-runtime");function Je({t:e,status:t,updateSettings:n,uiStyle:a}){let o=t.settings.agentTools,r=o.allow??[],l=W.filter(s=>r.includes(s)).length,i=(s,p)=>{n(u=>({...u,agentTools:{...u.agentTools,allow:ze(u.agentTools.allow??[],s,p)}}))};return(0,x.jsxs)(F,{icon:(0,x.jsx)(Re,{}),title:e("agentTitle"),action:(0,x.jsx)(E,{children:e("agentCount",{enabled:l,total:W.length})}),children:[(0,x.jsx)(Q,{label:e("agentMaster"),checked:o.enabled,onChange:s=>n(p=>({...p,agentTools:{...p.agentTools,enabled:s}}))}),(0,x.jsx)(v,{children:e("agentApproval")}),a==="detailed"?(0,x.jsx)("div",{className:"hh-tool-cards",children:W.map(s=>(0,x.jsxs)("label",{className:"hh-tool-card",children:[(0,x.jsx)("input",{type:"checkbox",checked:r.includes(s),disabled:!o.enabled,onChange:p=>i(s,p.target.checked)}),(0,x.jsxs)("span",{className:"hh-tool-card-body",children:[(0,x.jsxs)("span",{className:"hh-tool-card-head",children:[(0,x.jsx)("span",{className:"hh-tool-card-name",children:e(ge[s])}),ue(s)?(0,x.jsx)(E,{tone:"warn",children:e("agentApprovalBadge")}):null]}),(0,x.jsx)("span",{className:"hh-tool-card-desc",children:e(Oe[s])})]})]},s))}):(0,x.jsx)("div",{className:"hh-tools",children:W.map(s=>(0,x.jsx)(Ye,{label:(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)("span",{className:"hh-check-text",children:e(ge[s])}),ue(s)?(0,x.jsx)(E,{tone:"warn",children:e("agentApprovalBadge")}):null]}),checked:r.includes(s),disabled:!o.enabled,onChange:p=>i(s,p)},s))})]})}var ot=require("react");function Xe(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function Ze(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:a,commands:o}=t;return n!==!1?null:{detail:typeof a=="string"?a:"",commands:Xe(o)}}function Qe(e){return e===void 0?null:{ok:e.ok===!0,action:e.action==="uninstall"?"uninstall":"install",detail:typeof e.detail=="string"?e.detail:"",commands:Xe(e.commands)}}var Lt=["enabled-running","enabled-failing","installed-disabled"];function et(e,t){let n=e.filter(r=>r.available).map(r=>r.mechanism),a=n.filter(r=>r!=="unsupported"),o=["auto",...a.length>0?a:n];return o.includes(t)||o.push(t),o}function tt(e,t){return e!==null&&e!==t}function nt(e,t){return e===null||e.ok?!1:e.action==="install"?Lt.includes(t):t==="not-installed"}var f=require("react/jsx-runtime");function at({t:e,status:t,run:n,updateSettings:a,busy:o,uiStyle:r}){let l=t.boot,i=t.settings.autostart,s=l.candidates??[],p=l.commands??[],[u,R]=(0,ot.useState)(null),C=o==="boot.install"||o==="boot.uninstall",X=et(s,i.mechanism).map(N=>({value:N,label:N==="auto"?e("bootMechanismAuto"):N})),Z=tt(l.mechanism,i.mechanism),I=l.mechanism!==null,T=N=>e(N==="install"?"bootActionInstall":"bootActionUninstall"),H=async N=>{let q=await n(`boot.${N}`,async()=>N==="install"?w("boot.install",i.mechanism==="auto"?{}:{mechanism:i.mechanism}):w("boot.uninstall",{}));if(!q.ok){R(null);return}let te=Ze(q.value);R(te===null?null:{ok:!1,action:N,detail:te.detail,commands:te.commands})},P=Qe(i.lastAttempt),O=nt(P,l.state),A=u??(O?null:P);return(0,f.jsxs)(F,{icon:(0,f.jsx)(Ne,{}),title:e("bootTitle"),action:(0,f.jsx)(le,{value:i.mechanism,options:X,label:e("bootMechanism"),disabled:o==="settings"||C,onChange:N=>a(q=>({...q,autostart:{...q.autostart,mechanism:N}}))}),children:[(0,f.jsxs)("div",{className:"hh-btn-row",children:[(0,f.jsx)(S,{variant:I?"default":"primary",disabled:i.mechanism==="unsupported",busy:o==="boot.install",onClick:()=>{H("install")},children:e(Z?"bootSwitchMode":"bootEnabled")}),(0,f.jsx)(S,{disabled:!I,busy:o==="boot.uninstall",onClick:()=>{H("uninstall")},children:e("bootUninstall")}),(0,f.jsx)(S,{variant:"ghost",busy:o==="boot.verify",onClick:()=>{n("boot.verify",()=>w("boot.verify",{}))},children:e("bootRecheck")})]}),i.enabled&&l.state==="not-installed"?(0,f.jsx)(Y,{tone:"warn",children:e("bootRequestedNotInstalled")}):null,A!==null&&!A.ok?(0,f.jsxs)("div",{className:"hh-section-body",children:[(0,f.jsx)(Ke,{title:e("bootAttemptFailed",{action:T(A.action)}),detail:A.detail.length>0?A.detail:e("bootAttemptNoDetail")}),A.commands.length>0?(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(v,{children:e("bootAttemptCommands")}),(0,f.jsx)(oe,{text:A.commands.join(`
|
|
5
|
+
`),copyLabel:e("copy"),copiedLabel:e("copied")})]}):null]}):null,A!==null&&A.ok?(0,f.jsx)(v,{children:e("bootAttemptSucceeded",{action:T(A.action),detail:A.detail})}):null,p.length>0?(0,f.jsxs)($,{label:e("bootCommandsLabel"),open:r==="detailed",children:[(0,f.jsx)(v,{children:e("bootCommandsExplain")}),(0,f.jsx)(oe,{text:p.join(`
|
|
6
|
+
`),copyLabel:e("copy"),copiedLabel:e("copied")})]}):null,(0,f.jsxs)($,{label:e("details"),open:r==="detailed",children:[(0,f.jsx)(b,{label:e("bootState"),children:e(ie[l.state]??"bootStateUnsupported")}),(0,f.jsx)(b,{label:e("bootBootCapable"),children:l.bootCapable?e("yes"):e("no")}),(0,f.jsx)(b,{label:e("bootPrivileged"),children:l.privileged?e("yes"):e("no")}),(0,f.jsx)(b,{label:e("bootUnitPath"),children:(0,f.jsx)(V,{children:y(l.unitPath)})}),l.detail.length>0?(0,f.jsx)(v,{children:l.detail}):null]})]})}var k=require("react/jsx-runtime");function Bt(e){return e.defaultEntryId??"dsh"}function rt({t:e,status:t,run:n,busy:a}){let o=t.entries??[],r=t.settings.manageDsh===!0,l=t.boot.platform==="win32",i=Bt(t),s=p=>{if(p){let u={id:i,autostart:!0};n("entries.apply",()=>w("entries.apply",{intents:[u]}))}else n("entries.remove",()=>w("entries.remove",{id:i}))};return(0,k.jsxs)(F,{icon:(0,k.jsx)(Ee,{}),title:e("entriesTitle"),children:[(0,k.jsx)(Q,{label:e("entriesManage",{id:i}),checked:r,disabled:a!==null,onChange:s}),(0,k.jsx)(v,{children:e("entriesManageNote",{id:i})}),l?(0,k.jsx)(Y,{tone:"warn",children:e("entriesManageWinWarning",{id:i})}):null,o.length===0?(0,k.jsx)(v,{children:e("entriesEmpty",{id:i})}):(0,k.jsx)("div",{className:"hh-list",children:o.map(p=>{let u=p.live;return(0,k.jsxs)("div",{className:"hh-item",children:[(0,k.jsxs)("span",{className:"hh-item-main",children:[(0,k.jsx)("span",{className:"hh-item-name",children:p.intent.id}),(0,k.jsx)(E,{tone:p.exists?"ok":"bad",children:p.exists?e("entriesExists"):e("entriesMissing")}),(0,k.jsx)(E,{children:p.managed?e("entriesManaged"):e("entriesUnmanaged")}),p.drift.length>0?(0,k.jsx)(E,{tone:"warn",children:`${e("entriesDrift")} ${Be(p.drift)}`}):null]}),(0,k.jsx)("span",{className:"hh-item-spacer"}),(0,k.jsx)("span",{className:"hh-item-meta",children:u===null?e("entriesNotRunning"):`${y(u.status)}${u.pid===null?"":` \xB7 pid ${u.pid}`}`})]},p.intent.id)})})]})}var J=require("react");var d=require("react/jsx-runtime"),Ot={absent:"panelTokenWarnAbsent",present:"panelTokenWarnPresent",stale:"panelTokenWarnStale"};function _t({value:e,label:t,hint:n,invalidLabel:a,placeholder:o,disabled:r,onChange:l}){let[i,s]=(0,J.useState)(e===null?"":String(e));(0,J.useEffect)(()=>{s(e===null?"":String(e))},[e]);let p=i.trim()===""?null:Number(i),u=p!==null&&(!Number.isInteger(p)||p<1||p>65535),R=()=>{if(u){s(e===null?"":String(e));return}p!==e&&l(p)};return(0,d.jsxs)("div",{className:"hh-field-block",children:[(0,d.jsxs)("div",{className:"hh-field",children:[(0,d.jsx)("label",{className:"hh-field-label",htmlFor:"hh-panel-port",children:t}),(0,d.jsx)("input",{id:"hh-panel-port",className:"hh-input",type:"number",value:i,placeholder:o,disabled:r,onChange:C=>s(C.target.value),onBlur:R,onKeyDown:C=>{C.key==="Enter"&&R()}})]}),(0,d.jsx)(v,{children:u?a:n})]})}function it({t:e,status:t,run:n,updateSettings:a,busy:o,uiStyle:r}){let l=t.panel,i=t.cli,s=i?.prefer??t.settings.cli?.prefer??"pinned",[p,u]=(0,J.useState)(!1),[R,C]=(0,J.useState)(null),[G,X]=(0,J.useState)(null),Z=l.reachable?Ot[l.token]:void 0,I=i?.version??null,T=I!==null&&l.version!==null,H=l.reachable&&T&&I!==l.version,{dependency:P,global:O}=i===void 0?{dependency:null,global:null}:Fe(i),A=i===void 0?[]:[`pnpm add -g home-hosted@${i.expectedRange}`,`npm install -g home-hosted@${i.expectedRange}`],N=M=>{a(_=>({..._,cli:{..._.cli,prefer:M}}))},q=async()=>{let M=await n("cli.installGlobal",()=>w("cli.installGlobal",{}));if(!M.ok)return;let _=M.value;C(typeof _?.output=="string"?_.output:null)},te=async()=>{let M=await n("panel.reclaimToken",()=>w("panel.reclaimToken",{}));X(M.ok?e("panelTokenRegenerated"):e("panelTokenRegenerateFailed",{message:M.error.message}))};return(0,d.jsxs)(F,{icon:(0,d.jsx)(Pe,{}),title:e("panelTitle"),children:[Z===void 0?null:(0,d.jsxs)(Y,{tone:"warn",title:e("panelTokenWarningTitle"),children:[(0,d.jsx)("p",{children:e(Z)}),(0,d.jsx)("div",{className:"hh-note-actions",children:(0,d.jsx)(S,{variant:"primary",busy:o==="panel.reclaimToken",onClick:()=>{te()},children:e("panelTokenRegenerate")})})]}),G===null?null:(0,d.jsx)(v,{children:G}),i===void 0?null:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsxs)("div",{className:"hh-choice",role:"radiogroup","aria-label":e("panelCopy"),children:[(0,d.jsx)(me,{label:e("optionsPreferPinned"),hint:(0,d.jsx)(qe,{children:e("optionsRecommended")}),meta:P===null?void 0:y(P.version),path:P?.path??void 0,checked:s==="pinned",disabled:P===null||o==="settings",onChange:()=>N("pinned")}),(0,d.jsx)(me,{label:e("optionsPreferGlobal"),meta:O===null?void 0:y(O.version),path:O?.path??void 0,checked:s==="global",disabled:O===null||o==="settings",onChange:()=>N("global")})]}),(0,d.jsx)(v,{children:e("panelCopyHint")}),i.source==="config"?(0,d.jsx)(v,{children:e("optionsConfigOverride")}):null,i.source==="path"&&s!=="global"?(0,d.jsx)(v,{children:e("panelCliNotPinned",{range:i.expectedRange})}):null,i.supported?null:(0,d.jsx)(Y,{tone:"warn",children:e("panelCliUnsupported")}),i.launcherPath!=null&&i.launcherVersion==null?(0,d.jsx)(Y,{tone:"warn",children:e("panelCliLauncherFailed")}):null]}),(0,d.jsx)(_t,{value:t.settings.panel?.port??null,label:e("panelPort"),hint:l.reachable?e("panelPortHint"):e("panelPortFree"),invalidLabel:e("panelPortInvalid"),placeholder:l.configPort==null?void 0:String(l.configPort),disabled:l.reachable||o!==null,onChange:M=>a(_=>({..._,panel:{..._.panel,port:M}}))}),(0,d.jsxs)("div",{className:"hh-field-block",children:[(0,d.jsx)(Q,{label:e("panelReclaimAuto"),checked:t.settings.reclaimToken!==!1,disabled:o==="settings",onChange:M=>a(_=>({..._,reclaimToken:M}))}),(0,d.jsx)(v,{children:e("panelReclaimAutoHint")})]}),(0,d.jsxs)("div",{className:"hh-btn-row",children:[l.reachable?null:(0,d.jsx)(S,{variant:"primary",busy:o==="panel.start",onClick:()=>{n("panel.start",()=>w("panel.start",{}))},children:e("panelStart")}),H&&!p?(0,d.jsx)(S,{variant:"primary",onClick:()=>u(!0),children:e("panelReplace",{copy:e(s==="global"?"panelCopyGlobal":"panelCopyPinned")})}):null]}),H&&p?(0,d.jsx)("div",{className:"hh-note",role:"alertdialog","aria-label":e("panelTakeoverTitle"),children:(0,d.jsxs)("div",{className:"hh-note-body",children:[(0,d.jsx)("strong",{children:e("panelTakeoverTitle")}),(0,d.jsx)("p",{children:e("panelTakeoverBody",{id:t.defaultEntryId??"dsh"})}),(0,d.jsxs)("div",{className:"hh-note-actions",children:[(0,d.jsx)(S,{onClick:()=>u(!1),children:e("confirmCancel")}),(0,d.jsx)(S,{variant:"danger",busy:o==="panel.takeover",onClick:()=>{u(!1),n("panel.takeover",()=>w("panel.takeover",{}))},children:e("confirmReplace")})]})]})}):null,i!==void 0&&O===null?(0,d.jsxs)($,{label:e("optionsInstallLabel"),open:r==="detailed",children:[(0,d.jsx)(v,{children:e("optionsInstallHint")}),(0,d.jsx)(oe,{text:A.join(`
|
|
7
|
+
`),copyLabel:e("copy"),copiedLabel:e("copied")}),(0,d.jsx)("div",{className:"hh-btn-row",children:(0,d.jsx)(S,{busy:o==="cli.installGlobal",onClick:()=>{q()},children:e("optionsInstall")})}),R===null?null:(0,d.jsx)("pre",{className:"hh-output",children:R})]}):null,(0,d.jsxs)($,{label:e("details"),open:r==="detailed",children:[(0,d.jsx)(b,{label:e("panelHome"),children:(0,d.jsx)(V,{children:l.home})}),(0,d.jsx)(b,{label:e("panelUrl"),children:l.url===null?y(l.url):(0,d.jsx)(K,{href:l.url,children:l.url})}),(0,d.jsx)(b,{label:e("panelVersion"),children:y(l.version)}),(0,d.jsx)(b,{label:e("panelPid"),children:y(l.pid)}),(0,d.jsx)(b,{label:e("panelWriteVia"),children:e(_e[l.writeVia]??"writeViaNone")}),(0,d.jsx)(b,{label:e("panelToken"),children:e(Ue[l.token]??"tokenUnknown")}),i===void 0?null:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(b,{label:e("panelCliSource"),children:`${e(De[i.source]??"panelCliMissing")} \xB7 ${y(i.version)}`}),(0,d.jsx)(b,{label:e("panelCliPath"),children:(0,d.jsx)(V,{children:y(i.path)})})]}),l.detail.length>0?(0,d.jsx)(v,{children:l.detail}):null]})]})}var Ut=5e3;function fe(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ee(e,t){let n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:null}function st(e,t){let n=e[t];return typeof n=="string"&&n.length>0?n:null}function lt(e){let t=e/1e3;return`${Number.isInteger(t)?t:t.toFixed(1)}s`}function ct(e,t,n){if(!fe(e))return B;if(e.enabled!==!0)return n("serversDisabled");let a=st(e,"mode"),o=fe(e.http)?e.http:null,r;if(a==="http"||a===null&&o!==null){let i=(o===null?null:st(o,"path"))??"/",s=o===null?null:ee(o,"expectStatus"),p=o===null?null:ee(o,"expectStatusBelow");r=s!==null?n("serversHealthHttp",{status:s,path:i}):p!==null?n("serversHealthHttpBelow",{status:p,path:i}):n("serversHealthHttpProbe",{path:i})}else t!==null?r=n("serversHealthPort",{port:t}):r=n("serversHealthProbe");let l=ee(e,"intervalMs");return l!==null&&l!==Ut?`${r} \xB7 ${n("serversHealthEvery",{seconds:lt(l)})}`:r}function dt(e,t){if(!fe(e))return B;if(e.enabled===!1)return t("serversDisabled");let n=ee(e,"maxRetries"),a=ee(e,"baseDelayMs"),o=ee(e,"factor");return n===null||a===null||o===null?t("serversEnabled"):t("serversRestartSummary",{retries:n,base:lt(a),factor:o})}var Dt={"not-installed":"idle","installed-disabled":"warn","enabled-running":"ok","enabled-failing":"bad",unsupported:"idle"};function Ft(...e){return e.filter(t=>t!==null&&t.length>0).join(" \xB7 ")}function Vt(e,t){let{panel:n}=e;return n.reachable?{key:"panel",tone:"ok",name:t("sigPanel"),state:t("stateAnswering"),meta:y(n.version),href:n.url}:{key:"panel",tone:e.lastError===null?"idle":"bad",name:t("sigPanel"),state:t("stateNotAnswering"),meta:n.home,href:null}}function $t(e,t){let{boot:n}=e,o=e.settings.autostart.enabled&&n.state==="not-installed"?"warn":Dt[n.state]??"idle",r=n.mechanism??(e.settings.autostart.mechanism==="auto"?null:e.settings.autostart.mechanism);return{key:"autostart",tone:o,name:t("sigAutostart"),state:t(ie[n.state]??"bootStateUnsupported"),meta:r??"",href:null}}function jt(e,t){let n=e.entries??[],a=t("sigEntry",{id:e.defaultEntryId??"dsh"}),o=e.settings.manageDsh===!0,r=n.filter(p=>!p.exists).length,l=n.filter(p=>p.drift.length>0).length,i=n.find(p=>p.live!==null)?.live??null;return{key:"entry",tone:o?r>0?"bad":l>0?"warn":i!==null?"ok":"warn":"idle",name:a,state:t(o?"stateManaged":"stateNotManaged"),meta:i===null?t("entriesNotRunning"):Ft(y(i.status),i.pid===null?null:`pid ${i.pid}`),href:null}}function ht(e,t){return[Vt(e,t),$t(e,t),jt(e,t)]}function pt(e,t){let n=e.filter(a=>a.status==="running").length;return t("serversCount",{running:n,total:e.length})}var h=require("react/jsx-runtime");function ut({t:e,server:t,run:n,busy:a,offline:o}){let r=t.status==="running";return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(S,{variant:"ghost",disabled:o||r,busy:a===`servers.start:${t.id}`,onClick:()=>{n(`servers.start:${t.id}`,()=>w("servers.start",{id:t.id}))},children:e("serversStart")}),(0,h.jsx)(S,{variant:"ghost",disabled:o||!r,busy:a===`servers.stop:${t.id}`,onClick:()=>{n(`servers.stop:${t.id}`,()=>w("servers.stop",{id:t.id}))},children:e("serversStop")}),(0,h.jsx)(S,{variant:"ghost",disabled:o||!r,busy:a===`servers.restart:${t.id}`,onClick:()=>{n(`servers.restart:${t.id}`,()=>w("servers.restart",{id:t.id}))},children:e("serversRestart")})]})}function zt({text:e}){return e.length===0?(0,h.jsx)(h.Fragment,{children:B}):(0,h.jsx)("span",{className:"hh-nowrap",title:e,children:(0,h.jsx)(V,{children:e})})}function gt({t:e,status:t,run:n,busy:a,uiStyle:o}){let r=t.servers??[],l=!t.panel.reachable||a!==null,i=new Map((t.entries??[]).map(s=>[s.intent.id,s.intent]));return(0,h.jsxs)(F,{icon:(0,h.jsx)(Ae,{}),title:e("serversTitle"),action:(0,h.jsx)(E,{children:pt(r,e)}),children:[(0,h.jsx)(v,{children:t.panel.url===null?e("serversHintNoPanel"):(0,h.jsxs)(h.Fragment,{children:[`${e("serversHintPanel")} `,(0,h.jsx)(K,{href:t.panel.url,children:t.panel.url})]})}),r.length===0?(0,h.jsx)(v,{children:e("serversEmpty")}):(0,h.jsx)("div",{className:o==="detailed"?"hh-cards":"hh-list",children:r.map(s=>{let p=s.status==="running",u=s.config;if(o==="detailed"){let R=(u.args??[]).join(" "),C=u.cwd??"",G=i.get(s.id)?.persistent;return(0,h.jsxs)("article",{className:"hh-card",children:[(0,h.jsxs)("div",{className:"hh-card-head",children:[(0,h.jsx)("span",{className:"hh-item-name",children:s.id}),(0,h.jsx)(E,{tone:p?"ok":"idle",children:y(s.status)}),G===!0?(0,h.jsx)("span",{title:e("serversPersistentHint"),children:(0,h.jsx)(E,{tone:"accent",children:e("serversPersistent")})}):null,(0,h.jsx)("span",{className:"hh-item-spacer"}),(0,h.jsx)("span",{className:"hh-item-actions",children:(0,h.jsx)(ut,{t:e,server:s,run:n,busy:a,offline:l})})]}),(0,h.jsxs)("div",{className:"hh-card-facts",children:[(0,h.jsx)(b,{label:e("serversUrl"),children:s.url===null?y(s.url):(0,h.jsx)(K,{href:s.url,children:s.url})}),(0,h.jsx)(b,{label:e("serversPid"),children:y(s.pid)}),(0,h.jsx)(b,{label:e("serversPort"),children:y(u.port)}),(0,h.jsx)(b,{label:e("serversAutostart"),children:u.autostart===void 0?B:u.autostart?e("yes"):e("no")})]}),(0,h.jsxs)($,{label:e("serversConfiguration"),children:[(0,h.jsx)(b,{label:e("serversCommand"),children:u.command===void 0||u.command.length===0?B:(0,h.jsx)("span",{className:"hh-nowrap",title:u.command,children:(0,h.jsx)(V,{children:u.command})})}),(0,h.jsx)(b,{label:e("serversArgs"),children:(0,h.jsx)(zt,{text:R})}),(0,h.jsx)(b,{label:e("serversCwd"),children:C.length===0?B:(0,h.jsx)("span",{className:"hh-nowrap",title:C,children:(0,h.jsx)(V,{children:se(C)})})}),(0,h.jsx)(b,{label:e("serversOnPortConflict"),children:y(u.onPortConflict)}),(0,h.jsx)(b,{label:e("serversHealth"),children:ct(u.health,u.port??null,e)}),(0,h.jsx)(b,{label:e("serversRestartPolicy"),children:dt(u.restart,e)})]}),(0,h.jsx)($,{label:e("serversRawConfig"),children:(0,h.jsx)("pre",{className:"hh-output",children:JSON.stringify(u,null,2)})})]},s.id)}return(0,h.jsxs)("div",{className:"hh-item",children:[(0,h.jsxs)("span",{className:"hh-item-main",children:[(0,h.jsx)("span",{className:"hh-item-name",children:s.id}),(0,h.jsx)(E,{tone:p?"ok":"idle",children:y(s.status)}),s.url===null?null:(0,h.jsx)(K,{href:s.url,children:s.url})]}),(0,h.jsx)("span",{className:"hh-item-spacer"}),s.pid===null?null:(0,h.jsx)("span",{className:"hh-item-meta",children:`${e("serversPid")} ${s.pid}`}),(0,h.jsx)("span",{className:"hh-item-actions",children:(0,h.jsx)(ut,{t:e,server:s,run:n,busy:a,offline:l})})]},s.id)})})]})}var be=`
|
|
8
8
|
.hh-root {
|
|
9
9
|
--hh-line: var(--dsw-alias-border-l2, rgba(128, 128, 128, 0.25));
|
|
10
10
|
--hh-line-soft: var(--dsw-alias-border-l1, rgba(128, 128, 128, 0.15));
|
|
@@ -758,6 +758,6 @@ var module = { exports: {} }; var exports = module.exports;
|
|
|
758
758
|
.hh-tool-cards { grid-template-columns: minmax(0, 1fr); }
|
|
759
759
|
.hh-card-facts { grid-template-columns: minmax(0, 1fr); }
|
|
760
760
|
}
|
|
761
|
-
`;var g=require("react/jsx-runtime");function
|
|
761
|
+
`;var g=require("react/jsx-runtime");function Gt({signal:e}){return(0,g.jsxs)("div",{className:"hh-signal","data-tone":e.tone,children:[(0,g.jsx)("span",{className:"hh-signal-dot","aria-hidden":"true"}),(0,g.jsx)("span",{className:"hh-signal-name",children:e.name}),(0,g.jsx)("span",{className:"hh-signal-state",children:e.state}),e.meta.length===0&&e.href===null?null:(0,g.jsxs)("span",{className:"hh-signal-meta",children:[e.meta,e.href===null?null:(0,g.jsxs)(g.Fragment,{children:[e.meta.length===0?null:" \xB7 ",(0,g.jsx)(K,{href:e.href,children:e.href})]})]})]})}function mt(e){let t=we(e.t),{data:n,error:a,loading:o,refresh:r}=Ce(),[l,i]=(0,j.useState)(null),[s,p]=(0,j.useState)(null),u=(0,j.useCallback)((T,H)=>(p(T),i(null),(async()=>{try{let P=await H();return P.ok||i(P.error),P}catch(P){let O={code:"client",message:P instanceof Error?P.message:String(P)};return i(O),{ok:!1,error:O}}finally{p(null),await r()}})()),[r]),R=(0,j.useCallback)(T=>{if(n===null)return;let H=je(n.settings,T(n.settings));Object.keys(H).length!==0&&u("settings",()=>Te(H))},[n,u]),C=n?.settings.uiStyle??"detailed",[G,X]=(0,j.useState)(C);(0,j.useEffect)(()=>{X(C)},[C]);let Z=T=>{X(T),R(H=>({...H,uiStyle:T}))};if(n===null)return(0,g.jsxs)("div",{className:"hh-root",children:[(0,g.jsx)("style",{children:be}),o?(0,g.jsx)(v,{children:t("loading")}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(ne,{error:a??{code:"status",message:t("statusUnavailable")},title:t("errorTitle")}),(0,g.jsx)("div",{className:"hh-btn-row",children:(0,g.jsx)(S,{onClick:()=>{r()},children:t("retry")})})]})]});let I={t,status:n,run:u,updateSettings:R,busy:s,uiStyle:G};return(0,g.jsxs)("div",{className:"hh-root",children:[(0,g.jsx)("style",{children:be}),(0,g.jsxs)("header",{className:"hh-head",children:[(0,g.jsx)("h2",{className:"hh-title",children:t("tab")}),(0,g.jsx)("span",{className:"hh-head-spacer"}),(0,g.jsx)(le,{value:G,label:t("uiStyleLabel"),disabled:s==="settings",options:[{value:"detailed",label:t("uiStyleDetailed")},{value:"compact",label:t("uiStyleCompact")}],onChange:T=>Z(T)}),(0,g.jsx)(S,{variant:"ghost",icon:(0,g.jsx)(He,{size:13}),busy:s==="status.refresh",onClick:()=>{u("status.refresh",()=>w("status",{refresh:!0}))},children:t("refresh")})]}),(0,g.jsx)("div",{className:"hh-signals","data-busy":s!==null,children:ht(n,t).map(T=>(0,g.jsx)(Gt,{signal:T},T.key))}),n.lastError===null?null:(0,g.jsx)(ne,{error:{code:"panel",message:n.lastError},title:t("errorTitle")}),(0,g.jsx)(ne,{error:a,title:t("errorTitle")}),(0,g.jsx)(ne,{error:l,title:t("errorTitle")}),(0,g.jsx)(it,{...I}),(0,g.jsx)(at,{...I}),(0,g.jsx)(rt,{...I}),(0,g.jsx)(Je,{...I}),(0,g.jsx)(gt,{...I})]})}var Wt=["slots","locale"],ft="[dsh-home-hosted]";function z(e,t){t===void 0?console.warn(`${ft} ${e}`):console.warn(`${ft} ${e}`,t)}function bt(e,t){try{let n=e.get?.(t);if(n!=null)return n}catch{}try{let n=e[t];if(n!=null)return n}catch{}}function vt(e,t,n){if(typeof e.effect=="function")try{e.effect(t,n);return}catch(a){z(`registering the effect "${n}" failed`,a);return}try{t()}catch(a){z(`the effect "${n}" failed`,a)}}function Kt(e){try{let t=bt(e,"locale"),n=xe(t);t===void 0?z("the locale service is unavailable; the page keeps its bundled English copy"):vt(e,()=>{let o=[];try{o.push(t.register(ae,{en:de,zh:ve}))}catch(r){z("registering the dictionaries failed",r)}return()=>{for(let r of o)try{r()}catch(l){z("disposing a dictionary failed",l)}}},"dsh-home-hosted: dictionaries");let a=bt(e,"slots");if(a===void 0){z("the slots service is unavailable; the settings section was not registered");return}vt(e,()=>{try{return a.inject("settings.section",()=>{try{return a.register({name:"settings.section",id:"home-hosted",order:60,label:()=>n("tab"),locale:ae,inject:()=>({t:n})},mt)}catch(o){return z("registering the settings section failed",o),()=>{}}})}catch(o){return z("injecting into settings.section failed",o),()=>{}}},"dsh-home-hosted: settings section")}catch(t){z("client bootstrap failed",t)}}
|
|
762
762
|
|
|
763
763
|
return module.exports; } });
|