@xingular/harness 2.1.2 → 3.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 +12 -0
- package/NOTICE.md +22 -0
- package/README.md +67 -36
- package/dist/cli.js +6023 -6621
- package/dist/terminal-pi.js +19 -24
- package/docs/terminal-tui.md +27 -7
- package/package.json +2 -2
- package/src/accounts/accounts.ts +4 -3
- package/src/capabilities/api.ts +1 -1
- package/src/cli.ts +7 -3
- package/src/core/caller.ts +34 -0
- package/src/core/fs.ts +17 -1
- package/src/harness.ts +55 -66
- package/src/{memory → history}/recall.test.ts +1 -1
- package/src/{memory → history}/recall.ts +1 -1
- package/src/{memory → history}/trajectory.test.ts +4 -4
- package/src/{memory → history}/trajectory.ts +1 -1
- package/src/hub/hub.test.ts +4 -5
- package/src/hub/hub.ts +2 -2
- package/src/index.ts +28 -14
- package/src/mcp/connections.ts +1 -1
- package/src/mcp/service.ts +1 -1
- package/src/pi/proxy.test.ts +68 -0
- package/src/pi/runtime.test.ts +61 -0
- package/src/pi/runtime.ts +50 -0
- package/src/plugins/api.ts +11 -9
- package/src/plugins/builtin.ts +22 -40
- package/src/plugins/catalogue.test.ts +13 -41
- package/src/plugins/catalogue.ts +3 -32
- package/src/plugins/discover.ts +2 -1
- package/src/plugins/firstParty.test.ts +1 -1
- package/src/plugins/hooks.test.ts +21 -71
- package/src/plugins/hooks.ts +6 -7
- package/src/plugins/identity.ts +16 -2
- package/src/plugins/install.test.ts +1 -1
- package/src/plugins/install.ts +2 -1
- package/src/plugins/inventory.ts +19 -18
- package/src/plugins/plugins.ts +38 -2
- package/src/prompt/compile.test.ts +82 -193
- package/src/prompt/compile.ts +98 -363
- package/src/refine/cli.ts +114 -0
- package/src/refine/demo.ts +124 -0
- package/src/refine/evidence.ts +349 -0
- package/src/refine/host.ts +102 -0
- package/src/refine/ledger.ts +104 -0
- package/src/refine/library.ts +192 -0
- package/src/refine/pi.test.ts +90 -0
- package/src/refine/pi.ts +218 -0
- package/src/refine/prompts.ts +430 -0
- package/src/refine/recursion.ts +353 -0
- package/src/refine/refine.test.ts +140 -0
- package/src/refine/runner.ts +205 -0
- package/src/refine/selection.ts +291 -0
- package/src/refine/service.ts +194 -0
- package/src/refine/trajectory.ts +71 -0
- package/src/refine/types.ts +91 -0
- package/src/server/methods.ts +137 -123
- package/src/server/server.test.ts +37 -30
- package/src/sessions/contracts.ts +6 -1
- package/src/sessions/conversation.test.ts +2 -27
- package/src/sessions/policy.ts +1 -1
- package/src/sessions/pricing.ts +3 -1
- package/src/sessions/registry.ts +5 -1
- package/src/sessions/runStore.ts +3 -1
- package/src/sessions/runner.ts +10 -5
- package/src/sessions/sessions.test.ts +45 -6
- package/src/sessions/sessions.ts +40 -17
- package/src/sessions/subagentService.test.ts +22 -1
- package/src/sessions/subagentService.ts +14 -1
- package/src/sessions/subagents.ts +2 -0
- package/src/terminal/cli.ts +24 -48
- package/src/terminal/pluginControl.test.ts +7 -8
- package/src/terminal/socket.ts +3 -3
- package/src/terminal/terminal.test.ts +21 -39
- package/src/terminal/terminals.ts +20 -13
- package/src/terminal/tui/application.test.ts +58 -0
- package/src/terminal/tui/application.ts +10 -4
- package/src/terminal/tui/clipboardFiles.test.ts +94 -0
- package/src/terminal/tui/clipboardFiles.ts +86 -0
- package/src/terminal/tui/piAdapter.ts +7 -4
- package/src/terminal/tui/runtime.ts +2 -0
- package/src/tools/definitions.ts +49 -132
- package/src/tools/dispatch.ts +78 -0
- package/src/tools/harnessTools.ts +23 -0
- package/src/tools/spawnSubagent.ts +3 -3
- package/src/tools/types.ts +1 -1
- package/src/tree/components.ts +221 -0
- package/src/tree/materialise.ts +122 -0
- package/src/tree/seed.ts +123 -0
- package/src/tree/store.ts +193 -0
- package/src/tree/surface.ts +135 -0
- package/src/tree/tree.test.ts +126 -0
- package/src/tree/tree.ts +346 -0
- package/src/tree/trust.ts +86 -0
- package/src/wiki/notes.ts +313 -0
- package/src/memory/api.test.ts +0 -82
- package/src/memory/api.ts +0 -303
- package/src/memory/blocks.test.ts +0 -78
- package/src/memory/blocks.ts +0 -408
- package/src/memory/caller.ts +0 -69
- package/src/memory/curation.test.ts +0 -206
- package/src/memory/curation.ts +0 -64
- package/src/memory/dispatch.ts +0 -64
- package/src/memory/facts.test.ts +0 -41
- package/src/memory/facts.ts +0 -248
- package/src/memory/graph.ts +0 -103
- package/src/memory/health.test.ts +0 -130
- package/src/memory/health.ts +0 -74
- package/src/memory/maintainer.ts +0 -272
- package/src/memory/maintenance.test.ts +0 -192
- package/src/memory/maintenance.ts +0 -679
- package/src/memory/migrate.ts +0 -79
- package/src/memory/operations.ts +0 -150
- package/src/memory/proposals.test.ts +0 -168
- package/src/memory/proposals.ts +0 -584
- package/src/memory/references.ts +0 -77
- package/src/memory/runContext.ts +0 -93
- package/src/memory/store.test.ts +0 -66
- package/src/memory/store.ts +0 -385
- package/src/memory/wiki.test.ts +0 -47
- package/src/memory/wiki.ts +0 -423
- package/src/memory/wikiIndex.test.ts +0 -88
- package/src/memory/wikiIndex.ts +0 -117
- package/src/plugins/proposal.ts +0 -121
- package/src/skills/registry.test.ts +0 -104
- package/src/skills/registry.ts +0 -413
- package/src/tools/maintenance.ts +0 -29
- package/src/tools/memoryTools.ts +0 -22
- package/src/tools/pluginPropose.ts +0 -41
- package/src/tools/registryWrite.test.ts +0 -101
- package/src/tools/registryWrite.ts +0 -182
- /package/src/{memory → core}/secrets.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 3.0.0 - 2026-10-19
|
|
6
|
+
|
|
7
|
+
Rebuilt on recursive harnessing (Harness², Apache-2.0, Google LLC). Breaking.
|
|
8
|
+
|
|
9
|
+
- Add harness trees (`src/tree/`): each caller scope has a versioned tree of eight components — system prompt, guardrails, memory, tool guidance, subagents, skills, scripts and plugins — that is validated, content-addressed, and pinned for a whole run. `SessionRunInput.harness` and `TerminalPrepareInput.harness` choose one; run records carry `harnessScope` and `harnessVersion`. Plugin code in a tree loads only after it is trusted (`TreeTrust`).
|
|
10
|
+
- Add refinement (`src/refine/`): Propose–Probe–Compose in parallel and sequential modes with the R=4k/P=3k budget identity, blind answer-free selection, reflection into a per-scope experience library, and adoption of the chosen tree. Executions and improver sessions are ordinary recorded runs, marked by the `probe` and `improver` triggers. `harness.refine`, `refine.*` and `library.*` RPC methods, and `xingular-harness refine demo|run`.
|
|
11
|
+
- Add the seventh extension point, `RefineHost`: where an execution works, as whom, with which tools, and what it produced.
|
|
12
|
+
- `spawn_subagent` takes `agent`, naming one of the tree's subagents; that child works from its own definition.
|
|
13
|
+
- Replace the Wiki with project notes (`src/wiki/`): linked Markdown under `wiki/`, versions, search, and `wiki_search`, `wiki_read`, `wiki_list` and a switchable `wiki_write`. An earlier Wiki's memory blocks, facts, revisions and Inbox are moved once to `legacy/wiki-<time>/`; nothing is deleted.
|
|
14
|
+
- Remove memory blocks, facts, proposals and the evidence gate, maintenance and the maintainer, curation, context profiles, the skills/rules/prompts registry as a source of prompt text, `registry_write`, `plugin_write` and `plugin_propose`. `harnesses.seed` builds a caller's first tree from what shaped it before (instructions, its rules, its memory blocks, its skills). `registry/` stays as a component library the Hub installs into and a tree can take items from.
|
|
15
|
+
- Hook events are `wiki.page.saved` and `history.run.ended`.
|
|
16
|
+
|
|
5
17
|
## 2.1.2 - 2026-10-19
|
|
6
18
|
|
|
7
19
|
- Add `/log`, a full-screen snapshot of redacted Harness diagnostics and current-conversation run events.
|
package/NOTICE.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Third-party notices
|
|
2
2
|
|
|
3
|
+
## Harness²
|
|
4
|
+
|
|
5
|
+
The harness tree (`src/tree/`) and refinement (`src/refine/`) port the method of Harness²:
|
|
6
|
+
Recursive Agent Harnessing for an Open World (Xu, Chen, CuiZhu, Dalvi Mishra, Ming, Yu, Han,
|
|
7
|
+
Lee, Pfister; arXiv:2610.14224). The component surface and its validation, Propose–Probe–Compose
|
|
8
|
+
in parallel and sequential modes with its budget identity, blind answer-free selection, the
|
|
9
|
+
reflection record and the experience library, and the improver, selector and reflector prompts
|
|
10
|
+
are adapted from its reference implementation (`harness2/core`, `harness2/substrate`) for Pi.
|
|
11
|
+
|
|
12
|
+
Upstream: https://github.com/google-research/harness2 (Copyright 2026 Google LLC)
|
|
13
|
+
|
|
14
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files
|
|
15
|
+
except in compliance with the License. You may obtain a copy of the License at
|
|
16
|
+
https://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in
|
|
17
|
+
writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
18
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Changes from upstream: ported
|
|
19
|
+
from Python to TypeScript; the OpenCode and Codex surfaces replaced by one Pi surface; executors
|
|
20
|
+
and improvers run as recorded harness sessions; benchmark adapters replaced by a host-supplied
|
|
21
|
+
`RefineHost`; prompt text that named a framework rewritten for Pi.
|
|
22
|
+
|
|
23
|
+
## Oh My Pi
|
|
24
|
+
|
|
3
25
|
The Harness terminal presentation adapts the titanium color palette, five-row Pi logo,
|
|
4
26
|
diagonal gradient and related terminal presentation conventions from Oh My Pi 18.11.3,
|
|
5
27
|
particularly `@oh-my-pi/pi-tui/src/theme/defaults/titanium.json` and
|
package/README.md
CHANGED
|
@@ -1,22 +1,38 @@
|
|
|
1
1
|
# Xingular Harness
|
|
2
2
|
|
|
3
|
-
A Pi agent harness
|
|
4
|
-
|
|
3
|
+
A Pi agent harness built on **recursive harnessing** ([Harness²](https://arxiv.org/abs/2610.14224),
|
|
4
|
+
Apache-2.0, Google LLC), as one TypeScript package (`@xingular/harness`). The harness — what a
|
|
5
|
+
model is told and can do — is the object that improves, with model weights fixed:
|
|
6
|
+
|
|
7
|
+
- **A harness is a tree of eight components** (c1–c8): system prompt, guardrails, memory and tool
|
|
8
|
+
guidance (always in the prompt, capped), subagents, skills and scripts (on demand), and plugins
|
|
9
|
+
(in the tool loop). Each caller scope has versioned, validated trees; a run pins one version.
|
|
10
|
+
- **Task-level recursion** refines a tree on one task through *Propose–Probe–Compose*: k base
|
|
11
|
+
executions, improvers that edit the tree from the evidence (INV: how the agent works; DOM: what a
|
|
12
|
+
practitioner knows), a probe execution of each candidate, and compositions built from the
|
|
13
|
+
behavioural contrasts. Parallel mode explores wider; sequential mode refines deeper. Each costs
|
|
14
|
+
4k executions and 3k improver sessions.
|
|
15
|
+
- **Blind, answer-free selection** picks one final output from anonymised candidates; no rubric,
|
|
16
|
+
score or reviewer verdict ever reaches an improver.
|
|
17
|
+
- **Harnessing-level recursion** keeps an experience library per scope: each adopted tree with
|
|
18
|
+
what each edit did and one evidence-backed lesson, read by the next task's improvers.
|
|
5
19
|
|
|
6
20
|
| Part | Folder | What it does |
|
|
7
21
|
|---|---|---|
|
|
22
|
+
| Harness trees | `src/tree/` | The eight-component surface, validation and repair, content-addressed versions and lineage, materialising a tree for Pi, plugin-code trust, seeding a first tree, the component library. |
|
|
23
|
+
| Refinement | `src/refine/` | Evidence folders, the prompt pack, parallel and sequential recursion, the budget ledger, selection, reflection, the experience library, Pi-backed executor and improver, and the `refine` service. |
|
|
8
24
|
| 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
|
-
| Sessions | `src/sessions/` | Pi SDK turns, run records and `events.jsonl`, interrupt, approvals, questions, recovery after a crash. |
|
|
10
|
-
| Prompt | `src/prompt/` | The system prompt compiled from sections with budgets
|
|
11
|
-
|
|
|
12
|
-
|
|
|
25
|
+
| Sessions | `src/sessions/` | Pi SDK turns on a pinned harness tree, run records and `events.jsonl`, interrupt, approvals, questions, subagents (named by a tree's c5), recovery after a crash. |
|
|
26
|
+
| Prompt | `src/prompt/` | The system prompt compiled from the tree's sections and the application's, with budgets; a stable prefix, and changing state delivered as updates in native history. |
|
|
27
|
+
| Wiki | `src/wiki/` | Project notes: linked Markdown, versions, search. Reference material, not instructions. |
|
|
28
|
+
| History | `src/history/` | Recall over earlier runs and bounded trajectory reads. |
|
|
13
29
|
| 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
|
-
| Tools | `src/tools/` | Tool definitions,
|
|
30
|
+
| Tools | `src/tools/` | Tool definitions, History/Wiki/skill tools, `ask_user`; a gate that asks the application's policy, then standing approvals, then the person. |
|
|
15
31
|
| Connected apps | `src/mcp/` | MCP connections, OAuth, per-session grants, redaction, a trace of what each call returned. |
|
|
16
|
-
| Terminal | `src/terminal/` | A Harness-owned terminal frontend over persistent Pi sessions
|
|
32
|
+
| Terminal | `src/terminal/` | A Harness-owned terminal frontend over persistent Pi sessions on a harness tree. |
|
|
17
33
|
| Server | `src/server/` | The same API over newline-delimited JSON, for a host that is not a Node program. |
|
|
18
34
|
|
|
19
|
-
|
|
35
|
+
Try refinement with no model and no credentials: `npm run build && node dist/cli.js refine demo --k 2`.
|
|
20
36
|
The [documentation index](docs/README.md) links current terminal architecture and decisions.
|
|
21
37
|
|
|
22
38
|
### Session options for applications
|
|
@@ -26,8 +42,9 @@ The [documentation index](docs/README.md) links current terminal architecture an
|
|
|
26
42
|
- 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
43
|
- 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
44
|
- `providers: false` runs a session with the harness's own tools only.
|
|
29
|
-
-
|
|
30
|
-
-
|
|
45
|
+
- `harness: { scope }` runs the session on that scope's head tree (or `{ scope, version }`, or `{ dir }` for a tree on disk). The version is pinned for the run and recorded on it.
|
|
46
|
+
- On the caller, `recallExcludeAgents` hides those agents' conversations from history and trajectory tools.
|
|
47
|
+
- `harnessTools: false` runs a session without the History, Wiki and skill tools.
|
|
31
48
|
|
|
32
49
|
Every session also gets `trajectory_search` and `trajectory_read` from the built-in History plugin.
|
|
33
50
|
Search lists runs in the current data root, including active runs, with filters and a continuation
|
|
@@ -44,16 +61,19 @@ They report recorded evidence without scoring runs, and do not backfill older re
|
|
|
44
61
|
import { createHarness } from '@xingular/harness'
|
|
45
62
|
|
|
46
63
|
const harness = createHarness({
|
|
47
|
-
dataRoot: '/path/to/data', //
|
|
64
|
+
dataRoot: '/path/to/data', // harnesses/, library/, refine/, wiki/, registry/, runs/, index.sqlite
|
|
48
65
|
stateDir: '/path/to/state', // device-local: accounts, approvals, connections, sockets
|
|
49
66
|
productName: 'My App', // how the harness names itself to a model (default 'Xingular Harness')
|
|
50
67
|
secrets, // SecretStore; defaults to an owner-only file in stateDir
|
|
51
68
|
policy, // ToolPolicy: what a run may do, and what needs a person
|
|
52
69
|
directory, // names for the ids the application uses
|
|
53
70
|
builtins: ['/path/to/builtin'], // folders of built-in skills, prompts, and rules
|
|
54
|
-
plugins: [myPlugin]
|
|
71
|
+
plugins: [myPlugin], // the application's own parts, described as plugins
|
|
72
|
+
refineHost // where refinement executions work, as whom, with which tools
|
|
55
73
|
})
|
|
56
74
|
|
|
75
|
+
harness.refine.start({ task: { id, scope: 'agent-1', prompt }, k: 1, mode: 'parallel' })
|
|
76
|
+
|
|
57
77
|
harness.sessions.provide((session) => myTools(session)) // the application's own tools
|
|
58
78
|
harness.runs.listen((event, run) => show(event)) // every run event, after it is saved
|
|
59
79
|
|
|
@@ -61,6 +81,7 @@ await harness.sessions.run({
|
|
|
61
81
|
run: { id, sessionId },
|
|
62
82
|
cwd, sessionDir, text,
|
|
63
83
|
caller: { agentId, agentName, actor: 'Chat' },
|
|
84
|
+
harness: { scope: 'agent-1' },
|
|
64
85
|
launch: { sections: [{ id: 'identity', title: 'Identity', body, budget: 2000, order: 10 }] },
|
|
65
86
|
tools: { allow: ['read', 'bash', 'my_tool'], gated: ['bash'] }
|
|
66
87
|
})
|
|
@@ -68,14 +89,14 @@ await harness.sessions.run({
|
|
|
68
89
|
|
|
69
90
|
## How an application extends it
|
|
70
91
|
|
|
71
|
-
The harness knows a caller
|
|
72
|
-
An application adds what it knows through
|
|
92
|
+
The harness knows a caller and a harness scope (opaque ids), never an agent, a group, or a task.
|
|
93
|
+
An application adds what it knows through seven points:
|
|
73
94
|
|
|
74
95
|
1. **Prompt sections** (`Launch.sections`, `Launch.toolGroups`, `Launch.references`). Each
|
|
75
|
-
section has an `order` and may be `dynamic`. The harness adds its own (`
|
|
76
|
-
`
|
|
77
|
-
|
|
78
|
-
updates.
|
|
96
|
+
section has an `order` and may be `dynamic`. The harness adds its own (`system` 25,
|
|
97
|
+
`guardrails` 40, `memory` 45, `references` 50, `subagents` 64, `scripts` 66, `wiki` 80,
|
|
98
|
+
`tools` 90), applies budgets, keeps stable sections in the system prompt, and sends dynamic
|
|
99
|
+
ones as updates.
|
|
79
100
|
2. **Tool providers** (`harness.sessions.provide`). A provider returns `ToolSpec`s for a session;
|
|
80
101
|
only the names in the session's `allow` list are registered, in that order.
|
|
81
102
|
A tool may return `attachments` as `{ id, name, mimeType }` references. The harness records
|
|
@@ -84,9 +105,6 @@ An application adds what it knows through six points:
|
|
|
84
105
|
The harness provides the web tools itself: `webTools({ secrets })` gives `web_search` (Brave Search,
|
|
85
106
|
key read from the secret store) and `web_fetch` (checked reads of public pages). An application
|
|
86
107
|
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.
|
|
90
108
|
3. **`ToolPolicy`**. `scope` says whether a call is inside what the run may do (or needs one
|
|
91
109
|
approval). A decision with `humanOnly` is for a person alone: the always-approve switch and
|
|
92
110
|
remembered answers do not apply to it. `authorize` says whether the tool is still switched on;
|
|
@@ -99,6 +117,11 @@ An application adds what it knows through six points:
|
|
|
99
117
|
the application and says which tools, prompt sections and tool groups it provides. It is data:
|
|
100
118
|
it changes what `plugins.list` and `plugins.inventory` report, never what runs. `WEB_PLUGIN`
|
|
101
119
|
describes the web tools. A host that is not a Node program sends them with `plugins.describe`.
|
|
120
|
+
7. **`RefineHost`** (`HarnessOptions.refineHost`). Where a refinement execution works
|
|
121
|
+
(`prepareWorkspace`: an isolated folder, such as a git worktree), as whom and with which tools
|
|
122
|
+
(`session`), and what it produced (`deliverable`). Executions run as unattended runs with
|
|
123
|
+
trigger `probe`, so a `ToolPolicy` can refuse anything with effects outside that folder;
|
|
124
|
+
improver sessions run with trigger `improver`, file tools only, on a copy of the evidence.
|
|
102
125
|
|
|
103
126
|
`apps.expose(...)` additionally offers the application's tools through the connected-apps
|
|
104
127
|
broker (`mcp_list_tools`, `mcp_call_tool`), which is how a terminal session reaches them.
|
|
@@ -107,7 +130,7 @@ broker (`mcp_list_tools`, `mcp_call_tool`), which is how a terminal session reac
|
|
|
107
130
|
|
|
108
131
|
A plugin is a bundle with a title, a description and contributions: instructions, skills,
|
|
109
132
|
commands, tools, connections, code (a Pi extension) and themes. A Pi package is a plugin as it
|
|
110
|
-
is; so are the harness's own parts (
|
|
133
|
+
is; so are the harness's own parts (Harness, Wiki, History, Subagents, Ask the user, Connected apps, Pi), the
|
|
111
134
|
application's, a person's registry ("Yours"), the folder every account shares, and what a
|
|
112
135
|
working folder brings.
|
|
113
136
|
|
|
@@ -141,11 +164,10 @@ working folder brings.
|
|
|
141
164
|
input does so before the gate sees it. Every resource reload revalidates the parent's original
|
|
142
165
|
trusted selection; changed or revoked code requires review and a fresh terminal.
|
|
143
166
|
- **A required part can be extended.** A package names the part it adds to and, optionally, a
|
|
144
|
-
hooks file: `"harness": { "extends": ["
|
|
145
|
-
hooks itself (`src/plugins/hooks.ts`), in its own process, because
|
|
146
|
-
no session is open. `export default function (harness) { harness.on('
|
|
147
|
-
(event, ctx) => …) }`; the events are `
|
|
148
|
-
`wiki.page.saved` and `history.run.ended`. A hook is told after the write and cannot stop it,
|
|
167
|
+
hooks file: `"harness": { "extends": ["wiki"], "hooks": "./hooks.mjs" }`. The harness runs
|
|
168
|
+
hooks itself (`src/plugins/hooks.ts`), in its own process, because notes are often written while
|
|
169
|
+
no session is open. `export default function (harness) { harness.on('wiki.page.saved', async
|
|
170
|
+
(event, ctx) => …) }`; the events are `wiki.page.saved` and `history.run.ended`. A hook is told after the write and cannot stop it,
|
|
149
171
|
has 30 seconds, and what it throws is kept in `plugin-hooks.json` and shown on its plugin. It
|
|
150
172
|
runs only while its plugin is switched on for everyone and trusted; what is loaded is checked
|
|
151
173
|
against that before each delivery. `ctx.call(connection, tool, args)` reaches a connected app
|
|
@@ -172,7 +194,8 @@ working folder brings.
|
|
|
172
194
|
Outside a session, `xingular-harness plugins list | show | install | remove | update | attach |
|
|
173
195
|
detach | trust | untrust` acts directly, as the person who typed it; `trust` shows the files
|
|
174
196
|
and wants a typed yes or `--yes`. It does not open the data root, so it settles no run.
|
|
175
|
-
- **Unattended runs
|
|
197
|
+
- **Unattended runs load no extension found on disk.** A harness tree's own trusted plugins still
|
|
198
|
+
load, so a refinement probe runs the plugin it is testing.
|
|
176
199
|
- **A person switches things on and off for a scope.** `plugins.attach` and `plugins.detach`
|
|
177
200
|
take a plugin's or a contribution's `id` and a `scope` (`{}` for everywhere, `{ agentId }`, or
|
|
178
201
|
`{ projectId }`). The narrowest scope that says something wins: an agent, then a project, then
|
|
@@ -216,7 +239,8 @@ table. With the `--host-*` flags the harness calls the host for `secrets.get|set
|
|
|
216
239
|
`policy.scope|authorize|approval|connections`, and `tools.call`; the host registers its tools
|
|
217
240
|
with `tools.register` and its names with `directory.set`.
|
|
218
241
|
|
|
219
|
-
`
|
|
242
|
+
`harnesses.importComponents` adds complete skill folders, or single-file rules and prompts, to the
|
|
243
|
+
component library:
|
|
220
244
|
|
|
221
245
|
```ts
|
|
222
246
|
{ skills: [{ name, files: [{ path, content, encoding }] }] }
|
|
@@ -227,7 +251,8 @@ It validates bounded relative paths and file encodings, requires a root
|
|
|
227
251
|
has no knowledge of the application feature that may call it.
|
|
228
252
|
|
|
229
253
|
`npm run prove` starts that server on a throwaway data root, with no application present, and
|
|
230
|
-
exercises accounts,
|
|
254
|
+
exercises accounts, harness trees, the Wiki, the prompt, connected apps, a recorded session, a
|
|
255
|
+
plugin hook, and the refinement demo end to end.
|
|
231
256
|
|
|
232
257
|
## Run it as a standalone Harness terminal
|
|
233
258
|
|
|
@@ -309,19 +334,25 @@ command. The explicit `terminal` command is an alias for the default launch. Use
|
|
|
309
334
|
|
|
310
335
|
```
|
|
311
336
|
<data root>/
|
|
312
|
-
|
|
313
|
-
|
|
337
|
+
harnesses/<scope>/ versions/<fingerprint>/tree/, head.json, lineage.jsonl (the eight components)
|
|
338
|
+
refine/<id>/ summary.json, task.json, harnesses/<label>/, rollouts/, context/, selection/, reflection/, improver/
|
|
339
|
+
library/<scope>/<area>/ INDEX.md, harnesses/<task>/{harness/, EXPERIENCE.md} (the experience library)
|
|
340
|
+
wiki/ home.md, library/, projects/<slug>/ (project notes)
|
|
341
|
+
wiki-history/ earlier versions of notes
|
|
342
|
+
legacy/ what an earlier Wiki kept (memory blocks, facts, revisions, Inbox), moved once
|
|
343
|
+
registry/ skills/, prompts/, rules/ (the component library; the Hub installs here)
|
|
314
344
|
plugins/<name>/ packages kept with a person's data; each is found as an installed plugin
|
|
315
345
|
runs/<id>/ run.json, events.jsonl, context.json, caller.json, subagents.json (reserved child IDs)
|
|
316
|
-
config/
|
|
346
|
+
config/ what is switched on for whom (plugin-attachments.json),
|
|
317
347
|
settings the harness reads
|
|
318
|
-
index.sqlite a rebuildable index of
|
|
348
|
+
index.sqlite a rebuildable index of runs for recall (FTS5)
|
|
319
349
|
projects.json read only: the application owns it
|
|
320
350
|
|
|
321
351
|
<state dir>/
|
|
322
352
|
accounts/ registry, per-account Pi agent folders, audit log
|
|
323
353
|
approvals.json standing approvals
|
|
324
354
|
plugin-trust.json the code a person trusted, by hash, and whether earlier packages were taken over
|
|
355
|
+
tree-plugin-trust.json harness-tree plugin code a person trusted, and scopes whose probes may run improver code
|
|
325
356
|
plugin-registered.json what each extension registered the last time a session loaded it
|
|
326
357
|
plugin-hooks.json what each hooks file listens for and how its last run went
|
|
327
358
|
connections.json connected apps (secrets are in the SecretStore)
|
|
@@ -343,7 +374,7 @@ Node 22.19 or newer.
|
|
|
343
374
|
|
|
344
375
|
## Images
|
|
345
376
|
|
|
346
|
-
`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
|
|
377
|
+
`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 attachment selection, extraction and image preparation; the Harness transports typed image content and validates model capability. In the standalone terminal, pasting Finder-copied HEIC/HEIF files on macOS converts them to temporary PNGs so Pi can read their pixels. See [the terminal guide](docs/terminal-tui.md#clipboard-image-paste).
|
|
347
378
|
|
|
348
379
|
## Curated Hub
|
|
349
380
|
|