@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/CHANGELOG.md +456 -0
- package/LICENSE +21 -0
- package/README.md +219 -2
- package/client.js +3303 -0
- package/cordis.patch.yml +6 -0
- package/icon.png +0 -0
- package/index.js +52 -0
- package/lib/config.js +103 -0
- package/lib/errors.js +40 -0
- package/lib/falari-sdk.cjs +39775 -0
- package/lib/pin.js +126 -0
- package/lib/routes.js +311 -0
- package/lib/sdk.js +13 -0
- package/lib/service.js +1429 -0
- package/lib/tools.js +193 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +61 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Falari Harness bundle. The bundle is installed into a
|
|
4
|
+
DeepSeek Harness profile; version numbers track the delivery milestones in
|
|
5
|
+
[docs/plan.md](docs/plan.md).
|
|
6
|
+
|
|
7
|
+
## 0.8.10 — 2026-11-10
|
|
8
|
+
|
|
9
|
+
Documentation and package metadata carry the project identity only.
|
|
10
|
+
|
|
11
|
+
- Developer is **falari_labs**, project website **https://falari.xyz**; the npm
|
|
12
|
+
manifest's `author` and `homepage` say so, and the LICENSE reads
|
|
13
|
+
`Copyright (c) 2026 falari_labs`.
|
|
14
|
+
- Removed a developer machine path from the README install example (it now uses
|
|
15
|
+
`/path/to/clients/harness`) and dropped `repository` / `bugs` links that pointed
|
|
16
|
+
at a repository that is not the published channel; the npm package is.
|
|
17
|
+
- No functional change.
|
|
18
|
+
|
|
19
|
+
## 0.8.9 — 2026-11-10
|
|
20
|
+
|
|
21
|
+
Any storage term can be typed, and the fee rules match the chain exactly.
|
|
22
|
+
|
|
23
|
+
- Upload → 存储时长 gains **自定义…**: a number plus days / months / years
|
|
24
|
+
(days = 24 h, months = 30 days, years = 365 days), converted to whole seconds
|
|
25
|
+
and sent as the duration. The field echoes the billing in words
|
|
26
|
+
(`≈ 30 days billed · expires 12/10/2026`), rejects anything under one day, and
|
|
27
|
+
blocks the upload button while the term is incomplete.
|
|
28
|
+
- Host accepts any whole second count from 0 (permanent) to the chain's
|
|
29
|
+
`max_intent_duration_seconds` (100 years), and refuses anything outside it.
|
|
30
|
+
The quote response now carries `billableDays` and `durationLimits`.
|
|
31
|
+
- **Fee rule fixed in the SDK**: `quoteStorageFee` now mirrors
|
|
32
|
+
`Params.RequiredFee` for long finite terms. Before, a 40-year quote was priced
|
|
33
|
+
by the day and came out *more expensive than permanent*; the chain switches to
|
|
34
|
+
the permanent price at 36 years (30-year window + 20% reserve), and the SDK now
|
|
35
|
+
does the same. Whole-day billing, rounded up, minimum one day, unchanged.
|
|
36
|
+
- SDK `@falari/agent` 0.2.6; new `duration-fee-cap.test.mjs` (4 checks).
|
|
37
|
+
|
|
38
|
+
## 0.8.8 — 2026-11-10
|
|
39
|
+
|
|
40
|
+
The panel header wears the original render, not the cut-out.
|
|
41
|
+
|
|
42
|
+
- `FalariLogoImage` draws the supplied artwork as-is (dark backdrop included),
|
|
43
|
+
cropped around the cube so it fills the 46 px tile without the empty margin of
|
|
44
|
+
the 512 px source. It is inlined once as a data URI, so the client bundle stays
|
|
45
|
+
a single file (~28 KB base64).
|
|
46
|
+
- The sidebar keeps the vector mark: at 20 px a raster loses the `>_` glyph,
|
|
47
|
+
while the vector stays crisp at any DPI.
|
|
48
|
+
- `icon.png` (plugin list) remains the transparent cut-out from 0.8.5; the header
|
|
49
|
+
and the icon are intentionally different treatments of the same artwork.
|
|
50
|
+
|
|
51
|
+
## 0.8.7 — 2026-11-10
|
|
52
|
+
|
|
53
|
+
The idle-lock window is a real setting, not a fixed number.
|
|
54
|
+
|
|
55
|
+
- Default stays **60 minutes**; the field now offers presets (15 / 30 / 60 / 120 /
|
|
56
|
+
240 / never) **plus a free minute input**, so any value from 0 to 10080 (7 days)
|
|
57
|
+
can be typed. 0 means "never lock until DSH exits".
|
|
58
|
+
- The typed value is echoed in words next to the input (`90 → 1 h 30 min`,
|
|
59
|
+
`2880 → 2 d`), so a bare number is never ambiguous.
|
|
60
|
+
- The host validates the same range (`lockIdleMinutes` 0–10080, integer) and
|
|
61
|
+
rejects anything outside it.
|
|
62
|
+
- The security card states the active window: `已解锁 … · 空闲 60 分钟后自动锁定`.
|
|
63
|
+
- Tests: host +3 (90 saved, 10081 rejected, 0 = never), client +4 (duration
|
|
64
|
+
wording in both languages).
|
|
65
|
+
|
|
66
|
+
## 0.8.6 — 2026-11-10
|
|
67
|
+
|
|
68
|
+
The PIN is asked for far less often, and never for a change that did not touch
|
|
69
|
+
the key.
|
|
70
|
+
|
|
71
|
+
- **A plugin row reload no longer locks.** Saving settings, toggling the bundle
|
|
72
|
+
or reinstalling constructs a new service in the same process; the decrypted
|
|
73
|
+
key now lives in a process-wide vault keyed by the sealed record's ciphertext,
|
|
74
|
+
so the new instance adopts it. A different key, a key re-sealed under a new
|
|
75
|
+
PIN, `Clear`, `Lock now` and process exit all still drop it.
|
|
76
|
+
- Default idle lock raised from 15 to **60 minutes**, still configurable
|
|
77
|
+
(`lockIdleMinutes`, 0 = never). The security card now states the real number:
|
|
78
|
+
`idle 60 min → auto-lock`.
|
|
79
|
+
- New `scripts/unit-vault.mjs` (6 checks): fresh service is locked, unlock works,
|
|
80
|
+
a reload keeps it, a different key does not inherit it, `Lock now` forgets it.
|
|
81
|
+
|
|
82
|
+
## 0.8.5 — 2026-11-10
|
|
83
|
+
|
|
84
|
+
New plugin icon: the rendered cube, cut out to transparency.
|
|
85
|
+
|
|
86
|
+
- `icon.png` (256×256 RGBA, 48 KB) replaces `icon.svg`; `exports["./icon"]` and
|
|
87
|
+
`files` point at it, matching the convention other Harness plugins use.
|
|
88
|
+
- The source artwork was a 512×512 image on a dark backdrop. The backdrop is
|
|
89
|
+
removed by taking the convex hull of the lit faces (which keeps the cube's own
|
|
90
|
+
black edges and the `>_` glyph), filling it at 4× for a smooth edge, and
|
|
91
|
+
cropping to the alpha bounds with 6% padding, so the mark is centred at any
|
|
92
|
+
size.
|
|
93
|
+
- Verified over white and dark backgrounds and at 16/24/32/44/64/128 px.
|
|
94
|
+
|
|
95
|
+
## 0.8.4 — 2026-11-10
|
|
96
|
+
|
|
97
|
+
One writer per queue ledger, across processes.
|
|
98
|
+
|
|
99
|
+
- The SDK takes `<upload-queue>.lock` around every queue pass: a JSON record with
|
|
100
|
+
`pid`, `host`, a `token` and a heartbeat every 15 s. A second DSH window (or a
|
|
101
|
+
second machine sharing the profile) defers instead of uploading the same task,
|
|
102
|
+
which is what produced `code 32: account sequence mismatch` when two drivers
|
|
103
|
+
signed batch commits at the same sequence.
|
|
104
|
+
- A lock whose heartbeat is older than 90 s, or whose pid is gone on this host,
|
|
105
|
+
is stale and is reclaimed: a crashed driver must not freeze the queue forever.
|
|
106
|
+
- Release only deletes its own token, so a stale takeover cannot be undone by the
|
|
107
|
+
slow original owner.
|
|
108
|
+
- `runUploadQueue()` reports `pending: true` while another process owns the
|
|
109
|
+
ledger, so the timer retries later without spinning.
|
|
110
|
+
- SDK `@falari/agent` 0.2.5, new test `upload-queue-lock.test.mjs` (live holder
|
|
111
|
+
defers, stale holder is reclaimed, lock released after a pass).
|
|
112
|
+
|
|
113
|
+
## 0.8.3 — 2026-11-10
|
|
114
|
+
|
|
115
|
+
Two writers on one queue were racing the account sequence, and the idle lock was
|
|
116
|
+
able to stop a paid upload.
|
|
117
|
+
|
|
118
|
+
- **One queue writer per process.** A plugin row reload constructs a new service
|
|
119
|
+
while the previous one may still have an upload tick in flight; both then sign
|
|
120
|
+
batch commits against the same account sequence and the chain rejects the loser
|
|
121
|
+
with `code 32`. The service now retires the previous instance before taking
|
|
122
|
+
over, and the SDK refuses to start a second queue loop while a tick is still
|
|
123
|
+
running (`uploadQueueRunning`).
|
|
124
|
+
- **Sequence retries widened**: 6 attempts with 200–1200 ms backoff instead of 3
|
|
125
|
+
attempts at 150–300 ms, enough for a burst of competing transactions to drain.
|
|
126
|
+
- **The idle lock no longer interrupts an upload.** `hasActiveUploads()` reads
|
|
127
|
+
the live queue, and while anything is `queued`/`uploading` the auto-lock
|
|
128
|
+
restarts its clock instead of locking. `POST /key/lock` refuses with
|
|
129
|
+
`upload_in_progress` (423) unless `force: true`; the panel asks before forcing.
|
|
130
|
+
- The security card says when auto-lock is paused for an upload.
|
|
131
|
+
|
|
132
|
+
## 0.8.2 — 2026-11-10
|
|
133
|
+
|
|
134
|
+
- The main account balance renders to four decimals (`12.3456 FAR`). It floors
|
|
135
|
+
rather than rounds, so the card can never claim more than the account holds;
|
|
136
|
+
the exact value stays in `balanceWei` for any calculation. The formatted
|
|
137
|
+
string from older Hosts is handled the same way.
|
|
138
|
+
|
|
139
|
+
## 0.8.1 — 2026-11-10
|
|
140
|
+
|
|
141
|
+
The panel now wears the wallet's visual language.
|
|
142
|
+
|
|
143
|
+
Taken from the Android client's `ui/theme` (the frosted-glass D+E theme), adapted
|
|
144
|
+
to a web panel: the palette still resolves to Harness tokens, so light and dark
|
|
145
|
+
follow the host instead of hard-coding colours.
|
|
146
|
+
|
|
147
|
+
- Token layer in `client.js`: `colors` (ink / hairline / divider / four surfaces /
|
|
148
|
+
brand + soft fills / three orb hues / glass edge), plus `radius` (20 card, 16
|
|
149
|
+
dialog, 14 block, 10 field, 12 tile), `space` (22 page, 18 card, 14 section,
|
|
150
|
+
12 row, 8 inline, 4 tight) and `type` (24 display … 10.5 kicker). Literal font
|
|
151
|
+
sizes in the page blocks were folded into the scale (58 sites).
|
|
152
|
+
- `Backdrop`: three blurred colour orbs behind the content, which is what makes
|
|
153
|
+
a translucent panel read as glass.
|
|
154
|
+
- `Card` is the single panel primitive: translucent surface, 1px highlight edge,
|
|
155
|
+
soft lift, 20px radius. `SectionTitle` gives every block the wallet's small
|
|
156
|
+
wide-bold label register.
|
|
157
|
+
- Header is one glass bar: the mark in a tinted tile, title + badges, hint below,
|
|
158
|
+
refresh on the right. Tabs became a floating segmented pill so the row reads as
|
|
159
|
+
a control, not a page divider.
|
|
160
|
+
- Buttons are gradient CTA / soft secondary / danger; badges are tinted fills
|
|
161
|
+
rather than outline rings; drop zone is a lifted area with a brand glyph.
|
|
162
|
+
- Data table: uppercase kicker headers, hairline row dividers, tabular numerals,
|
|
163
|
+
name + shortened intent id (full id in the tooltip).
|
|
164
|
+
- Task row: the intent id is shortened to match the table, the percentage is
|
|
165
|
+
promoted out of the muted grey.
|
|
166
|
+
|
|
167
|
+
Verified by rendering both palettes off the real component tree. Tests unchanged:
|
|
168
|
+
25 + 18 + 73 + 58 = 174 checks green.
|
|
169
|
+
|
|
170
|
+
## 0.8.0 — 2026-11-10
|
|
171
|
+
|
|
172
|
+
The Agent Key is sealed under a PIN; nothing readable is left on disk.
|
|
173
|
+
|
|
174
|
+
- New `lib/pin.js`: the `far_` string is encrypted with AES-256-GCM under a key
|
|
175
|
+
derived by scrypt (N=2^15, per-record 16-byte salt, 12-byte IV). Stored record
|
|
176
|
+
is `{v:2, kdf:'scrypt', salt, iv, tag, ct}`: no plaintext, and the KDF
|
|
177
|
+
parameters travel with it so a future change stays readable.
|
|
178
|
+
- **A PIN is mandatory when saving a key.** `POST /key` without one is refused
|
|
179
|
+
(`missing_pin`), so a profile can never quietly hold a clear-text key.
|
|
180
|
+
- The decrypted key lives only in this process's memory. `POST /key/lock`
|
|
181
|
+
drops it and stops the queue; `lockIdleMinutes` (default 15, 0 = never)
|
|
182
|
+
expires it after inactivity. A Host restart starts locked.
|
|
183
|
+
- A profile that already had a plaintext key is reported as `legacy`: the panel
|
|
184
|
+
flags it, uploads are refused with `pin_required`, and `POST /key/secure`
|
|
185
|
+
re-seals the same key in place with a PIN (no re-entry, no upload).
|
|
186
|
+
- Wrong PINs are counted: five misses cost a 30-second pause (`pin_blocked`,
|
|
187
|
+
429). A wrong PIN and a tampered record fail identically, so the error cannot
|
|
188
|
+
be used as a decryption oracle.
|
|
189
|
+
- Panel: the key card is now a vault (set PIN / unlock / lock now / clear), the
|
|
190
|
+
upload tab gates itself with an inline PIN field, and the status card shows
|
|
191
|
+
`Locked` instead of pretending the chain is down.
|
|
192
|
+
- Errors: `agent_key_locked` / `pin_required` → 423, `wrong_pin` → 401,
|
|
193
|
+
`pin_blocked` → 429. `GET /health` reports `encrypted` and `locked`.
|
|
194
|
+
- Tests: new `scripts/unit-pin.mjs` (18 checks: round trip, wrong PIN, tampered
|
|
195
|
+
ciphertext/tag, malformed salt, PIN policy, Unicode normalisation), host 73,
|
|
196
|
+
client 58.
|
|
197
|
+
|
|
198
|
+
## 0.7.6 — 2026-11-10
|
|
199
|
+
|
|
200
|
+
Upload authorization on the chunked path (the 0.6.5 fix missed it).
|
|
201
|
+
|
|
202
|
+
- Every shard goes through the **chunked** upload route (`/upload?offset=…`,
|
|
203
|
+
`?final=1`) whenever `ChainApi.uploadShardChunk` exists, and 0.6.5 only signed
|
|
204
|
+
the one-shot `/upload` variant. A miner in enforce mode kept answering
|
|
205
|
+
`upload auth: upload authorization is missing` for every shard, so a segment
|
|
206
|
+
never reached its receipt quorum.
|
|
207
|
+
- `ChainApi.uploadShardChunk` now accepts the EIP-712 envelope, and the chunked
|
|
208
|
+
v3 path attaches it on the direct route as well as the relay route (including
|
|
209
|
+
the empty final chunk that only reclaims a receipt).
|
|
210
|
+
- SDK `@falari/agent` 0.2.3; new SDK test pins the three headers on a direct
|
|
211
|
+
chunked upload.
|
|
212
|
+
|
|
213
|
+
## 0.7.5 — 2026-11-10
|
|
214
|
+
|
|
215
|
+
The Data tab paints before the chain answers.
|
|
216
|
+
|
|
217
|
+
- The intent list is cached in `localStorage` (keyed by the master account, so a
|
|
218
|
+
key or network change never flashes another account's files) and rendered
|
|
219
|
+
immediately; the chain's answer replaces it when it lands, with
|
|
220
|
+
`Showing the last snapshot while the chain answers` next to the refresh button.
|
|
221
|
+
- The first open in a profile shows five skeleton rows that pulse
|
|
222
|
+
(`@keyframes falari-skeleton`), instead of a one-line "loading".
|
|
223
|
+
- Each row's title is the file name plus the intent id
|
|
224
|
+
(`DBX.app.zip intent_e152ffa100…571d84`); the copy button still copies the full
|
|
225
|
+
id and a private intent without a readable name shows `Untitled` rather than
|
|
226
|
+
repeating its id.
|
|
227
|
+
|
|
228
|
+
## 0.7.4 — 2026-11-10
|
|
229
|
+
|
|
230
|
+
Audit of the upload and cancel flows; eight interaction defects fixed.
|
|
231
|
+
|
|
232
|
+
Upload:
|
|
233
|
+
|
|
234
|
+
- The estimate priced the **sum** of the selected files while every file becomes
|
|
235
|
+
its own order, so the deposit looked far larger than any single upload. It now
|
|
236
|
+
prices the largest file and says so when several are selected.
|
|
237
|
+
- A file that queued successfully stayed in the selection, so a retry sent it a
|
|
238
|
+
second time (a second escrow). Queued files are dropped from the list.
|
|
239
|
+
- The upload button is disabled while the quote says the budget is short, instead
|
|
240
|
+
of streaming a whole file and failing at the end.
|
|
241
|
+
- The progress line names the file being sent (`Sending 2/3 · name · size`); the
|
|
242
|
+
streaming phase had no feedback at all.
|
|
243
|
+
- The drop zone is keyboard reachable (role, tabIndex, Enter/Space).
|
|
244
|
+
|
|
245
|
+
Cancel:
|
|
246
|
+
|
|
247
|
+
- **Every unfinished upload can now be cancelled**, including `failed` and
|
|
248
|
+
`needs_source` rows: those hold an escrow but only offered Delete, so the money
|
|
249
|
+
was unreachable from the UI.
|
|
250
|
+
- A task with no on-chain order gets its own dialog (`Cancel upload`) that states
|
|
251
|
+
nothing is refunded, instead of a page of 0 FAR rows.
|
|
252
|
+
- A settled (`finalized`) order reports `unavailable: 'finalized'` and explains
|
|
253
|
+
that cancelling falls back to the early-termination rule, instead of showing a
|
|
254
|
+
zero escrow as if everything had been refunded.
|
|
255
|
+
- A failed preview read no longer aborts the termination, and a termination the
|
|
256
|
+
chain has not confirmed yet reports `pending` instead of claiming success.
|
|
257
|
+
- Escape and backdrop clicks are ignored while the cancel transaction is in
|
|
258
|
+
flight, so the dialog cannot vanish mid-mutation.
|
|
259
|
+
|
|
260
|
+
Tests: host 56, client 45.
|
|
261
|
+
|
|
262
|
+
## 0.7.3 — 2026-11-10
|
|
263
|
+
|
|
264
|
+
Cancelling no longer loses the race against the upload driver.
|
|
265
|
+
|
|
266
|
+
- The chain rejected the terminate with `code 32: account sequence mismatch,
|
|
267
|
+
expected 28, got 27`: the upload driver's batch commit consumed the sequence
|
|
268
|
+
the cancel had signed against. The bundled SDK now rebuilds the unsigned
|
|
269
|
+
transaction against the fresh sequence and re-signs, up to three attempts, on
|
|
270
|
+
both the agent (`/tx/exec`) and owner (`/tx/build`) paths.
|
|
271
|
+
- `classifyChainError` reports the race as `sequence_mismatch` /
|
|
272
|
+
`retryable: true`, so a terminate that still fails is queued for another
|
|
273
|
+
attempt instead of parking in `failed` with a retry button.
|
|
274
|
+
- SDK version `@falari/agent` 0.2.2; three new SDK tests pin the retry, the
|
|
275
|
+
no-retry on an unrelated rejection, and the classification.
|
|
276
|
+
|
|
277
|
+
## 0.7.2 — 2026-11-10
|
|
278
|
+
|
|
279
|
+
The status card speaks the interface language.
|
|
280
|
+
|
|
281
|
+
- **Permission tiers** render as 写入数据 / 管理数据 / 转账资金 (`Write data` /
|
|
282
|
+
`Manage data` / `Transfer funds`) instead of the wire names; an unknown tier
|
|
283
|
+
still falls back to its wire value, and the list separator follows the locale.
|
|
284
|
+
- **Key state** renders as 正常 / 已过期 / 已吊销 / 已冻结 / 已停用 / 待生效.
|
|
285
|
+
- Wire names stay unchanged in the API and in `falari_status`, so a signature,
|
|
286
|
+
a log line or a support thread still matches the chain.
|
|
287
|
+
|
|
288
|
+
## 0.7.1 — 2026-11-10
|
|
289
|
+
|
|
290
|
+
- The refund dialog prints `0 FAR` instead of `-0 FAR` when a deduction is zero,
|
|
291
|
+
and the byte formatter keeps one decimal below 100 KiB.
|
|
292
|
+
|
|
293
|
+
## 0.7.0 — 2026-11-10
|
|
294
|
+
|
|
295
|
+
Cancelling an upload asks first, and shows the money.
|
|
296
|
+
|
|
297
|
+
- **Cancel and refund** now opens a dialog instead of terminating on the click:
|
|
298
|
+
file, status, bytes already uploaded, the escrow the chain holds, the
|
|
299
|
+
cancellation rate (`voluntary_cancellation_fee_bps`), the withheld
|
|
300
|
+
compensation, the terminate service fee billed from the main balance, and the
|
|
301
|
+
amount going back to the main account.
|
|
302
|
+
- The numbers come from the chain, not from a local guess:
|
|
303
|
+
`GET /api/falari-harness/tasks/:id/refund` reads the intent (`locked_fee_wei`,
|
|
304
|
+
`uploaded_size`, `refunded_fee_wei`) and `/params`
|
|
305
|
+
(`voluntary_cancellation_fee_bps`, `min_cancellation_fee`,
|
|
306
|
+
`service_fees.terminate`) and mirrors `closeUnfinalizedIntent`: the fee is
|
|
307
|
+
`max(min_cancellation_fee, escrow * bps / 10000)` capped at the escrow, and an
|
|
308
|
+
intent with no committed receipt is closed without compensation.
|
|
309
|
+
- Confirming posts `/tasks/:id/cancel`, which terminates, then re-reads the
|
|
310
|
+
intent and shows the amount the chain actually released.
|
|
311
|
+
- `formatFar` / `formatBytes` helpers; the dialog closes on Escape or a backdrop
|
|
312
|
+
click.
|
|
313
|
+
|
|
314
|
+
## 0.6.5 — 2026-11-10
|
|
315
|
+
|
|
316
|
+
Uploads reach miners that enforce the EIP-712 upload authorization.
|
|
317
|
+
|
|
318
|
+
- The bundled SDK signed the envelope only for relayed shards. A miner with its
|
|
319
|
+
own HTTP endpoint got a bare `POST /upload` and refused it with
|
|
320
|
+
`upload auth: upload authorization is missing`, so an upload ended with
|
|
321
|
+
`only 0/1 segments reached 4 receipts on 3 distinct miners`.
|
|
322
|
+
- `ChainApi.uploadShard` now accepts the envelope, and the v3 upload paths
|
|
323
|
+
(whole shard, chunk, empty final chunk) sign one per attempt on the direct
|
|
324
|
+
route as well. The nonce is single-use, so every retry re-signs.
|
|
325
|
+
- SDK: new tests assert the three `X-Falari-Upload-*` headers on a direct upload
|
|
326
|
+
and that an upload without a signer stays unsigned.
|
|
327
|
+
|
|
328
|
+
## 0.6.4 — 2026-11-10
|
|
329
|
+
|
|
330
|
+
The panel paints the last known status instead of waiting for the chain.
|
|
331
|
+
|
|
332
|
+
- The Host keeps the status view in memory and in
|
|
333
|
+
`<dataDir>/status-cache.json` (0600, keyed by network + master + agent
|
|
334
|
+
address). `GET /api/falari-harness/status` answers from that cache immediately
|
|
335
|
+
and starts one background chain read when the cached view is older than 15
|
|
336
|
+
seconds; `?refresh=1` forces a read. A failed read keeps the last good numbers
|
|
337
|
+
and reports the error beside them.
|
|
338
|
+
- The panel and the settings page store the status in `localStorage`, so the
|
|
339
|
+
card renders before the first request completes, then polls every 5 seconds
|
|
340
|
+
and shows newer numbers when they arrive. The header shows `Updated HH:MM:SS`
|
|
341
|
+
and `refreshing…` while a read is in flight.
|
|
342
|
+
- `falari_status` gained `refresh: true` to bypass the cache. Clearing the key
|
|
343
|
+
removes the cached view on both sides.
|
|
344
|
+
|
|
345
|
+
## 0.6.3 — 2026-11-10
|
|
346
|
+
|
|
347
|
+
The status card shows one address.
|
|
348
|
+
|
|
349
|
+
- The Agent Key's own address is gone from the status view and the panel: the
|
|
350
|
+
row now reads **Main address / 主地址** with the owner account, which is the
|
|
351
|
+
account that pays and owns the data.
|
|
352
|
+
- `keyStatusFrom` no longer returns `agentKey.agentAddress`, so the
|
|
353
|
+
`falari_status` tool result does not carry it either. The key's ordinal, state,
|
|
354
|
+
tiers, allowance and expiry still identify it.
|
|
355
|
+
|
|
356
|
+
## 0.6.2 — 2026-11-09
|
|
357
|
+
|
|
358
|
+
The official Falari mark replaces the placeholder cube.
|
|
359
|
+
|
|
360
|
+
- `icon.svg` is the real logo: isometric cube measured from the supplied
|
|
361
|
+
artwork (hexagon, three lit faces, the inner edges drawn as bands inside the
|
|
362
|
+
faces, the `>_` prompt on the left face) in a 100×100 box.
|
|
363
|
+
- The panel header and the sidebar use the same geometry; a hairline silhouette
|
|
364
|
+
keeps the white cube readable on white surfaces, and the sidebar's 20px mark
|
|
365
|
+
uses a bolder stroke and darker faces.
|
|
366
|
+
- Gradient ids are per instance (`useId`), so several marks can render at once.
|
|
367
|
+
|
|
368
|
+
## 0.6.1 — 2026-11-09
|
|
369
|
+
|
|
370
|
+
Configuration is reachable from the plugin itself, and the plugin metadata reads
|
|
371
|
+
in both languages.
|
|
372
|
+
|
|
373
|
+
- The panel gained a fourth tab, **Settings / 设置**, holding the Agent Key form,
|
|
374
|
+
the status card and the storage configuration — the plugin's own settings
|
|
375
|
+
surface, independent of the plugin-manager page.
|
|
376
|
+
- The Host now declares `configure({ auto: false })` to the Settings service, so
|
|
377
|
+
DSH knows this plugin ships its own configuration page instead of expecting a
|
|
378
|
+
schema-generated form. Skipped when the service is absent.
|
|
379
|
+
- `plugins.bundle.config` and `plugins.row.config` honor `view: 'summary'` with a
|
|
380
|
+
one-line summary, as the plugin manager expects for compact rows.
|
|
381
|
+
- `locale/*.json` titles and descriptions now carry both languages
|
|
382
|
+
(`Falari Data / Falari 数据`), so the plugin reads the same in any UI language.
|
|
383
|
+
|
|
384
|
+
## 0.6.0 — 2026-11-09
|
|
385
|
+
|
|
386
|
+
The plugin's settings live on its own page, not in the global Settings dialog.
|
|
387
|
+
|
|
388
|
+
- Removed the `settings.section` registration; the Agent Key form, status and
|
|
389
|
+
configuration card now render through `plugins.bundle.config` (the bundle page)
|
|
390
|
+
and `plugins.row.config` (the row's configure page), both keyed by this package.
|
|
391
|
+
- Copy across the panel, the tools and the Host errors now points at
|
|
392
|
+
*Plugins → Falari Data → Configure* instead of the Settings dialog.
|
|
393
|
+
- Dropped the duplicated page header, since the host heads these pages with the
|
|
394
|
+
plugin title and description; two locale keys and three checks updated.
|
|
395
|
+
|
|
396
|
+
## 0.5.0 — 2026-11-09
|
|
397
|
+
|
|
398
|
+
Settings become editable and the offline test suite is complete.
|
|
399
|
+
|
|
400
|
+
- `POST /api/falari-harness/config` writes network, default privacy, default
|
|
401
|
+
duration, upload size limit, download directory and the
|
|
402
|
+
upload-outside-workspace switch through the profile's config editor. Saving
|
|
403
|
+
restarts the plugin row, and the panel says so.
|
|
404
|
+
- Field-level validation for every accepted value; unknown fields and empty
|
|
405
|
+
patches are refused with a reason instead of being dropped.
|
|
406
|
+
- `scripts/unit-host.mjs`: config validation/defaults, file-name sanitizing, HTTP
|
|
407
|
+
status mapping and error mapping.
|
|
408
|
+
- `docs/test-plan.md`: automated coverage, live testnet steps and panel checks.
|
|
409
|
+
- Removed the placeholder component and 22 unused locale keys; English and
|
|
410
|
+
Chinese dictionaries stay at 141 keys each.
|
|
411
|
+
|
|
412
|
+
## 0.4.0 — 2026-11-09
|
|
413
|
+
|
|
414
|
+
Intent listing and downloads.
|
|
415
|
+
|
|
416
|
+
- `GET /intents`, `GET /intents/:id`, `POST /downloads`, `GET /downloads/:id`.
|
|
417
|
+
- `falari_list` and `falari_download` Agent tools.
|
|
418
|
+
- Private intent names are decrypted locally when this machine holds the data
|
|
419
|
+
key; otherwise the intent id is shown.
|
|
420
|
+
- Downloads run as tasks with progress, are written only inside the download
|
|
421
|
+
directory, and never overwrite an existing file.
|
|
422
|
+
- Upload and download tasks share one list; the panel gained *My data* and
|
|
423
|
+
*Download* tabs.
|
|
424
|
+
|
|
425
|
+
## 0.3.0 — 2026-11-09
|
|
426
|
+
|
|
427
|
+
Uploads.
|
|
428
|
+
|
|
429
|
+
- `POST /quote`, `POST /uploads` (raw octet-stream, streamed to a 0600 temp file)
|
|
430
|
+
and the upload queue driven by the SDK's persistent ledger.
|
|
431
|
+
- `falari_quote`, `falari_upload` and `falari_task` tools; uploads from the model
|
|
432
|
+
are restricted to the session working directory.
|
|
433
|
+
- Upload panel with drag-and-drop, privacy and duration, automatic quote with a
|
|
434
|
+
budget check, and per-task pause/resume/retry/cancel.
|
|
435
|
+
- Panel routes answer loopback peers only (`allowRemoteRoutes` to change);
|
|
436
|
+
cross-origin writes are rejected.
|
|
437
|
+
- `scripts/build-sdk.sh` bundles the unpublished `@falari/agent` and
|
|
438
|
+
`@falari/precompiles` packages into `lib/falari-sdk.cjs`.
|
|
439
|
+
|
|
440
|
+
## 0.2.0 — 2026-11-09
|
|
441
|
+
|
|
442
|
+
Agent Key management.
|
|
443
|
+
|
|
444
|
+
- The key is stored in the DSH credential store as `falari-harness/agent-key`;
|
|
445
|
+
the browser never receives it and no route returns it.
|
|
446
|
+
- Key validation (format, registration, network) with distinct error codes.
|
|
447
|
+
- `falari_status` tool and the settings page status card: agent address, master,
|
|
448
|
+
tiers, allowance, balance, expiry, miners.
|
|
449
|
+
|
|
450
|
+
## 0.1.0 — 2026-11-09
|
|
451
|
+
|
|
452
|
+
Initial bundle.
|
|
453
|
+
|
|
454
|
+
- `@falari/harness` bundle manifest, row patch, icon, locale metadata.
|
|
455
|
+
- Host half activates; Web half registers a sidebar entry, a data panel and a
|
|
456
|
+
settings page.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 falari_labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|