@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 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, or every local binding as
73
- a host door — when you want it reachable from other machines.
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; results become `read`-ready `ukp://` references. A missing rg binary skips the endpoint with a warning. |
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`, every local binding as a **host door** — over HTTP (a discovery document plus the five command routes; loopback by default). |
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 behind it
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. Steps 3–6 are exactly what
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 redirect. No PATH export: the launcher finds bun
140
- itself, and the logged-on task carries the per-user PATH. Write it
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. `schtasks /Create /TN ukp-door /TR "wscript.exe
149
- \"%USERPROFILE%\.ukp\start-door-hidden.vbs\"" /SC ONLOGON /F` (from an
150
- elevated shell — creating an ONLOGON task from a plain one fails with
151
- Access denied) + a firewall rule for the port; `schtasks /Run /TN
152
- ukp-door` to start now.
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
- `schtasks /Run`. Unattended-boot always-on would need WinSW/NSSM-class
165
- wrapping — or prefer ssh:// there. (Task Scheduler's own
166
- restart-on-failure setting does not fire on exit codes — do not rely
167
- on it.)
168
- - To restart the door by hand (new token, ukp upgrade, new cert):
169
- `taskkill /PID <door-pid> /T /F`, then `schtasks /Run /TN ukp-door` —
170
- `schtasks /End` does not reliably kill the process tree.
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catheadowl/ukp",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "bun": ">=1.3.14"