@falari/harness 0.0.0-stage → 0.8.10

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
@@ -1,3 +1,220 @@
1
- # Temporary Holding Version
1
+ # Falari Harness
2
+
3
+ Falari Data client for **DeepSeek Harness** (DSH): upload files to Falari
4
+ storage and download them back, with an Agent Key as the only credential. The
5
+ same six operations are exposed to the model as tools and to the user as a
6
+ panel.
7
+
8
+ - Design and milestone log: [docs/plan.md](docs/plan.md)
9
+ - Test plan: [docs/test-plan.md](docs/test-plan.md)
10
+ - Release notes: [CHANGELOG.md](CHANGELOG.md)
11
+
12
+ The plugin wears the Falari mark: `icon.png` is the rendered logo with a
13
+ transparent background for the plugin list; the panel header shows the original
14
+ render (dark backdrop, cropped to the cube); the sidebar draws crisp vector art
15
+ so the `>_` survives at 20 px.
16
+
17
+ ## Status
18
+
19
+ | Phase | Scope | State |
20
+ |---|---|---|
21
+ | M0 | Bundle scaffold, install, panel/settings placeholders | done — installed in the `desktop` profile (2026-11-09) |
22
+ | M1 | Agent Key storage, `falari_status` tool, settings page | done (v0.2.0) |
23
+ | M2 | Quotes, upload queue, upload panel, `falari_quote` / `falari_upload` / `falari_task` | done (v0.3.0) |
24
+ | M3 | Intent list, download/decrypt, `falari_list` / `falari_download` | done (v0.4.0) |
25
+ | M4 | Editable settings, unit tests, test plan | done (v0.5.0); live acceptance pending a testnet key |
26
+ | M5 | Repository layout, changelog, license, manifest check | done (v0.5.0) |
27
+
28
+ Live-chain verification still needs a real testnet Agent Key: the settings page
29
+ and every route/tool path are covered by the offline smoke tests, but nothing
30
+ here has performed a paid upload against the testnet yet.
31
+
32
+ The full design is in [docs/plan.md](docs/plan.md).
33
+
34
+ ## Project
35
+
36
+ - Developer: **falari_labs**
37
+ - Website: <https://falari.xyz>
38
+ - Package: `@falari/harness`
39
+
40
+ ## Install (development)
41
+
42
+ Open **Plugins → Add** in DeepSeek Harness and point it at this directory, or
43
+ from an agent session call the plugin manager tool:
44
+
45
+ ```text
46
+ plugin_manager action=install_bundle target=/path/to/clients/harness
47
+ ```
48
+
49
+ The bundle is installed as a local link (`link:...`). For a release build use
50
+ `plugin_manager action=install_bundle target=@falari/harness@0.8.9`. Host code changes need the
51
+ plugin row to reload (toggle the bundle off/on, or restart DSH); client code
52
+ changes need a page refresh.
53
+
54
+ Storage duration can be a preset (permanent / 30d / 90d / 1y / 5y / 10y) or any
55
+ custom term in days, months or years. Fees follow the chain's `RequiredFee`:
56
+ whole days rounded up, minimum one day, and any term past 36 years is charged the
57
+ permanent price instead of growing forever.
58
+
59
+ Cancelling an upload opens a confirmation dialog with the refund breakdown
60
+ (escrow, cancellation rate, withheld compensation, terminate service fee, amount
61
+ returned) read from the chain before anything is signed.
62
+
63
+ Status reads are cached: the Host answers from `<dataDir>/status-cache.json` and
64
+ refreshes the chain in the background (a 15 s window), and the panel keeps its own
65
+ `localStorage` copy so the card renders before the first request returns.
66
+
67
+ The Agent Key is stored **encrypted under a PIN**, never in clear text: scrypt
68
+ derives the AES-256-GCM key from the PIN, the decrypted key lives only in memory,
69
+ and the panel locks it on demand or after `lockIdleMinutes` of inactivity
70
+ (default 60, presets or any value from 0 to 10080 minutes). A plugin row reload
71
+ keeps the unlock while the process lives. A
72
+ profile that already holds a plaintext key is flagged and re-sealed in place.
73
+
74
+ The Agent Key and the storage defaults are configured in the plugin itself, never
75
+ in the global Settings dialog:
76
+
77
+ - **Falari Data panel → Settings tab** — always available, whatever the plugin
78
+ page renders.
79
+ - **Plugins → Falari Data** — the bundle page card, or the row's **Configure**
80
+ control, driven by the `plugins.bundle.config` / `plugins.row.config` slots.
81
+ Both may take a browser refresh to appear after an install.
82
+
83
+ ## Configuration
84
+
85
+ The row accepts an optional `config` block (defaults shown). Put overrides in the
86
+ profile patch:
87
+
88
+ ```yaml
89
+ - id: falari-harness
90
+ name: '@falari/harness'
91
+ config:
92
+ network: testnet # testnet | mainnet (mainnet is not live yet)
93
+ defaultPrivacy: public # public | private
94
+ defaultDuration: permanent # permanent | 30d | 90d | 1y | 5y | 10y
95
+ maxFileSizeBytes: 2147483648
96
+ allowUploadOutsideWorkspace: false
97
+ allowRemoteRoutes: false # keep the panel routes on loopback only
98
+ # gatewayUrl / retrievalUrl / explorerUrl override the network presets
99
+ # timeoutMs defaults to 60000
100
+ # dataDir defaults to <DSH_PROFILE_DIR>/falari-harness
101
+ ```
102
+
103
+ The Agent Key is **not** configuration: it lives in the DSH credential store as
104
+ the record `falari-harness/agent-key`.
105
+
106
+ ## Tools
107
+
108
+ | Tool | Purpose |
109
+ |---|---|
110
+ | `falari_status` | Key state, tiers, allowance, balance, miners (`refresh: true` bypasses the cache) |
111
+ | `falari_quote` | Price an upload (`path` or `size_bytes`) and check the budget |
112
+ | `falari_upload` | Queue a workspace file; `wait: true` waits up to two minutes |
113
+ | `falari_task` | Read one task or the recent list |
114
+ | `falari_list` | This account's intents, newest first |
115
+ | `falari_download` | Download one intent, verify roots, decrypt when private |
116
+
117
+ The plugin configuration page writes these values back through the profile's
118
+ config editor, so saving restarts the plugin row.
119
+
120
+ Agent uploads are restricted to the Session working directory unless
121
+ `allowUploadOutsideWorkspace` is enabled. Files the user picks in the panel are
122
+ not subject to that guard.
123
+
124
+ ## Build
125
+
126
+ The Host half bundles the unpublished Falari SDK (`@falari/agent`) and the
127
+ precompiles package into `lib/falari-sdk.cjs`, so installing the bundle needs no
128
+ npm package for them:
129
+
130
+ ```sh
131
+ npm run build:sdk
132
+ ```
133
+
134
+ Run this after pulling a newer `sdk/sdk-agent-ts`.
135
+
136
+ ## Repository
137
+
138
+ The project lives in this directory and is published as the npm package
139
+ `@falari/harness`; the surrounding Falari checkout only hosts the SDK it builds
140
+ against and the docs it follows. Project home: <https://falari.xyz>.
141
+
142
+ The package name `@falari/harness` is the bundle identity: `package.json` `name`,
143
+ the Loader row in `cordis.patch.yml` and the `id` passed to
144
+ `window.__ModuleLoader__.load` must all stay equal, because the client-modules
145
+ scan matches the installed manifest name against the Loader specifier.
146
+
147
+ `package.json` exports `.`, `./client`, `./cordis.patch.yml`, `./package.json`,
148
+ `./locale/*.json` and `./icon`, and ships `index.js`, `client.js`, `lib/**`, the
149
+ patch, locales, icon, README, CHANGELOG and LICENSE. Everything else
150
+ (`scripts/`, `docs/`) is repository-only. `npm pack --dry-run` lists 18 files.
151
+
152
+ Publishing is a push of this directory to a new repository; nothing else in the
153
+ manifest needs to change.
154
+
155
+ ## Layout
156
+
157
+ ```text
158
+ clients/harness/
159
+ ├── .gitignore
160
+ ├── CHANGELOG.md # release notes per milestone
161
+ ├── LICENSE # MIT, © 2026 falari_labs
162
+ ├── README.md
163
+ ├── package.json # dsh.bundle + dsh.client manifest, exports, files
164
+ ├── cordis.patch.yml # inserts the falari-harness row
165
+ ├── icon.png
166
+ ├── index.js # Host entry: wiring
167
+ ├── client.js # Web client half: panel, tabs, settings
168
+ ├── lib/
169
+ │ ├── config.js # row config resolution + edit validation
170
+ │ ├── errors.js # shared error shape and mapping
171
+ │ ├── routes.js # /api/falari-harness/* (same-origin, loopback)
172
+ │ ├── sdk.js # loads the bundled SDK
173
+ │ ├── service.js # FalariDataService: key, quote, budget, uploads, downloads
174
+ │ ├── tools.js # six falari_* Agent tools
175
+ │ └── falari-sdk.cjs # generated by npm run build:sdk (committed on purpose)
176
+ ├── scripts/
177
+ │ ├── build-sdk.sh # esbuild bundle of @falari/agent + precompiles
178
+ │ ├── unit-host.mjs # pure-helper unit tests
179
+ │ ├── smoke-host.mjs # HTTP route smoke tests against a patched SDK
180
+ │ └── smoke-client.mjs # client.js render smoke test in a VM
181
+ ├── locale/{en,zh}.json # plugin metadata
182
+ └── docs/
183
+ ├── plan.md # v0.1 design and milestone log
184
+ └── test-plan.md # automated, live and panel checks
185
+ ```
186
+
187
+ ## Test
188
+
189
+ ```sh
190
+ npm test # unit + Host routes + client render, all offline
191
+ ```
192
+
193
+ | Suite | What it does |
194
+ |---|---|
195
+ | `scripts/unit-host.mjs` | config validation/defaults, name sanitizing, status and error mapping |
196
+ | `scripts/smoke-host.mjs` | patches the SDK client and drives every HTTP route: status, key, quote, raw upload, task actions, intents, download, config save, origin and loopback guards |
197
+ | `scripts/smoke-client.mjs` | loads `client.js` in a VM and server-renders the three slot components |
198
+
199
+ 83 checks pass today. The manual and live testnet steps are in
200
+ [docs/test-plan.md](docs/test-plan.md).
201
+
202
+ ## Security
203
+
204
+ - The Agent Key is a bearer credential with upload rights. It is stored only in
205
+ the Host credential store; the browser never receives or persists the raw
206
+ `far_...` string, and no route returns it.
207
+ - Upload routes accept only same-origin requests; cross-origin writes are
208
+ rejected with 403.
209
+ - Routes answer loopback peers only unless `allowRemoteRoutes` is enabled, so a
210
+ listener bound to a wider address cannot be used to change the key or pay for
211
+ uploads.
212
+ - Browser uploads stream into a 0600 temp file under the plugin data directory
213
+ and are deleted once the task completes or is cancelled; files older than 24
214
+ hours are swept at startup.
215
+ - The panel shows a private file's Data Key once the upload completes, because
216
+ losing it makes the ciphertext unrecoverable.
217
+ - Downloads are written only inside the configured `downloadDir` (default
218
+ `<dataDir>/downloads`); an `out_path` that escapes it is refused, and an
219
+ existing file name gains a ` (1)` suffix instead of being overwritten.
2
220
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.