@xingular/harness 0.1.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/NOTICE.md +38 -0
- package/README.md +139 -28
- package/dist/cli.js +9598 -2201
- package/dist/terminal-pi.js +808 -16
- package/docs/README.md +15 -0
- package/docs/decisions/ADR-0001-owned-terminal.md +87 -0
- package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
- package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +68 -0
- package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +49 -0
- package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
- package/docs/terminal-tui.md +344 -0
- package/package.json +11 -4
- package/src/accounts/accounts.test.ts +197 -1
- package/src/accounts/accounts.ts +266 -28
- package/src/cli.ts +7 -3
- package/src/core/bus.test.ts +22 -0
- package/src/core/bus.ts +17 -2
- package/src/harness.ts +27 -4
- package/src/hub/catalog.json +123 -0
- package/src/hub/cli.ts +59 -0
- package/src/hub/hub.test.ts +205 -0
- package/src/hub/hub.ts +256 -0
- package/src/hub/schema.ts +81 -0
- package/src/index.ts +12 -2
- package/src/mcp/connections.ts +39 -12
- package/src/mcp/service.test.ts +49 -3
- package/src/mcp/service.ts +14 -3
- package/src/mcp/types.ts +10 -0
- package/src/memory/api.ts +16 -2
- package/src/memory/blocks.ts +3 -1
- package/src/memory/caller.ts +13 -1
- package/src/memory/curation.test.ts +206 -0
- package/src/memory/curation.ts +64 -0
- package/src/memory/dispatch.ts +5 -0
- package/src/memory/maintenance.test.ts +17 -1
- package/src/memory/maintenance.ts +367 -18
- package/src/memory/operations.ts +12 -0
- package/src/memory/proposals.ts +16 -8
- package/src/memory/recall.test.ts +11 -0
- package/src/memory/recall.ts +11 -3
- package/src/memory/trajectory.test.ts +178 -0
- package/src/memory/trajectory.ts +220 -0
- package/src/memory/wiki.ts +2 -1
- package/src/memory/wikiIndex.ts +3 -2
- package/src/plugins/builtin.ts +4 -2
- package/src/plugins/catalogue.test.ts +1 -1
- package/src/server/methods.ts +43 -2
- package/src/server/server.test.ts +20 -1
- package/src/sessions/approvals.test.ts +49 -0
- package/src/sessions/approvals.ts +26 -4
- package/src/sessions/contracts.ts +29 -3
- package/src/sessions/conversation.test.ts +83 -0
- package/src/sessions/lineageJoin.ts +1 -1
- package/src/sessions/policy.ts +4 -0
- package/src/sessions/questionBatches.test.ts +110 -0
- package/src/sessions/registry.ts +145 -27
- package/src/sessions/runStore.ts +14 -0
- package/src/sessions/runner.ts +45 -4
- package/src/sessions/sessions.test.ts +137 -4
- package/src/sessions/sessions.ts +51 -15
- package/src/sessions/subagentService.test.ts +159 -0
- package/src/sessions/subagentService.ts +236 -0
- package/src/sessions/subagents.ts +97 -0
- package/src/skills/registry.ts +16 -10
- package/src/terminal/accountsMenu.test.ts +225 -0
- package/src/terminal/accountsMenu.ts +382 -0
- package/src/terminal/control.test.ts +23 -0
- package/src/terminal/control.ts +23 -0
- package/src/terminal/controller.ts +134 -7
- package/src/terminal/hubMenu.ts +24 -0
- package/src/terminal/launch.test.ts +5 -14
- package/src/terminal/launch.ts +2 -42
- package/src/terminal/piExtension.lifecycle.test.ts +55 -0
- package/src/terminal/piExtension.ts +91 -6
- package/src/terminal/socket.test.ts +23 -0
- package/src/terminal/socket.ts +55 -20
- package/src/terminal/standalone.test.ts +37 -0
- package/src/terminal/standalone.ts +28 -7
- package/src/terminal/terminal.test.ts +220 -16
- package/src/terminal/terminals.ts +234 -16
- package/src/terminal/trajectory.test.ts +66 -0
- package/src/terminal/trajectory.ts +44 -0
- package/src/terminal/tui/application.test.ts +290 -0
- package/src/terminal/tui/application.ts +653 -0
- package/src/terminal/tui/commands.test.ts +278 -0
- package/src/terminal/tui/commands.ts +443 -0
- package/src/terminal/tui/dialogs.ts +301 -0
- package/src/terminal/tui/editor.test.ts +113 -0
- package/src/terminal/tui/editor.ts +109 -0
- package/src/terminal/tui/keybindings.test.ts +30 -0
- package/src/terminal/tui/keybindings.ts +59 -0
- package/src/terminal/tui/piAdapter.ts +62 -0
- package/src/terminal/tui/planMode.test.ts +10 -0
- package/src/terminal/tui/planMode.ts +12 -0
- package/src/terminal/tui/presentation.test.ts +79 -0
- package/src/terminal/tui/questions.test.ts +41 -0
- package/src/terminal/tui/questions.ts +47 -0
- package/src/terminal/tui/runtime.socket.test.ts +178 -0
- package/src/terminal/tui/runtime.test.ts +225 -0
- package/src/terminal/tui/runtime.ts +403 -0
- package/src/terminal/tui/screen.test.ts +143 -0
- package/src/terminal/tui/screen.ts +121 -0
- package/src/terminal/tui/sessionUi.ts +24 -0
- package/src/terminal/tui/settings.test.ts +150 -0
- package/src/terminal/tui/settings.ts +188 -0
- package/src/terminal/tui/skillInvocation.test.ts +71 -0
- package/src/terminal/tui/skillInvocation.ts +51 -0
- package/src/terminal/tui/status.test.ts +48 -0
- package/src/terminal/tui/status.ts +82 -0
- package/src/terminal/tui/theme.ts +185 -0
- package/src/terminal/tui/tools.test.ts +145 -0
- package/src/terminal/tui/tools.ts +142 -0
- package/src/terminal/tui/trajectoryPanel.test.ts +99 -0
- package/src/terminal/tui/trajectoryPanel.ts +226 -0
- package/src/terminal/tui/transcript.test.ts +39 -0
- package/src/terminal/tui/transcript.ts +135 -0
- package/src/terminal/tui/ui.test.ts +313 -0
- package/src/terminal/tui/ui.ts +166 -0
- package/src/terminal/tui/welcome.ts +102 -0
- package/src/terminal/tui/workingStatus.test.ts +44 -0
- package/src/terminal/tui/workingStatus.ts +238 -0
- package/src/tools/askUser.test.ts +69 -0
- package/src/tools/askUser.ts +31 -17
- package/src/tools/definitions.ts +42 -1
- package/src/tools/maintenance.ts +29 -0
- package/src/tools/memoryTools.ts +1 -1
- package/src/tools/registryWrite.test.ts +101 -0
- package/src/tools/registryWrite.ts +182 -0
- package/src/tools/spawnSubagent.ts +47 -0
- package/src/tools/types.ts +2 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 2.0.0 - 2026-10-18
|
|
6
|
+
|
|
7
|
+
- Let a connected app sign in with an OAuth client the application registered itself (`oauthClient: 'app'`), supplied through `HarnessOptions.oauthClients` and never stored; `connections.appClients` reports which catalog entries a build can sign in for. See [ADR-0005](docs/decisions/ADR-0005-app-provided-oauth-clients.md).
|
|
8
|
+
- Invoke a skill in the terminal as `$name` instead of `/skill:name`: the completion offers the loaded skills at a `$`, and a leading `$name` is sent to the model as that skill. A typed `/skill:name` still works, and `$` followed by a number or an unknown name stays ordinary text.
|
|
9
|
+
- Keep a stored key or sign-in when a terminal that began before it was saved ends, and let several terminals of one account share its auth.json across processes: a terminal saves only what its own Pi changed, and the last terminal out removes the file.
|
|
10
|
+
- Give every session bounded `trajectory_search` and `trajectory_read` tools for inspecting recorded run events without exposing credentials, attachments, or provider reasoning.
|
|
11
|
+
- Show terminal notices, such as mode changes, errors and the keyboard list, as rows in the conversation instead of above the composer; queued messages stay in the dock.
|
|
12
|
+
- Step the terminal's thinking effort with Shift+Up and Shift+Down within the levels the model supports. Shift+Tab toggles a read-only plan mode that withdraws changing tools until it is switched back.
|
|
13
|
+
- Show the product lockup above the terminal transcript only until the chat has a user message; a resumed session with history starts without it, and a header from a trusted extension is never hidden.
|
|
14
|
+
- Keep the terminal composer on the last rows in fullscreen while the transcript scrolls above it; `tuiMode: regular` keeps the flowing layout, and leaving fullscreen copies the conversation into scrollback.
|
|
15
|
+
- Add one native asynchronous subagent service for SDK, RPC and standalone terminal callers, with selective waits, parent joins, typed history receipts and explicit-resume recovery.
|
|
16
|
+
- Preserve capability ceilings and route child approvals/questions through the owning terminal; release pending interactions before SDK abort.
|
|
17
|
+
- Show a stable rotating work verb with an animated status glyph and keep the completion duration until the next turn.
|
|
18
|
+
|
|
19
|
+
- Harness owns the standalone terminal frontend, using persistent Pi 1.2.0 sessions and the inspected Oh My Pi 18.11.3 presentation.
|
|
20
|
+
- Add titanium and light themes, native session navigation, local command help and completion, account/plugin/Hub controls, and trusted extension UI hosting.
|
|
21
|
+
- Keep account isolation, exact prepared context and resource selection, the final tool gate, native histories and Harness run recording.
|
|
22
|
+
- Support grouped questions with atomic answers, cancellation and restored draft focus.
|
|
23
|
+
- Isolate stale plugin UI callbacks across session replacement and resource reload; restore terminal modes after fatal asynchronous failures and cleanup errors.
|
|
24
|
+
|
|
25
|
+
Implementation and verification limits are recorded in [the terminal reference](docs/terminal-tui.md).
|
package/NOTICE.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
The Harness terminal presentation adapts the titanium color palette, five-row Pi logo,
|
|
4
|
+
diagonal gradient and related terminal presentation conventions from Oh My Pi 18.11.3,
|
|
5
|
+
particularly `@oh-my-pi/pi-tui/src/theme/defaults/titanium.json` and
|
|
6
|
+
`@oh-my-pi/pi-tui/src/prompt/welcome.ts`.
|
|
7
|
+
|
|
8
|
+
Upstream: https://github.com/can1357/oh-my-pi
|
|
9
|
+
|
|
10
|
+
The adapted portions are included under the following upstream license. Harness-specific
|
|
11
|
+
product identity and runtime integration are maintained in this package. Dependencies retain
|
|
12
|
+
their own licenses and notices.
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
MIT License
|
|
16
|
+
|
|
17
|
+
Copyright (c) 2025 Mario Zechner
|
|
18
|
+
Copyright (c) 2025-2026 Can Bölük
|
|
19
|
+
Copyright (c) 2026 Stencil Labs, Inc.
|
|
20
|
+
|
|
21
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
22
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
23
|
+
in the Software without restriction, including without limitation the rights
|
|
24
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
25
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
26
|
+
furnished to do so, subject to the following conditions:
|
|
27
|
+
|
|
28
|
+
The above copyright notice and this permission notice shall be included in all
|
|
29
|
+
copies or substantial portions of the Software.
|
|
30
|
+
|
|
31
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
32
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
33
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
34
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
35
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
36
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
37
|
+
SOFTWARE.
|
|
38
|
+
```
|
package/README.md
CHANGED
|
@@ -8,15 +8,35 @@ needs to work for someone over time, and nothing about any particular applicatio
|
|
|
8
8
|
| Accounts | `src/accounts/` | Several isolated Pi accounts and pools, sign-in, model lists, health and limits. A session keeps the account it started with. |
|
|
9
9
|
| Sessions | `src/sessions/` | Pi SDK turns, run records and `events.jsonl`, interrupt, approvals, questions, recovery after a crash. |
|
|
10
10
|
| Prompt | `src/prompt/` | The system prompt compiled from sections with budgets and profiles; a stable prefix, and changing state delivered as updates in native history. |
|
|
11
|
-
| Memory | `src/memory/` | The Wiki: pages, facts, memory blocks, revisions, proposals with an evidence gate, undo, an Inbox, recall
|
|
11
|
+
| Memory | `src/memory/` | The Wiki: pages, facts, memory blocks, revisions, proposals with an evidence gate, undo, an Inbox, history recall, run trajectory inspection, and sleep-time consolidation. |
|
|
12
12
|
| Skills | `src/skills/` | Skills, prompts, and rules: a person's own in the data root, and built-in ones shipped with the harness or the application. |
|
|
13
13
|
| Plugins | `src/plugins/` | What a Pi session loads, chosen by the harness and never by Pi's own discovery; trust for a working folder's code; the list of every plugin and what reaches one caller. |
|
|
14
14
|
| Tools | `src/tools/` | Tool definitions, the memory tools, `ask_user`; a gate that asks the application's policy, then standing approvals, then the person. |
|
|
15
15
|
| Connected apps | `src/mcp/` | MCP connections, OAuth, per-session grants, redaction, a trace of what each call returned. |
|
|
16
|
-
| Terminal | `src/terminal/` |
|
|
16
|
+
| Terminal | `src/terminal/` | A Harness-owned terminal frontend over persistent Pi sessions, isolated accounts, compiled instructions, the tool gate and telemetry bridge, native history, plugin UI, `/plugins`, `/hub`, `/accounts`, and the existing session socket. |
|
|
17
17
|
| Server | `src/server/` | The same API over newline-delimited JSON, for a host that is not a Node program. |
|
|
18
18
|
|
|
19
19
|
It was split out of Xingular Agent, which is now an application built on it.
|
|
20
|
+
The [documentation index](docs/README.md) links current terminal architecture and decisions.
|
|
21
|
+
|
|
22
|
+
### Session options for applications
|
|
23
|
+
|
|
24
|
+
- Interactive sessions offer `spawn_subagent` and `wait_subagents` by default. `subagents: null` disables them; `{ maxDepth }` configures native nesting (default one, maximum three), independently of the host caller depth. Unattended sessions remain disabled unless the host explicitly supplies subagent options. A frozen capability set can narrow these tools further.
|
|
25
|
+
- `harness.subagents.spawn({ parentRunId, brief, tools?, wait? })` opens a fresh child of the same caller with no wider capabilities. It returns `{ runId, nativeSessionId }` once open; `wait: true` also waits for settlement. `harness.subagents.wait({ parentRunId, runIds? })` joins selected direct children, or the current children when omitted, and returns their outcomes. `results` reads the same bounded outcome records without waiting. RPC exposes `subagents.spawn`, `subagents.wait`, and `subagents.results`; `sessions.spawnSubagent` remains a compatibility alias.
|
|
26
|
+
- The model's `spawn_subagent` returns immediately by default; `wait: true` returns an inline result. `wait_subagents` joins selected children. The SDK and standalone terminal share this execution service. Terminal calls use its private control channel, including when connected apps are disabled.
|
|
27
|
+
- Parents receive results at native turn boundaries and join outstanding children before completing. Typed native-history receipts prevent duplicate automatic delivery; explicit waits can reread results. Ownership is recorded before startup so an explicit resume can recover even a lost spawn return. Startup reservations without a run become interrupted outcomes. A restarted Harness never restarts model work automatically. Recovery requires the same recorded account, caller, working folder, and selected history branch. Session IDs are opaque; consumers follow `parentRunId` and `relation`.
|
|
28
|
+
- `providers: false` runs a session with the harness's own tools only.
|
|
29
|
+
- On the caller, `vaultAccess: 'propose'` writes no memory directly, and `recallExcludeAgents` hides those agents' conversations from history and trajectory tools.
|
|
30
|
+
- `maintenanceRunTrigger: false` (a harness option) leaves memory to explicit proposals and scheduled merges.
|
|
31
|
+
|
|
32
|
+
Every session also gets `trajectory_search` and `trajectory_read` from the built-in History plugin.
|
|
33
|
+
Search lists runs in the current data root, including active runs, with filters and a continuation
|
|
34
|
+
cursor. Read returns pages of the canonical execution events, including captured prompt/context,
|
|
35
|
+
tool, decision, retry, compaction, and usage evidence. Active runs show the latest events saved so
|
|
36
|
+
far; settled reads stop at the first outcome. Payloads are bounded and marked when truncated, and
|
|
37
|
+
the tools omit account identifiers, credential fields, attachment bytes, native adapter payloads,
|
|
38
|
+
and provider reasoning text or summaries.
|
|
39
|
+
They report recorded evidence without scoring runs, and do not backfill older records.
|
|
20
40
|
|
|
21
41
|
## Using it from Node
|
|
22
42
|
|
|
@@ -64,9 +84,14 @@ An application adds what it knows through six points:
|
|
|
64
84
|
The harness provides the web tools itself: `webTools({ secrets })` gives `web_search` (Brave Search,
|
|
65
85
|
key read from the secret store) and `web_fetch` (checked reads of public pages). An application
|
|
66
86
|
passes it to `harness.sessions.provide` and switches the names on for each agent.
|
|
87
|
+
`registryTools({ harness })` gives `registry_write` (a skill, rule, or prompt) and `plugin_write`
|
|
88
|
+
(a plugin). Each writes for the calling agent only: the item is on for that agent, and a plugin's
|
|
89
|
+
code is trusted once written. An item others already use goes to the Inbox instead.
|
|
67
90
|
3. **`ToolPolicy`**. `scope` says whether a call is inside what the run may do (or needs one
|
|
68
|
-
approval)
|
|
69
|
-
|
|
91
|
+
approval). A decision with `humanOnly` is for a person alone: the always-approve switch and
|
|
92
|
+
remembered answers do not apply to it. `authorize` says whether the tool is still switched on;
|
|
93
|
+
`approval` adds facts for standing approvals; `connections` narrows the connected apps a session
|
|
94
|
+
reaches.
|
|
70
95
|
4. **`SecretStore`**. Where credentials live (a keychain, a vault). Keys are
|
|
71
96
|
`<account id>/<name>`.
|
|
72
97
|
5. **`Directory`**. Names for the application's ids, shown in what the harness writes.
|
|
@@ -111,8 +136,10 @@ working folder brings.
|
|
|
111
136
|
does nothing. A tool an extension registered is offered to the model and asks before every
|
|
112
137
|
call. A command it registered runs when a message starts with it.
|
|
113
138
|
- **The gate runs last.** In an SDK session it is an inline extension, loaded after those on
|
|
114
|
-
disk
|
|
115
|
-
|
|
139
|
+
disk. A terminal retains its final prepared `--extension` bridge argument; the owned frontend
|
|
140
|
+
loads that bridge as the final trusted inline factory. A plugin that changes a tool call's
|
|
141
|
+
input does so before the gate sees it. Every resource reload revalidates the parent's original
|
|
142
|
+
trusted selection; changed or revoked code requires review and a fresh terminal.
|
|
116
143
|
- **A required part can be extended.** A package names the part it adds to and, optionally, a
|
|
117
144
|
hooks file: `"harness": { "extends": ["memory"], "hooks": "./hooks.mjs" }`. The harness runs
|
|
118
145
|
hooks itself (`src/plugins/hooks.ts`), in its own process, because most memory is written while
|
|
@@ -138,8 +165,8 @@ working folder brings.
|
|
|
138
165
|
- **A person can do the same from a terminal.** In a terminal session, `/plugins` lists what the
|
|
139
166
|
session loads and switches a plugin, or one thing it brings, for the session's project or for
|
|
140
167
|
everyone, and trusts code after showing its files. The session's shell can read the session
|
|
141
|
-
token from its environment, so a change is taken only with a second key that the
|
|
142
|
-
|
|
168
|
+
token from its environment, so a change is taken only with a second key that the trusted
|
|
169
|
+
terminal process claims once (`control.claim`) and shares with its bridge in memory; the socket's
|
|
143
170
|
`plugins.list` is open to the session, and `plugins.attach`, `plugins.detach`, `plugins.trust`
|
|
144
171
|
and `plugins.untrust` refuse without that key. A change applies when the session restarts.
|
|
145
172
|
Outside a session, `xingular-harness plugins list | show | install | remove | update | attach |
|
|
@@ -162,9 +189,10 @@ working folder brings.
|
|
|
162
189
|
one caller, each item attributed to a plugin, with `unattributed` naming any prompt section,
|
|
163
190
|
tool group or tool no plugin accounts for.
|
|
164
191
|
|
|
165
|
-
A terminal session
|
|
166
|
-
`tool-search`, `llama.cpp`).
|
|
167
|
-
|
|
192
|
+
A terminal session can load Pi's four existing builtins (`builtin:mcp`, `codemode`,
|
|
193
|
+
`tool-search`, `llama.cpp`). The Harness resource selection passes enabled builtins by name,
|
|
194
|
+
and the pinned compatibility adapter supplies their implementations to the persistent SDK
|
|
195
|
+
runtime. The separate per-turn SDK execution path does not load these terminal builtins.
|
|
168
196
|
|
|
169
197
|
## Using it from another language
|
|
170
198
|
|
|
@@ -201,7 +229,7 @@ has no knowledge of the application feature that may call it.
|
|
|
201
229
|
`npm run prove` starts that server on a throwaway data root, with no application present, and
|
|
202
230
|
exercises accounts, memory, skills, the prompt, connected apps, and a recorded session.
|
|
203
231
|
|
|
204
|
-
## Run it as a standalone
|
|
232
|
+
## Run it as a standalone Harness terminal
|
|
205
233
|
|
|
206
234
|
After the CLI package is published to npm or your company's npm registry, install and launch it:
|
|
207
235
|
|
|
@@ -210,26 +238,69 @@ npm install --global @xingular/harness
|
|
|
210
238
|
xingular-harness
|
|
211
239
|
```
|
|
212
240
|
|
|
213
|
-
The machine needs Node 22.19 or newer.
|
|
214
|
-
on
|
|
215
|
-
launch,
|
|
241
|
+
The machine needs Node 22.19 or newer. Harness runs its own terminal frontend through the
|
|
242
|
+
active Node runtime on every platform, using its pinned Pi SDK; no separate global `pi`
|
|
243
|
+
installation is required. On first launch, it creates a `Default` isolated account. Use
|
|
244
|
+
`/accounts` or `/login` to sign in.
|
|
216
245
|
|
|
217
|
-
|
|
246
|
+
Provider sign-in progress lives in the running Harness process. An embedding application can call
|
|
247
|
+
`accounts.loginStatus` after reconnecting to recover the current device code or prompt by account;
|
|
248
|
+
the status carries a revision so it can be safely merged with streamed login events. Progress is
|
|
249
|
+
never written to account files, and a completed or cancelled attempt no longer exposes its code.
|
|
250
|
+
|
|
251
|
+
To build and run from a source checkout, use the development command:
|
|
218
252
|
|
|
219
253
|
```sh
|
|
220
254
|
npm install
|
|
221
|
-
npm run
|
|
222
|
-
node dist/cli.js
|
|
255
|
+
npm run dev
|
|
223
256
|
```
|
|
224
257
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
258
|
+
`npm run dev` rebuilds the CLI and opens the Harness terminal in the current working directory.
|
|
259
|
+
It uses the normal Harness data and state directories. Press `/quit` or Ctrl+C to close it.
|
|
260
|
+
For separate development data, pass the usual `--data <dir>` and `--state <dir>` arguments:
|
|
261
|
+
`npm run dev -- --data <dir> --state <dir>`.
|
|
262
|
+
|
|
263
|
+
Building a checkout does not update an existing global `xingular-harness` installation.
|
|
264
|
+
To replace that command with this checkout, run `npm pack`, then install the exact tarball
|
|
265
|
+
filename it prints with `npm install --global ./<tarball-filename>`. This is a local install;
|
|
266
|
+
it does not publish a release. Close an already-running terminal session and launch the command
|
|
267
|
+
again to load the new frontend. A package version alone cannot distinguish an unreleased local
|
|
268
|
+
build from an older installed build with the same version.
|
|
269
|
+
|
|
270
|
+
This opens the Harness-owned terminal frontend in the current working directory. Its
|
|
271
|
+
presentation follows the inspected Oh My Pi 18.11.3 titanium and light palettes, centered welcome,
|
|
272
|
+
colored text statusline and curved `╰─` prompt, with Harness identity and existing capabilities. Harness
|
|
273
|
+
owns screen composition, editing/input dispatch, scrolling, command routing and plugin UI;
|
|
274
|
+
Pi supplies the persistent execution runtime, native history and rich content components.
|
|
275
|
+
The existing isolated account, compiled context, approval gate, telemetry and Wiki/socket
|
|
276
|
+
commands remain behind the terminal. No Pi `InteractiveMode` is constructed.
|
|
277
|
+
|
|
278
|
+
`/resume` stays inside the prepared history and working folder; `/import` accepts an explicitly
|
|
279
|
+
selected native JSONL file only for the same working folder. Cancel an active response before
|
|
280
|
+
changing or reloading a session. Full OMP visual parity is not established by the current
|
|
281
|
+
verification. `/permissions` reviews device-local Pi terminal grants and the Full Permission switch;
|
|
282
|
+
tool grants apply across terminal sessions sharing this Harness state, and Full Permission requires
|
|
283
|
+
confirmation. `/trajectory` opens recorded runs for the current native conversation, with event
|
|
284
|
+
navigation and a detail inspector. See [terminal architecture and evidence](docs/terminal-tui.md),
|
|
285
|
+
[the decision](docs/decisions/ADR-0001-owned-terminal.md), and [third-party notices](NOTICE.md).
|
|
286
|
+
|
|
287
|
+
### `/accounts` in the terminal
|
|
288
|
+
|
|
289
|
+
`/accounts` manages the Pi accounts the same way the app's Accounts screen does: add, rename,
|
|
290
|
+
check, make default, sign in (browser or API key), sign out, remove a provider or an account,
|
|
291
|
+
manage pools, and read the activity log. Each change is made by the person at the terminal; a
|
|
292
|
+
command the model runs in the shell cannot make it.
|
|
293
|
+
|
|
294
|
+
A running session stays on the account it started with. To use another account for this
|
|
295
|
+
session, choose **Use for this session**: the terminal child restarts and the same conversation
|
|
296
|
+
resumes on that account. Removing an account that a running terminal is using is refused. Only
|
|
297
|
+
terminals in this process are counted, so an account used by another running `xingular-harness` window can
|
|
298
|
+
still be removed; that session then asks for another account the next time it starts.
|
|
228
299
|
|
|
229
300
|
The default data and device state directories are `~/.xingular-harness/data` and
|
|
230
301
|
`~/.xingular-harness/state`. Override them with `--data <dir>` and `--state <dir>`. Session
|
|
231
|
-
history is stored per working directory and can be reopened with
|
|
232
|
-
explicit `terminal` command is an alias for the default launch. Use `--help` to see the commands;
|
|
302
|
+
history is stored per working directory and can be reopened with the terminal's `/resume`
|
|
303
|
+
command. The explicit `terminal` command is an alias for the default launch. Use `--help` to see the commands;
|
|
233
304
|
`serve` remains the host-facing RPC service for integrations such as Xingular Agent/App.
|
|
234
305
|
|
|
235
306
|
## Storage
|
|
@@ -239,7 +310,7 @@ explicit `terminal` command is an alias for the default launch. Use `--help` to
|
|
|
239
310
|
wiki/ home.md, library/, projects/<slug>/, facts/, blocks/, revisions, inbox, log
|
|
240
311
|
registry/ skills/, prompts/, rules/ (a person's own; never copied)
|
|
241
312
|
plugins/<name>/ packages kept with a person's data; each is found as an installed plugin
|
|
242
|
-
runs/<id>/ run.json, events.jsonl, context.json, caller.json
|
|
313
|
+
runs/<id>/ run.json, events.jsonl, context.json, caller.json, subagents.json (reserved child IDs)
|
|
243
314
|
config/ context profiles, what is switched on for whom (plugin-attachments.json),
|
|
244
315
|
settings the harness reads
|
|
245
316
|
index.sqlite a rebuildable index of Wiki entries and runs (FTS5)
|
|
@@ -253,6 +324,7 @@ explicit `terminal` command is an alias for the default launch. Use `--help` to
|
|
|
253
324
|
plugin-hooks.json what each hooks file listens for and how its last run went
|
|
254
325
|
connections.json connected apps (secrets are in the SecretStore)
|
|
255
326
|
run/ the session socket and the terminal commands
|
|
327
|
+
harness.log diagnostics from the standalone terminal, kept off its screen
|
|
256
328
|
```
|
|
257
329
|
|
|
258
330
|
The files are the source of truth; `index.sqlite` can be deleted and rebuilt
|
|
@@ -261,14 +333,53 @@ The files are the source of truth; `index.sqlite` can be deleted and rebuilt
|
|
|
261
333
|
## Commands
|
|
262
334
|
|
|
263
335
|
```sh
|
|
264
|
-
npm run typecheck
|
|
265
|
-
npm test # unit tests and the golden prompt/memory fixtures in tests/golden
|
|
336
|
+
npm run ci # typecheck, unit/golden tests, and standalone proof; matches GitHub CI
|
|
266
337
|
npm run build # dist/cli.js (the xingular-harness command) and dist/terminal-pi.js
|
|
267
|
-
npm run prove # the standalone proof above
|
|
268
338
|
```
|
|
269
339
|
|
|
270
|
-
Node 22.
|
|
340
|
+
Node 22.19 or newer.
|
|
271
341
|
|
|
272
342
|
## Images
|
|
273
343
|
|
|
274
344
|
`SessionRunInput.requiresImageInput` optionally requires a vision-capable resolved Pi model before a prompt is delivered. The check includes direct `images` input, and the generic tool wrapper rejects image results on text-only models. Direct prompt images use Pi's `{ type: 'image', data, mimeType }` content shape. Applications own file formats, attachment selection, extraction and image preparation; the Harness only transports typed image content and validates model capability.
|
|
345
|
+
|
|
346
|
+
## Curated Hub
|
|
347
|
+
|
|
348
|
+
`xingular-harness hub list [--refresh]`, `hub show publisher/name@version`, and
|
|
349
|
+
`hub install publisher/name@version` browse and install exact catalog versions. `/hub` offers the
|
|
350
|
+
same review in the interactive terminal, using its private control key for installation. Both the
|
|
351
|
+
terminal and embedding applications use `hub.list`, `hub.get`, `hub.install`, and `hub.readDocument`.
|
|
352
|
+
`hub.get { id, version, preview: true }` verifies data payload bytes without installing them.
|
|
353
|
+
|
|
354
|
+
Registry bundles import complete skills or single Markdown prompts/rules, disabled. Pi packages
|
|
355
|
+
reuse the existing installer and require an exact npm version or full GitHub commit. Documents
|
|
356
|
+
are saved as inert JSON for a compatible host to interpret; the harness does not apply them.
|
|
357
|
+
Installation grants no attachment, trust, credentials, or permission. Writes are serialized and
|
|
358
|
+
existing registry files are never overwritten.
|
|
359
|
+
|
|
360
|
+
Installed documents and provenance live under `<data root>/hub/`; the catalog cache is
|
|
361
|
+
`<state dir>/hub/catalog.json`. An offline snapshot ships with the package. Explicit refresh keeps
|
|
362
|
+
the last valid catalog when the network or schema fails. The prepared public distribution repository
|
|
363
|
+
is `../Hub`; publication remains separate from local installation and testing. Run its build with
|
|
364
|
+
`--sync-harness` to regenerate this package's offline snapshot after reviewing catalog changes.
|
|
365
|
+
|
|
366
|
+
Standalone defaults stay separate from a host application's folders. Use explicit `--data` and
|
|
367
|
+
`--state` to target the same library. CLI hub commands construct the harness without opening the
|
|
368
|
+
data root, so they do not migrate the Wiki or settle another process's runs.
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
## External curation
|
|
372
|
+
|
|
373
|
+
An embedding application may set `externalMaintenance: true`, supply trusted `CallerContext`
|
|
374
|
+
`vaultAccess` (`self` or `curator`), and register `maintenanceTools`/`MAINTENANCE_PLUGIN`.
|
|
375
|
+
Self callers directly edit only their own writable persona/notes; shared knowledge and text-resource
|
|
376
|
+
writes become persistent proposals. Curator tools read original evidence, compare captured target
|
|
377
|
+
revisions, read all host-assigned requests together, and apply reconciled Wiki proposals as one
|
|
378
|
+
undoable change set. Resource proposals keep their own receipts; executable proposals remain inert
|
|
379
|
+
until the user reviews/trusts them. Later user edits are never overwritten.
|
|
380
|
+
`maintenance.list`, `maintenance.review` and `maintenance.retry` let the host dispatch its own
|
|
381
|
+
recorded sessions. Curator runs do not recursively queue maintenance. Optional assigned IDs freeze
|
|
382
|
+
which requests a batch may claim. These fields are trusted host context, never model arguments.
|
|
383
|
+
`maintenance_read_batch` reads those assigned requests together; `maintenance_apply_batch` records
|
|
384
|
+
one decision for each and applies the evidence-checked Wiki set atomically. Standalone callers that
|
|
385
|
+
omit this option retain the existing lifecycle and direct-write contract.
|