@catheadowl/ukp 0.2.4 → 0.2.6
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 +15 -7
- package/docs/remote-deployment.md +101 -16
- package/package.json +1 -1
- package/src/capabilities/door-health.ts +480 -0
- package/src/capabilities/remote-client.ts +201 -21
- package/src/capabilities/rg.ts +147 -20
- package/src/capabilities/tls-identity.ts +3 -2
- package/src/cli.ts +7 -1
- package/src/commands/diagnose.ts +80 -2
- package/src/commands/guide-content/remote.txt +4 -2
- package/src/commands/guide-content/rg.txt +35 -0
- package/src/commands/guide.ts +11 -4
- package/src/commands/init.ts +27 -0
- package/src/commands/rg.ts +45 -14
- package/src/commands/serve-task.ts +334 -44
- package/src/commands/serve.ts +101 -19
- package/src/server.ts +113 -65
- package/src/spawn-relay.ts +57 -0
package/README.md
CHANGED
|
@@ -61,7 +61,9 @@ predictable scope, and a single command surface. Use UKP when:
|
|
|
61
61
|
Requirements). `read` and `nav` are derived defaults of every local
|
|
62
62
|
Service.
|
|
63
63
|
- Run base lexical search with `rg` across endpoint files — no search
|
|
64
|
-
provider needed, on by default, shaped into `read`-ready references
|
|
64
|
+
provider needed, on by default, shaped into `read`-ready references —
|
|
65
|
+
or enumerate them with `rg --files` (a tree walk: empty and binary files
|
|
66
|
+
included, hidden files behind `-- --hidden`).
|
|
65
67
|
- Search indexed content, QMD-backed: one endpoint, the workspace default
|
|
66
68
|
scope, or the whole local Registry. `--recursive` additionally searches
|
|
67
69
|
the endpoints a Service declares in its manifest `dependencies` —
|
|
@@ -69,8 +71,9 @@ predictable scope, and a single command surface. Use UKP when:
|
|
|
69
71
|
- Propose changes as an idempotent, reviewable suggestion — the proposal
|
|
70
72
|
lands in the endpoint's inbox and the verdict stays with its owner.
|
|
71
73
|
- Update provider-owned indexes through a stable UKP command (QMD-backed).
|
|
72
|
-
- Serve an endpoint over HTTP — a single endpoint,
|
|
73
|
-
a host door — when you want it reachable from other
|
|
74
|
+
- Serve an endpoint over HTTP — a single endpoint, a `--select`ed subset, or
|
|
75
|
+
every local binding as a host door — when you want it reachable from other
|
|
76
|
+
machines.
|
|
74
77
|
- Want a read-only endpoint? Declare zero capabilities — an empty
|
|
75
78
|
`[capabilities]` table still registers one (derived `read`/`nav` only).
|
|
76
79
|
- Give agents JSON output (`--json`; `ukp read` uses `--format json`),
|
|
@@ -143,7 +146,7 @@ Endpoint commands:
|
|
|
143
146
|
| `ukp search` | Indexed search through the endpoint's provider (QMD today); `--recursive` expands the manifest's declared `dependencies`. Results hand off via docid session keys and verified `ukp://` references. |
|
|
144
147
|
| `ukp read` | Reads an endpoint-scoped resource — exact path, `ukp://` URI, or a `docid` handed off by search results. |
|
|
145
148
|
| `ukp nav` | Markdown outline of an endpoint (`--depth`, respects `.gitignore`); on by default, configurable via `[capabilities.nav]`. |
|
|
146
|
-
| `ukp rg` | Lexical grep (ripgrep) across endpoint files — provider-free, on by default;
|
|
149
|
+
| `ukp rg` | Lexical grep (ripgrep) across endpoint files — provider-free, on by default; `--files` enumerates them instead of searching. Results become `read`-ready `ukp://` references. A missing rg binary skips the endpoint with a warning. |
|
|
147
150
|
| `ukp propose` | Submits an idempotent change proposal (suggestion box — the owner decides what happens next). Created/unchanged/updated; the revision bumps only on `updated`. |
|
|
148
151
|
|
|
149
152
|
Registry commands:
|
|
@@ -161,7 +164,7 @@ Operations commands:
|
|
|
161
164
|
| `ukp diagnose` | Checks a Service folder or endpoint scope for wiring problems. |
|
|
162
165
|
| `ukp inspect` | Explains current scope, bindings, manifest capabilities, and provider availability. |
|
|
163
166
|
| `ukp update` | Runs provider-owned maintenance when `update/qmd` is declared (local endpoints today). |
|
|
164
|
-
| `ukp serve` | Serves one endpoint — or, without `--endpoint`,
|
|
167
|
+
| `ukp serve` | Serves one endpoint — or, without `--endpoint`, local bindings as a **host door** (every one of them, or just the ones `--select` names — unselected endpoints are not served, routed, or declared) — over HTTP (a discovery document plus the five command routes; loopback by default). |
|
|
165
168
|
|
|
166
169
|
Help commands:
|
|
167
170
|
|
|
@@ -171,6 +174,7 @@ Help commands:
|
|
|
171
174
|
| `ukp guide service` | Provider-agnostic Service setup path. |
|
|
172
175
|
| `ukp guide service qmd` | Provider-owned setup for the QMD provider. |
|
|
173
176
|
| `ukp guide client` | How a workspace uses registered Services by default. |
|
|
177
|
+
| `ukp guide rg` | The rg quickstart: modes, glob semantics, visibility tiers. |
|
|
174
178
|
| `ukp guide remote` | How to serve and consume endpoints across machines. |
|
|
175
179
|
| `ukp guide propose` | The propose quickstart. |
|
|
176
180
|
|
|
@@ -200,10 +204,14 @@ NAT/EIP cloud host (public IP on no NIC)? Name it with
|
|
|
200
204
|
over the same key, so the pin (and every registration) survives; details in
|
|
201
205
|
the deployment guide.
|
|
202
206
|
|
|
203
|
-
Registration mechanics: a **host door** url imports every endpoint
|
|
207
|
+
Registration mechanics: a **host door** url imports every endpoint it declares
|
|
204
208
|
(`--endpoint <name>` checks the served name and narrows the import to that
|
|
205
209
|
one, `--select` narrows to a subset); `--token` is stored with the binding;
|
|
206
|
-
re-running a registration refreshes it idempotently.
|
|
210
|
+
re-running a registration refreshes it idempotently. A host whose registry
|
|
211
|
+
mixes shareable knowledge with internal projects can serve
|
|
212
|
+
`ukp serve --select a,b,c` — one port for exactly those endpoints; everything
|
|
213
|
+
the door does not select behaves as if it did not exist (discovery, routes,
|
|
214
|
+
and 404 rosters alike).
|
|
207
215
|
|
|
208
216
|
Remote endpoints take the same commands as local ones — search, read, nav,
|
|
209
217
|
rg, propose. The full guide — the host door (one port for the whole
|
|
@@ -65,6 +65,13 @@ Notes:
|
|
|
65
65
|
wake — the client chooses the door port per invocation, which a fixed
|
|
66
66
|
forced command cannot express.
|
|
67
67
|
|
|
68
|
+
Windows note: some antivirus setups (Windows Defender behavioral inspection
|
|
69
|
+
included) delay a process spawned directly by the runtime by several seconds
|
|
70
|
+
per call — 5-10s per ssh/rg spawn was measured before ukp routed its
|
|
71
|
+
Windows tool spawns through a one-level relay. ukp does this automatically;
|
|
72
|
+
if you also add your own exclusion for your package manager's runtimes the
|
|
73
|
+
residual per-call cost is just the real ssh handshake plus the door spawn.
|
|
74
|
+
|
|
68
75
|
Windows hosts work out of the box: when the host's OpenSSH default shell
|
|
69
76
|
(cmd.exe) rejects the POSIX wake form, the client detects the signature and
|
|
70
77
|
resends the pinned cmd.exe form automatically — nothing to configure beyond
|
|
@@ -116,12 +123,23 @@ one bun process always running — with **no visible window** (a hidden
|
|
|
116
123
|
launcher owns the console; a popping cmd box is not an acceptable product
|
|
117
124
|
form) and bounded crash retry. Verified end to end (register/TOFU →
|
|
118
125
|
read → nav, plus zero-flash and crash-recovery drills) on a Windows 11
|
|
119
|
-
host with a plain user-level install
|
|
126
|
+
host with a plain user-level install; the task recipe and the log
|
|
127
|
+
ownership were re-verified end to end on 2026-09-23 (unelevated
|
|
128
|
+
per-user registration, no execution time limit, whole-tree restart).
|
|
129
|
+
Steps 3–6 are exactly what
|
|
120
130
|
`ukp serve --print-task --host 0.0.0.0 --tls`
|
|
121
131
|
(or `--tls-cert/--tls-key`) prints for you — the generator assembles the
|
|
122
132
|
mechanical half (start script, hidden launcher, Task Scheduler command,
|
|
123
133
|
firewall rule, token placeholder); this section keeps the judgment calls
|
|
124
|
-
and the pitfalls the verification run caught
|
|
134
|
+
and the pitfalls the verification run caught. A fast path exists for the
|
|
135
|
+
two file artifacts: `ukp serve --print-task --write ...` writes
|
|
136
|
+
`start-door.cmd` (token interpolated from your `UKP_SERVE_TOKEN` — never
|
|
137
|
+
displayed) and the hidden launcher straight into `%USERPROFILE%\.ukp\`,
|
|
138
|
+
CRLF by construction; existing files are never overwritten (manual edits
|
|
139
|
+
— a PATH patch, say — are safe; regeneration means removing the old files
|
|
140
|
+
first, as the removal section prescribes). The task-registration and
|
|
141
|
+
firewall steps stay on stdout for you to run; the print-only form remains
|
|
142
|
+
the full playbook (its Notes and the removal section):
|
|
125
143
|
|
|
126
144
|
1. Install the usual way (bun's official installer + `npm i -g
|
|
127
145
|
@catheadowl/ukp` — the npm shim needs bun on PATH, both land in
|
|
@@ -136,8 +154,11 @@ and the pitfalls the verification run caught:
|
|
|
136
154
|
-subj "/CN=ukp" -addext "subjectAltName=IP:<lan-ip>,DNS:localhost"`
|
|
137
155
|
4. `%USERPROFILE%\.ukp\start-door.cmd` (CRLF!) — set UKP_SERVE_TOKEN,
|
|
138
156
|
run `ukp serve --host 0.0.0.0 --port 8570 --tls-cert ... --tls-key ...`
|
|
139
|
-
with the door.log
|
|
140
|
-
|
|
157
|
+
with **no redirect on the serve line** — door.log is owned solely by
|
|
158
|
+
the vbs launcher's outer redirect; a second redirect here deadlocks
|
|
159
|
+
the nested append-open and the door never starts. No PATH export: the
|
|
160
|
+
launcher finds bun itself, and the logged-on task carries the
|
|
161
|
+
per-user PATH. Write it
|
|
141
162
|
with a real editor (writing cmd files over ssh echo mangles `%`
|
|
142
163
|
escaping — copy the file instead).
|
|
143
164
|
5. `%USERPROFILE%\.ukp\start-door-hidden.vbs` (CRLF, real editor) — the
|
|
@@ -145,11 +166,16 @@ and the pitfalls the verification run caught:
|
|
|
145
166
|
at process creation (nothing ever flashes), captures everything to
|
|
146
167
|
door.log, propagates the exit code, and retries a crashed door
|
|
147
168
|
3 times, 30s apart. `ukp serve --print-task` prints it verbatim.
|
|
148
|
-
6.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
ukp-
|
|
169
|
+
6. Scheduled task — register from a **plain PowerShell shell** (no
|
|
170
|
+
elevation needed: a per-user logon trigger is the OneDrive/Teams-class
|
|
171
|
+
autostart path; a machine-level logon trigger or another user's
|
|
172
|
+
session still needs the elevated schtasks route). Use the
|
|
173
|
+
`Register-ScheduledTask` block `ukp serve --print-task` prints —
|
|
174
|
+
per-user `AtLogOn -User` trigger, battery flags, `IgnoreNew`, and
|
|
175
|
+
deliberately **no execution time limit**
|
|
176
|
+
(`-ExecutionTimeLimit ([TimeSpan]::Zero)`). Then the firewall rule
|
|
177
|
+
for the port (that one does need an elevated shell), and
|
|
178
|
+
`Start-ScheduledTask -TaskName ukp-door` to start now.
|
|
153
179
|
7. Client: `ukp register --url https://<host>:8570 --token <token>` —
|
|
154
180
|
TOFU pins the certificate; re-registering refreshes the pin.
|
|
155
181
|
|
|
@@ -161,16 +187,66 @@ Pitfalls the verification run caught:
|
|
|
161
187
|
- ONLOGON starts at LOGON, not boot, and the launcher's crash retry is
|
|
162
188
|
bounded (3×30s): after an unattended reboot nobody logs into, or after
|
|
163
189
|
exhausted retries, the door is down until the next logon or a manual
|
|
164
|
-
`
|
|
165
|
-
wrapping — or prefer ssh:// there. (Task
|
|
166
|
-
restart-on-failure setting does not fire on exit
|
|
167
|
-
on it.)
|
|
168
|
-
-
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
`Start-ScheduledTask -TaskName ukp-door`. Unattended-boot always-on
|
|
191
|
+
would need WinSW/NSSM-class wrapping — or prefer ssh:// there. (Task
|
|
192
|
+
Scheduler's own restart-on-failure setting does not fire on exit
|
|
193
|
+
codes — do not rely on it.)
|
|
194
|
+
- **The 72-hour default**: a task without an explicit execution time
|
|
195
|
+
limit is stopped by Task Scheduler 72 hours after it starts — for a
|
|
196
|
+
resident door that is a silent kill (no window, no log line). The
|
|
197
|
+
recipe pins `-ExecutionTimeLimit ([TimeSpan]::Zero)` (PT0S in the task
|
|
198
|
+
XML); keep it when editing the task by hand.
|
|
199
|
+
- To restart the door by hand (new token, ukp upgrade, new cert): kill
|
|
200
|
+
the **launcher root**, not just the serve leaf — `taskkill /PID
|
|
201
|
+
<wscript-pid> /T /F` on the `wscript.exe` running
|
|
202
|
+
`start-door-hidden.vbs`, then `Start-ScheduledTask -TaskName
|
|
203
|
+
ukp-door`. A leaf-only kill leaves the launcher's bounded retry to
|
|
204
|
+
re-grab the port within 30 seconds, racing the manual start (which
|
|
205
|
+
`IgnoreNew` turns into a no-op while the old launcher lives); the
|
|
206
|
+
scheduler's End-Task does not reliably kill the tree either. Each
|
|
207
|
+
door has its own wscript — in PowerShell, `Get-CimInstance
|
|
208
|
+
Win32_Process -Filter "Name='wscript.exe'" | Select-Object
|
|
209
|
+
ProcessId,CommandLine` and match the vbs name.
|
|
210
|
+
- **Git Bash path conversion**: MSYS rewrites slash-style arguments into
|
|
211
|
+
Git paths (`taskkill /PID …` fails with a misleading
|
|
212
|
+
Invalid-argument error that reads like a permission problem). Prefix
|
|
213
|
+
such commands with `MSYS_NO_PATHCONV=1`.
|
|
214
|
+
- **Do not edit start-door.cmd while the door runs**: cmd.exe resumes
|
|
215
|
+
reading a running batch file at a stale byte offset, so an in-place
|
|
216
|
+
edit above the current line makes it execute garbled fragments when
|
|
217
|
+
the current command returns (observed live: a mid-comment `a` ran as
|
|
218
|
+
a command). Stop the door first, edit, then restart.
|
|
171
219
|
- `rg` on the host is the host's business — no ripgrep installed means
|
|
172
220
|
the remote `rg` capability reports unavailable (everything else works).
|
|
173
221
|
|
|
222
|
+
To remove the door — the inverse of steps 4–0, in three levels (stopping
|
|
223
|
+
is not disabling, and disabling is not erasing; `ukp serve --print-task`
|
|
224
|
+
prints this checklist as its §5):
|
|
225
|
+
|
|
226
|
+
1. **Stop now**: `taskkill /PID <wscript-pid> /T /F` on the launcher
|
|
227
|
+
root (same lookup as the restart pitfall above). With the task still
|
|
228
|
+
registered, the next logon brings the door back.
|
|
229
|
+
2. **Stop for good**:
|
|
230
|
+
`Unregister-ScheduledTask -TaskName ukp-door -Confirm:$false` from a
|
|
231
|
+
plain shell — the same zero-elevation path as registering it. The
|
|
232
|
+
cmdlet confirms by default (hence the flag), and unregistering does
|
|
233
|
+
**not** stop a running instance: the kill in step 1 is not optional.
|
|
234
|
+
3. **Erase everything**: `netsh advfirewall firewall delete rule
|
|
235
|
+
name="ukp-door"` (the elevated shell again), then delete
|
|
236
|
+
`%USERPROFILE%\.ukp\start-door.cmd` (**it carries the token in
|
|
237
|
+
plaintext** — deleting it destroys this copy; if it ever left the
|
|
238
|
+
machine, treat the token as burned), `start-door-hidden.vbs`, and
|
|
239
|
+
`door.log`, plus the certificate material: your `--tls-cert` /
|
|
240
|
+
`--tls-key` paths, or — with `--tls` — the identity in the served
|
|
241
|
+
folder's `.ukp\tls\` (single-endpoint door: *inside* the KB folder,
|
|
242
|
+
so git or cloud sync carries the private key out;
|
|
243
|
+
`ukp init service` drops a self-ignoring `.ukp\.gitignore` there) or
|
|
244
|
+
beside the host registry (host door). The endpoints stay registered
|
|
245
|
+
on the host for local use — `ukp unregister --endpoint <name>` per
|
|
246
|
+
endpoint only if you are done with them; and every consumer that
|
|
247
|
+
registered holds the token in plaintext in its own registry —
|
|
248
|
+
`ukp unregister --endpoint <name>` there too.
|
|
249
|
+
|
|
174
250
|
## Socket activation (Linux — no resident process on the https path either)
|
|
175
251
|
|
|
176
252
|
systemd can hold the listening port itself and spawn the door on first
|
|
@@ -229,6 +305,15 @@ Notes:
|
|
|
229
305
|
addresses — a public EIP is not among them, and registration would fail
|
|
230
306
|
CERT_ALTNAME_INVALID. Add `--tls-san <public-ip>` next to `--tls`
|
|
231
307
|
(see Native TLS above): the SAN grows, the key (and pin) does not.
|
|
308
|
+
- **Removing the door** (the setup block's inverse — the same three
|
|
309
|
+
levels as the Windows teardown above, in one gesture):
|
|
310
|
+
`systemctl --user disable --now ukp-door.socket` (a door still
|
|
311
|
+
running stops with `systemctl --user stop ukp-door.service`), then
|
|
312
|
+
delete the two unit files and the token env file, and
|
|
313
|
+
`rm -rf ~/.ukp/tls` if you are done with the self-signed identity;
|
|
314
|
+
`loginctl disable-linger "$USER"` too if nothing else on the host
|
|
315
|
+
needs it. Nothing else is resident — consumer and host registry
|
|
316
|
+
bindings come off exactly as on the Windows side.
|
|
232
317
|
|
|
233
318
|
## Host door (one host, many endpoints — one gesture, zero tokens)
|
|
234
319
|
|