geneseed 4.19.0 → 4.21.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 +27 -0
- package/SHIPPED.md +1 -1
- package/docs/guides/upgrade.md +1 -1
- package/docs/web-ui.md +11 -10
- package/harness.config.json +1 -1
- package/js/README.md +1 -1
- package/js/web/actions.mjs +39 -0
- package/js/web/api.mjs +24 -2
- package/js/web/handler.mjs +20 -1
- package/js/web/jobs.mjs +6 -6
- package/js/web/usage-api.mjs +24 -3
- package/package.json +1 -1
- package/src/skills/rule.md +3 -3
- package/web/dist/assets/Activity-DsKkFGhT.js +1 -0
- package/web/dist/assets/ActivityDetail-BWY-vaiK.js +1 -0
- package/web/dist/assets/Dashboard-BZmw2a7d.js +2 -0
- package/web/dist/assets/Docs-CNuRuMin.js +4 -0
- package/web/dist/assets/EmptyState-1sPNleqv.js +1 -0
- package/web/dist/assets/GreenhouseView-BCiZP9f9.js +1 -0
- package/web/dist/assets/Installs-xkBX6OjK.js +3 -0
- package/web/dist/assets/JournalView-BSR51TKR.js +1 -0
- package/web/dist/assets/{KitApply-BAF0gtXb.js → KitApply-BR8AcZ62.js} +1 -1
- package/web/dist/assets/Kits-e0DCj9sT.js +1 -0
- package/web/dist/assets/Laws-BuG2_HFE.js +3 -0
- package/web/dist/assets/Library-BYfB4mhf.js +2 -0
- package/web/dist/assets/Loops-r6L7a1g1.js +2 -0
- package/web/dist/assets/OperatorHudView-BLXm0zzn.js +1 -0
- package/web/dist/assets/Personal-kEfKCxlh.js +1 -0
- package/web/dist/assets/RailCats-DNlJKicm.js +1 -0
- package/web/dist/assets/StackBar-Y_gkoC3t.js +1 -0
- package/web/dist/assets/Tabs-2uMB511T.js +1 -0
- package/web/dist/assets/activity-BEWV9er4.js +1 -0
- package/web/dist/assets/drawable-ixCquffB.js +1 -0
- package/web/dist/assets/index-CDSHv_7s.css +1 -0
- package/web/dist/assets/index-Dwo3Gxek.js +2 -0
- package/web/dist/assets/jobBuckets-Dpjvbfm1.js +2 -0
- package/web/dist/index.html +2 -2
- package/web/dist/assets/Activity-2fa9G39h.js +0 -1
- package/web/dist/assets/ActivityDetail-DIT7ITJw.js +0 -1
- package/web/dist/assets/Dashboard-Ddz0KQF3.js +0 -3
- package/web/dist/assets/Docs-j5cPrsOs.js +0 -4
- package/web/dist/assets/GreenhouseView-BhI_tF4c.js +0 -1
- package/web/dist/assets/Installs-kkE0H4Q2.js +0 -3
- package/web/dist/assets/JournalView-w5adl4Sm.js +0 -1
- package/web/dist/assets/Kits-BteVDSKD.js +0 -1
- package/web/dist/assets/Laws-DNTpf31b.js +0 -3
- package/web/dist/assets/Library-CgX1dJTr.js +0 -1
- package/web/dist/assets/Loops-MhJU2d8B.js +0 -2
- package/web/dist/assets/OperatorHudView-BvLd1zig.js +0 -1
- package/web/dist/assets/Personal-BdN0jlmh.js +0 -1
- package/web/dist/assets/RailCats-D5RVYEjy.js +0 -1
- package/web/dist/assets/Tabs-BPs85vgk.js +0 -1
- package/web/dist/assets/activity-Jw8XcPiP.js +0 -1
- package/web/dist/assets/drawable-DjpisR6c.js +0 -1
- package/web/dist/assets/index-B9-bvRjd.js +0 -2
- package/web/dist/assets/index-DwzZK5uG.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,33 @@ label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [4.21.0] — 2026-10-25
|
|
12
|
+
|
|
13
|
+
Minor: Activity "Today", per-install rebuild, usage in the Library, sync with source in Hosts, a command palette, and `user` as an alias of `global`.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Activity "Today".** Runs per day over 14 days, gate asks per rule over 30 days and "Waiting on you", above a feed that mixes runs and gate asks by day, with filters — so the page answers what your agents did even with live tracking off.
|
|
17
|
+
- **Rebuild one install.** Each Overview row rebuilds only its own install, and "Rebuild all behind (N)" rebuilds only the installs that need it; both ask first and show progress on the rows they touch. A per-install rebuild on a console running older code than the disk asks you to restart it first.
|
|
18
|
+
- **Usage in the Library.** Each skill and agent shows its call count across installs, the reader shows where and how often it ran over 30 days, and a "Not used yet" filter lists what has not fired since counting began.
|
|
19
|
+
- **Hosts shows each install's sync with source**, and the Server tab is a settings sheet: server pid and uptime, whether the code matches the disk, the request guards, and a danger zone.
|
|
20
|
+
- **Command palette.** "Search or run…" (Ctrl/⌘ K or `/`) finds pages, items and actions in one place; actions that write still ask first.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **Rule scope `user` is an alias of `global`.** The rule skill documents `project` and `global`; the editor opens a `user` rule on `global` and writes `global` when you save it. Untouched rules keep what they say.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- The Constitution page's Dictates and Doctrines cells no longer show a light browser-default button background that hid their names in dark mode.
|
|
27
|
+
|
|
28
|
+
## [4.20.0] — 2026-10-24
|
|
29
|
+
|
|
30
|
+
Minor: every web console page uses the shared building blocks — one header and one primary action per page, named controls, consistent empty and error states.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- **Every console page uses the shared building blocks.** One page header per page with a single primary action ("Rebuild all (N behind)" on the Overview, "Apply and rebuild" only while Constitution changes are staged); repeated buttons carry distinct names for screen readers; empty and error states, tables, rings and bars come from the shared components. The four Overview lenses sit under that header with a working View switcher.
|
|
34
|
+
- **Installs:** uninstall goes through the danger dialog and names the memory and notebook paths when they will be deleted; notes carry a tone; Doctor shows when it last checked, failing groups first and clean ones folded; the diff names the install it compares and opens large diffs collapsed; host labels replace raw ids.
|
|
35
|
+
- **Activity, Docs and the shell:** one heading per page, timestamps on session timelines, Prev/Next as links, an outline on the CLI page; the appearance menu opens above the phone drawer; choosing a voice asks first; the breadcrumb is a list of links; lists move with the arrow keys, Home and End; the phone tab bar uses the sidebar's labels with a More button.
|
|
36
|
+
- **Library, Kits, Loops, Personal:** the reader titles an entry by its heading, empty kinds explain what to do, Loops explains what a loop and a brick are; the rule budget is one panel with one threshold, memory and notebook show real counts, a profile that is still the template says so, and the rule form has visible labels and keeps focus where you were.
|
|
37
|
+
|
|
11
38
|
## [4.19.0] — 2026-10-24
|
|
12
39
|
|
|
13
40
|
Minor: shared console building blocks, rule summaries kept next to their rules, and `global` as a documented rule scope.
|
package/SHIPPED.md
CHANGED
|
@@ -20,7 +20,7 @@ historical references, not files distributed with the repo.
|
|
|
20
20
|
> **On version numbers.** [`harness.config.json`](harness.config.json)'s `version` is a
|
|
21
21
|
> human-readable label only. The canonical identity of an installed harness is the
|
|
22
22
|
> **source fingerprint** stamped in `.geneseed-version` (see `geneseed version`), not the
|
|
23
|
-
> string. Current label: **4.
|
|
23
|
+
> string. Current label: **4.21.0**.
|
|
24
24
|
|
|
25
25
|
## Capabilities
|
|
26
26
|
|
package/docs/guides/upgrade.md
CHANGED
|
@@ -50,7 +50,7 @@ The console asks npm for the latest release once a day. An Overview page that st
|
|
|
50
50
|
|
|
51
51
|
The npm route never uses `sudo` and never retries. If npm refuses (no permission on the global folder, a proxy, a private registry), the job log shows npm's own output. Fix the cause, or run the two commands yourself.
|
|
52
52
|
|
|
53
|
-
When the update is done, the console restarts and the page reloads. If you ran `git pull` yourself, the Overview shows a banner that the console runs old code. Click **Rebuild** on an install that is behind
|
|
53
|
+
When the update is done, the console restarts and the page reloads. If you ran `git pull` yourself, the Overview shows a banner that the console runs old code. Click **Rebuild** on an install that is behind, or **Rebuild all behind** in the header. The console asks you to confirm, rebuilds only the installs it names, then restarts and reloads the page. If no install is behind, click **Restart** in the banner.
|
|
54
54
|
|
|
55
55
|
## What an upgrade keeps
|
|
56
56
|
|
package/docs/web-ui.md
CHANGED
|
@@ -101,7 +101,7 @@ streams the output of background jobs and keeps their history across reloads.
|
|
|
101
101
|
|
|
102
102
|
- **Rules** (`#/rules`) — your own standing rules, read from and written to the
|
|
103
103
|
`user-rules.md` beside the deployed AGENT.md (the seed-once file no update ever
|
|
104
|
-
touches). List with scope (project/user
|
|
104
|
+
touches). List with scope (project/global — a hand-written `user` opens as global — or any other scope written by hand, which a
|
|
105
105
|
save keeps as written) and trial chips, add/edit/retire forms (a body line starting
|
|
106
106
|
`## ` is refused: the file would read it as a new rule heading), a
|
|
107
107
|
**Graduate** action that adopts a trial rule for good, and a budget meter that turns
|
|
@@ -195,7 +195,9 @@ streams the output of background jobs and keeps their history across reloads.
|
|
|
195
195
|
### 🎨 Setup
|
|
196
196
|
|
|
197
197
|
- **Harness** (`#/harness`) — this machine's own install first (path, voice, footprint,
|
|
198
|
-
and when it was built), then the **Voice** reference, then every detected install.
|
|
198
|
+
and when it was built), then the **Voice** reference, then every detected install. A
|
|
199
|
+
**Sync with source** column says whether each install is behind the source (and by how many
|
|
200
|
+
files), in sync or not checked, shows hand edits apart from stale files, and links to Local edits.
|
|
199
201
|
`#/harnesses` and `#/themes` both still resolve here, so old links and bookmarks keep
|
|
200
202
|
working.
|
|
201
203
|
- The **Voice** card is the former Themes tab, kept as a REFERENCE rather than a second
|
|
@@ -224,14 +226,13 @@ streams the output of background jobs and keeps their history across reloads.
|
|
|
224
226
|
row's staging only when that install's kits changed. A failed rebuild keeps it and says so,
|
|
225
227
|
and a reload asks first while anything is staged. Files you edited in a kit that is now off are kept,
|
|
226
228
|
and the row lists them.
|
|
227
|
-
- **
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
the Harness tab.
|
|
229
|
+
- **Server** (`#/installs/server`; `#/settings` and `#/about` resolve here) — a settings sheet
|
|
230
|
+
with a section index. **Appearance**: accent, Overview view, console direction. **Machine**:
|
|
231
|
+
version + Update, Add to PATH, the viewed install's footprint. **Server**: running · port ·
|
|
232
|
+
pid · uptime, whether the code matches the disk (with Restart), start-at-login state (read
|
|
233
|
+
only), and the four request guards. **About**: version, changelog, credits, source, creator.
|
|
234
|
+
**Danger zone**: Stop server, Remove from PATH, and a pointer to each install's own
|
|
235
|
+
Uninstall in Hosts.
|
|
235
236
|
|
|
236
237
|
## Rebuilding the UI
|
|
237
238
|
|
package/harness.config.json
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
"_comment": "version is a human-readable release label only; the canonical identity of an installed harness is the source fingerprint stamped in .geneseed-version (see `harness version`), not this string.",
|
|
3
3
|
"theme": "neutral",
|
|
4
4
|
"product": "Geneseed",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.21.0"
|
|
6
6
|
}
|
package/js/README.md
CHANGED
|
@@ -241,7 +241,7 @@ the deployed harness as JSON.
|
|
|
241
241
|
| `api.mjs` | The dashboard and settings reads: overview, recent, themes, setup, doctor, diff, installs, excludes, loops |
|
|
242
242
|
| `update-check.mjs` | Is a newer release on npm? Answers from memory, refreshes in the background (a day when it got an answer, an hour when it did not), `null` on any failure, never asked under `node --test` |
|
|
243
243
|
| `gates-api.mjs` | `GET /api/gates`: gate asks per rule per day over 30 days, read off every installed harness's `notebook/gates.jsonl` (the Overview's sparklines) |
|
|
244
|
-
| `usage-api.mjs` | `GET /api/usage`: the 30-day skill and agent call counts across every installed harness, the never-fired list,
|
|
244
|
+
| `usage-api.mjs` | `GET /api/usage`: the 30-day skill and agent call counts across every installed harness, the never-fired list, a fleet-wide `names` list (per-name 30-day counts, installs, daily series, last day seen), and skips lines older than 90 days in each `notebook/usage.jsonl` |
|
|
245
245
|
| `user-files.mjs` | The fingerprint-guarded editors for `user-rules.md` (incl. memory promotion) and `PROFILE.md`, read and write |
|
|
246
246
|
| `actions.mjs` | The other mutating endpoints — memory delete, MCP, excludes, installs, view, restore — plus install/deploy argv |
|
|
247
247
|
| `daemon.mjs` | Detached web start/stop/status/restart, the `.geneseed-web.json` record, and `openUrl` |
|
package/js/web/actions.mjs
CHANGED
|
@@ -715,6 +715,45 @@ export function apiInstallCmd(state, body) {
|
|
|
715
715
|
return { cmd: [process.execPath, path.join(ROOT, 'bin', 'build-driver.mjs'), ...argv] };
|
|
716
716
|
}
|
|
717
717
|
|
|
718
|
+
/**
|
|
719
|
+
* The job steps for the `rebuild` action: the Overview's per-row Rebuild and its "Rebuild all
|
|
720
|
+
* behind", which name the installs to rebuild rather than every one on the machine.
|
|
721
|
+
*
|
|
722
|
+
* Body `{ installs: [{host, path}, ...] }`. Each pair must be an ACTIVE detected install, matched
|
|
723
|
+
* on the same serialised key as `detectedInstall` against a fresh `installTargets()` — the client
|
|
724
|
+
* echoes the raw `path` `/api/fleet` gave it, so an exact match is the honest test. The argv is
|
|
725
|
+
* built from the REGISTRY's host/scope/root, never from body strings, and it is what `rebuildAll`
|
|
726
|
+
* replays (`installProfile`), so a console rebuild of one row equals the CLI's of all of them.
|
|
727
|
+
*
|
|
728
|
+
* ALL OR NOTHING: one unknown, inactive or legacy entry (or a malformed body) is `{ error }` and no
|
|
729
|
+
* job starts. `detectedInstall`'s `NotFound` would answer 404; a refusal here means the world
|
|
730
|
+
* changed under the client, so the dispatcher answers 409, as for `install`. The shape is checked
|
|
731
|
+
* before the registry is read, so a bad body never costs a detect.
|
|
732
|
+
*/
|
|
733
|
+
export function rebuildCmds(body) {
|
|
734
|
+
const list = bget(body, 'installs');
|
|
735
|
+
if (!Array.isArray(list) || !list.length || !list.every(isDict)) {
|
|
736
|
+
return { error: 'installs must be a non-empty list of {host, path}' };
|
|
737
|
+
}
|
|
738
|
+
const active = installTargets().filter(([h, s, r]) => installState(r, h, s) === 'active');
|
|
739
|
+
const keys = [...new Set(list.map((e) => JSON.stringify([strOr(bget(e, 'host')),
|
|
740
|
+
strOr(bget(e, 'path'))])))];
|
|
741
|
+
if (keys.length > active.length) return { error: 'more installs named than are active' };
|
|
742
|
+
const steps = [];
|
|
743
|
+
for (const key of keys) {
|
|
744
|
+
const hit = active.findLast(([host, , root]) => JSON.stringify([host, String(root)]) === key);
|
|
745
|
+
if (hit === undefined) return { error: `not an active install: ${key}` };
|
|
746
|
+
const [host, scope, root] = hit;
|
|
747
|
+
// Asked BEFORE `installProfile`, as `rebuildAll` does: a legacy carrier must never be rebuilt.
|
|
748
|
+
if (legacyProcessCarrierOfDir(root, host)) {
|
|
749
|
+
return { error: `${host}:${scope} (${root}) predates the comms pack (its carrier names `
|
|
750
|
+
+ "'process 8') — run `geneseed setup` for it before rebuilding from the console" };
|
|
751
|
+
}
|
|
752
|
+
steps.push(...actionCommands('build', { buildArgv: installProfile(host, scope, root).argv }));
|
|
753
|
+
}
|
|
754
|
+
return { cmds: steps };
|
|
755
|
+
}
|
|
756
|
+
|
|
718
757
|
/**
|
|
719
758
|
* Deactivate, reactivate, or REMOVE one install.
|
|
720
759
|
*
|
package/js/web/api.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* bind paths to these functions are `routes.mjs`. This file imports none of its route siblings,
|
|
9
9
|
* which is what keeps the old `api ↔ actions` and `api ↔ activity` cycles from coming back.
|
|
10
10
|
*/
|
|
11
|
-
import { readdirSync, statSync } from 'node:fs';
|
|
11
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
|
|
14
14
|
import { CONFIG, CREDIT_RE, ROOT, SRC, THEMES, discoverNames, loadKits, makeCfg, upstreamOf } from '../build/source.mjs';
|
|
@@ -19,6 +19,7 @@ import { installProfile } from '../build/generate.mjs';
|
|
|
19
19
|
import { diffCollect, renderMemo } from '../inspect/diff.mjs';
|
|
20
20
|
import { excludesSnapshot } from '../inspect/excludes.mjs';
|
|
21
21
|
import { VERSION_MARKER, resolvePath } from '../hosts/hosts.mjs';
|
|
22
|
+
import { autostartPaths } from '../hosts/shim.mjs';
|
|
22
23
|
import {
|
|
23
24
|
footprintOfDir, gatesOfDir, installState, installTargets, legacyProcessCarrierOfDir, modeOfDir,
|
|
24
25
|
trustOfDir,
|
|
@@ -236,7 +237,27 @@ export function apiFleet(state) {
|
|
|
236
237
|
cost: alwaysOnCost({ host, root, dir, footprint: footprintOfDir(root) }),
|
|
237
238
|
});
|
|
238
239
|
}
|
|
239
|
-
|
|
240
|
+
// `version` is the source's release label, the "Behind 4.19.0" a behind row names; the same
|
|
241
|
+
// reader `/api/overview` uses, so the two never name different releases.
|
|
242
|
+
return { installs, source_fp: sourceFp, doctor: state.doctor, version: releaseLabel() };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* What the Server tab says about the process answering it — built FIELD BY FIELD, never from the
|
|
247
|
+
* daemon record, which holds the write token: a GET is readable by anything that passes the Host
|
|
248
|
+
* check, and the token is the only guard on a POST. `started` is the process's own start (the
|
|
249
|
+
* server is the process), in epoch seconds. `autostart` is whether the hand-written login
|
|
250
|
+
* launcher the install guide describes (`autostartPaths`) is on disk for THIS platform; null
|
|
251
|
+
* where that guide names none.
|
|
252
|
+
*/
|
|
253
|
+
function serverFacts() {
|
|
254
|
+
const [vbs, plist] = autostartPaths();
|
|
255
|
+
const launcher = { win32: vbs, darwin: plist }[process.platform];
|
|
256
|
+
return {
|
|
257
|
+
pid: process.pid,
|
|
258
|
+
started: Math.floor(Date.now() / 1000 - process.uptime()),
|
|
259
|
+
autostart: launcher ? existsSync(launcher) : null,
|
|
260
|
+
};
|
|
240
261
|
}
|
|
241
262
|
|
|
242
263
|
/** Source files of a kit member: `<dir>/<name>.md`, or every `.md` in a `<dir>/<name>/` folder. */
|
|
@@ -357,6 +378,7 @@ export function apiOverview(state) {
|
|
|
357
378
|
// True when the files on disk changed under this server since it started (an upgrade).
|
|
358
379
|
// `serve` installs the comparison; a state built without a server has none and is false.
|
|
359
380
|
daemon_stale: Boolean(state.daemonStale?.()),
|
|
381
|
+
server: serverFacts(),
|
|
360
382
|
counts: {
|
|
361
383
|
agents: inv.agents.length,
|
|
362
384
|
skills: inv.skills.length,
|
package/js/web/handler.mjs
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
import { resolvePath } from '../hosts/hosts.mjs';
|
|
15
15
|
import { isTruthy, jsonDumpsCompact } from '../lib/json.mjs';
|
|
16
16
|
import { parseIntStrict, percentDecode } from '../lib/text.mjs';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
apiDeployCmd, apiInstallCmd, apiPickFolder, apiRestore, buildActionCmds, mcpTargetPaths, rebuildCmds,
|
|
19
|
+
} from './actions.mjs';
|
|
18
20
|
import { BadRequest, NotFound } from './catalog.mjs';
|
|
19
21
|
import { openUrl, requestRestart } from './daemon.mjs';
|
|
20
22
|
import { apiDocs, apiDocsPage } from './docs.mjs';
|
|
@@ -312,6 +314,11 @@ export function makeHandler(state, jm, token, dist, holder = null) {
|
|
|
312
314
|
* means the world changed under the client) and 400 for deploy (its path came from the body,
|
|
313
315
|
* so a refusal means the body was wrong). Unifying the two would be wrong for one of them.
|
|
314
316
|
*
|
|
317
|
+
* `rebuild` follows them: the named installs' argv (`rebuildCmds`), 409 on a refusal for the
|
|
318
|
+
* install reason, and the build-all restart on a stale server. Its job is several steps, and
|
|
319
|
+
* `_run` stops at the first failed one where `rebuild-all` is best-effort: a click names the
|
|
320
|
+
* installs it wants, so a failure should stop and be read rather than be stepped past.
|
|
321
|
+
*
|
|
315
322
|
* `update` COMES NEXT AND IS INLINE: it is gated on a LOCAL-ONLY preflight before a job is
|
|
316
323
|
* ever started, so a dirty tree or a zip-download install gets a friendly 422 the UI renders
|
|
317
324
|
* as an info popup instead of a job that spawns and then fails. Its finish handler is its own
|
|
@@ -336,6 +343,18 @@ export function makeHandler(state, jm, token, dist, holder = null) {
|
|
|
336
343
|
if (Object.hasOwn(plan, 'error')) return sendJson(res, plan, 400, ae);
|
|
337
344
|
return startJob(res, 'deploy', [plan.cmd], ae);
|
|
338
345
|
}
|
|
346
|
+
if (action === 'rebuild') {
|
|
347
|
+
const plan = rebuildCmds(body);
|
|
348
|
+
if (Object.hasOwn(plan, 'error')) return sendJson(res, plan, 409, ae);
|
|
349
|
+
// A STALE server is refused, not restarted afterwards as build-all is: `rebuildCmds` built
|
|
350
|
+
// each argv with THIS (old) process's `installProfile`, while the build-driver it spawns is
|
|
351
|
+
// the new code on disk, so an axis or marker the pull added would be dropped. build-all
|
|
352
|
+
// spawns the new CLI, which builds every profile with the new code; this path cannot.
|
|
353
|
+
if (state.daemonStale?.()) {
|
|
354
|
+
return sendJson(res, { error: 'the console is running older code than the disk — restart it first (Installs › Server › Restart), then rebuild' }, 422, ae);
|
|
355
|
+
}
|
|
356
|
+
return startJob(res, 'rebuild', plan.cmds, ae);
|
|
357
|
+
}
|
|
339
358
|
if (action === 'update') {
|
|
340
359
|
// The route follows the install (`updatePlan`); a refusal is the same friendly 422.
|
|
341
360
|
// The daily background `git fetch` still running would hold `.git` locks the update's own
|
package/js/web/jobs.mjs
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
*
|
|
46
46
|
* ---------------------------------------------------------------------------------------
|
|
47
47
|
* THE ACTION SURFACE — `doctor`, `build`, `build-all`, `export`, `update`, `link` and
|
|
48
|
-
* `unlink` each name a verb `bin/geneseed-cli.mjs` runs, plus the
|
|
48
|
+
* `unlink` each name a verb `bin/geneseed-cli.mjs` runs, plus the four `INLINE_ACTIONS` the
|
|
49
49
|
* dispatcher answers without the table. `tests/unit/web_jobs.test.mjs` holds the union against
|
|
50
50
|
* a written-out list, so an eighth action cannot appear unchecked.
|
|
51
51
|
*
|
|
@@ -413,12 +413,12 @@ const CLI = () => path.join(ROOT, 'bin', 'geneseed-cli.mjs');
|
|
|
413
413
|
const GEN = () => path.join(ROOT, 'bin', 'build-driver.mjs');
|
|
414
414
|
|
|
415
415
|
/**
|
|
416
|
-
* The
|
|
417
|
-
* `restore` is synchronous and returns a result rather than a job id, and `install`/`deploy
|
|
418
|
-
* resolve their argv from the request body first. Declared so the surface check
|
|
419
|
-
* action the dispatcher answers, not only the table's keys.
|
|
416
|
+
* The four actions the dispatcher answers INLINE, without consulting the table above:
|
|
417
|
+
* `restore` is synchronous and returns a result rather than a job id, and `install`/`deploy`/
|
|
418
|
+
* `rebuild` resolve their argv from the request body first. Declared so the surface check
|
|
419
|
+
* covers every action the dispatcher answers, not only the table's keys.
|
|
420
420
|
*/
|
|
421
|
-
export const INLINE_ACTIONS = ['restore', 'install', 'deploy'];
|
|
421
|
+
export const INLINE_ACTIONS = ['restore', 'install', 'deploy', 'rebuild'];
|
|
422
422
|
|
|
423
423
|
/**
|
|
424
424
|
* ⚠ `doctrines` DEFAULTS TO THE FULL SET, and it is the one axis here whose default is not the
|
package/js/web/usage-api.mjs
CHANGED
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
* `notebook/usage.jsonl` (the writer is js/hosts/usage.mjs, and the OpenCode guard plugin's copy).
|
|
4
4
|
*
|
|
5
5
|
* `{ enabled, since, days_counted, per_day[30], rows[{install, kind, name, n}],
|
|
6
|
-
* never[{install, kind, name}]
|
|
6
|
+
* never[{install, kind, name}], names[{kind, name, n, installs, per_day[30], last}] }`, the
|
|
7
|
+
* window being the last 30 days including today.
|
|
8
|
+
*
|
|
9
|
+
* `names` is the Library's view, fleet-wide: one entry per distinct kind+name, summed over every
|
|
10
|
+
* install, because a skill fired daily on claude and never on opencode IS used — reading
|
|
11
|
+
* `never` (per install) for that was the OV-2 bug. `installs` names those with a call in the
|
|
12
|
+
* window; `last` is the latest day across installs, day-granular and bounded by the 90-day read,
|
|
13
|
+
* so a name whose only lines are older than the window still appears, with n 0 and its `last`.
|
|
14
|
+
* Bounded: distinct names × 30.
|
|
7
15
|
*
|
|
8
16
|
* `since` is the oldest day any ledger holds and `days_counted` how many of the 30 it covers:
|
|
9
17
|
* the console keeps the never-fired claim back until a full 30 are counted, so a fresh install
|
|
@@ -53,6 +61,7 @@ export function usageSummary({ now = Date.now(), targets = installTargets() } =
|
|
|
53
61
|
const first = days[0];
|
|
54
62
|
const perDay = new Array(WINDOW).fill(0);
|
|
55
63
|
const counts = new Map();
|
|
64
|
+
const names = new Map();
|
|
56
65
|
const never = [];
|
|
57
66
|
let since = null;
|
|
58
67
|
let enabled = !process.env.GENESEED_NO_USAGE;
|
|
@@ -63,9 +72,18 @@ export function usageSummary({ now = Date.now(), targets = installTargets() } =
|
|
|
63
72
|
const fired = new Set();
|
|
64
73
|
for (const e of entries) {
|
|
65
74
|
if (since === null || e.ts < since) since = e.ts;
|
|
75
|
+
const nk = `${e.kind}\u0000${e.name}`;
|
|
76
|
+
let it = names.get(nk);
|
|
77
|
+
if (!it) names.set(nk, it = { kind: e.kind, name: e.name, n: 0, installs: [], per_day: new Array(WINDOW).fill(0), last: e.ts });
|
|
78
|
+
if (e.ts > it.last) it.last = e.ts;
|
|
66
79
|
if (e.ts < first) continue;
|
|
67
80
|
const i = days.indexOf(e.ts);
|
|
68
|
-
if (i >= 0)
|
|
81
|
+
if (i >= 0) {
|
|
82
|
+
perDay[i] += 1;
|
|
83
|
+
it.per_day[i] += 1;
|
|
84
|
+
it.n += 1;
|
|
85
|
+
if (!it.installs.includes(install)) it.installs.push(install);
|
|
86
|
+
}
|
|
69
87
|
const key = `${install}\u0000${e.kind}\u0000${e.name}`;
|
|
70
88
|
counts.set(key, (counts.get(key) || 0) + 1);
|
|
71
89
|
fired.add(`${e.kind}\u0000${e.name}`);
|
|
@@ -86,7 +104,10 @@ export function usageSummary({ now = Date.now(), targets = installTargets() } =
|
|
|
86
104
|
}).sort((a, b) => b.n - a.n || a.name.localeCompare(b.name));
|
|
87
105
|
const daysCounted = since === null ? 0
|
|
88
106
|
: Math.min(WINDOW, Math.floor((Date.parse(day(now)) - Date.parse(since)) / DAY_MS) + 1);
|
|
89
|
-
return {
|
|
107
|
+
return {
|
|
108
|
+
enabled, since, days_counted: daysCounted, per_day: perDay, rows, never,
|
|
109
|
+
names: [...names.values()].sort((a, b) => b.n - a.n || a.name.localeCompare(b.name)),
|
|
110
|
+
};
|
|
90
111
|
}
|
|
91
112
|
|
|
92
113
|
export const apiUsage = () => usageSummary();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "Every field here is argued and gated in tests/unit/package_manifest.test.mjs. `files`, `bin` and `engines` each have a test that fails when reality drifts from this file; `version` mirrors harness.config.json and is gated too. Read that docblock before editing this one.",
|
|
3
3
|
"name": "geneseed",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.21.0",
|
|
5
5
|
"description": "A portable, theme-able harness you implant once and use everywhere to grow a disciplined AI coding agent.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai",
|
package/src/skills/rule.md
CHANGED
|
@@ -72,13 +72,13 @@ re-derived. Then take exactly one branch.
|
|
|
72
72
|
5. **Destination.** Scope decides the file: a rule that holds across all the user's
|
|
73
73
|
work goes to the *global* install's `user-rules.md`, a rule bound to this
|
|
74
74
|
codebase to the project's. Tag it to match: `scope: project` — this repo, committable,
|
|
75
|
-
binds the team; `scope: global` — every repository on the machine
|
|
76
|
-
|
|
75
|
+
binds the team; `scope: global` — every repository on the machine. `user` is still read
|
|
76
|
+
as `global`. Read the target first ({{LAW:verify-before-asserting}} — the real current
|
|
77
77
|
rules, not a remembered copy). The build seeds it once and never overwrites it;
|
|
78
78
|
if it is genuinely absent, create it with a `# User rules` header and note that a
|
|
79
79
|
rebuild would have seeded it.
|
|
80
80
|
6. **Draft in the file's own format**: the next free `## R<n> — Title` heading, an
|
|
81
|
-
optional `(scope: project|global
|
|
81
|
+
optional `(scope: project|global | source: …)` metadata line, then the rule in one
|
|
82
82
|
short paragraph, plain and testable. For a rule the user stated, `source:` keeps
|
|
83
83
|
their own words and the day they said them — `source: user 2026-10-16 "never push
|
|
84
84
|
red"` — one sentence at most: it is what later tells a stale rule from a changed
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{i as t,t as n}from"./react-DlYQp10C.js";import{t as r}from"./api-BfpZmUMI.js";import{A as i,J as a,K as o,T as s,V as c,k as l,st as u,u as d}from"./index-Dwo3Gxek.js";import{n as f}from"./jobBuckets-Dpjvbfm1.js";import{c as p,d as m,i as h,l as g,n as _,o as v,r as y,s as b,t as x,u as S}from"./activity-BEWV9er4.js";import{t as C}from"./EmptyState-1sPNleqv.js";import{t as w}from"./usePoll-bDFN-Hr6.js";var T=e(t(),1),E=n(),D=e=>e.catch(()=>null);function O({s:e}){let t=(0,T.useId)(),n=e.todos,r=b(e);return(0,E.jsxs)(`a`,{className:`card pad-md act-card`,href:`#/activity/${encodeURIComponent(e.session_id)}`,"aria-labelledby":`${t}-t ${t}-st`,"aria-describedby":r?`${t}-c`:void 0,children:[(0,E.jsx)(x,{s:e,id:t,heading:e.title||h(e.cwd)||e.session_id,children:(0,E.jsx)(c,{name:`chevron`,className:`glyph act-chev`})}),n&&n.total>0&&(0,E.jsx)(`div`,{className:`act-foot`,children:(0,E.jsxs)(`span`,{className:`row gap-8 dim act-sm`,children:[(0,E.jsx)(y,{done:n.done,total:n.total}),`plan `,n.done,`/`,n.total]})}),(0,E.jsxs)(`div`,{className:`dim mono act-updated`,children:[`updated `,o(e.updated_at),` ago`]})]})}var k=[[`all`,`All`],[`needs`,`Needs you`],[`runs`,`Runs`],[`gates`,`Gate asks`]];function A(){let e=new URLSearchParams(window.location.hash.split(`?`)[1]||``),t=e.get(`f`);return{f:k.some(([e])=>e===t)?t:`all`,host:e.get(`host`)||``,project:e.get(`project`)||``}}function j(e){let t=new URLSearchParams;e.f!==`all`&&t.set(`f`,e.f),e.host&&t.set(`host`,e.host),e.project&&t.set(`project`,e.project);let n=t.toString();window.history.replaceState(null,``,`#/activity${n?`?${n}`:``}`)}function M({enabled:e,onToggle:t}){return(0,E.jsxs)(`section`,{className:`card pad-md act-track`,"aria-labelledby":`act-track-h`,children:[(0,E.jsx)(c,{name:`activity`,className:`glyph act-fixed`}),(0,E.jsxs)(`div`,{className:`act-grow`,children:[(0,E.jsx)(`h2`,{id:`act-track-h`,className:`act-track-title`,children:e?`Live sessions are on`:`Live sessions are off`}),!e&&(0,E.jsx)(`p`,{className:`dim act-sm act-track-p`,children:`Runs and gate asks below come from the job log and the gate ledger. Turn tracking on to see what each session is doing now.`})]}),(0,E.jsxs)(`div`,{className:`row gap-10 act-fixed act-sm`,children:[(0,E.jsx)(`span`,{id:`act-track-l`,children:`Track live sessions`}),(0,E.jsx)(`div`,{className:`sw-toggle${e?` on`:``}`,role:`switch`,"aria-checked":e,"aria-labelledby":`act-track-l`,tabIndex:0,onClick:t,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.key===` `&&e.preventDefault(),t())}})]})]})}function N({jobs:e,loading:t}){let n=typeof e?.cap==`number`?e.cap:void 0,r=g(e?.jobs,{days:14,cap:n}),i=m(r.map(e=>e.nodata?`-`:e.n).join(`,`),`scaleY`),a=Math.max(1,...r.map(e=>e.n)),o=r.reduce((e,t)=>e+t.n,0),s=r.find(e=>!e.nodata),c=r.some(e=>e.nodata),l=`Runs per day: ${r.filter(e=>e.n).map(e=>`${e.n} on ${S(e.key)}`).join(`, `)||`none`}.`+(c?s?` Days before ${S(s.key)} are older than the runs the log keeps.`:` No run is in the log yet.`:``);return(0,E.jsxs)(`section`,{className:`card pad-md act-stat`,"aria-labelledby":`act-runs-h`,children:[(0,E.jsxs)(`div`,{className:`act-stat-head`,children:[(0,E.jsx)(`h2`,{id:`act-runs-h`,className:`act-lbl`,children:`Runs per day · 14 days`}),e&&(0,E.jsx)(`span`,{className:`act-big`,children:o})]}),t?(0,E.jsx)(`p`,{className:`dim act-sm`,children:`Reading the job log…`}):e?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(`div`,{className:`act-runs`,role:`img`,"aria-label":l,ref:i,children:r.map(e=>e.nodata?(0,E.jsx)(`i`,{className:`nodata`},e.key):e.n?(0,E.jsx)(`i`,{"data-sweep":!0,style:{height:`${e.n/a*100}%`},title:`${S(e.key)}: ${e.n}`},e.key):(0,E.jsx)(`i`,{className:`zero`},e.key))}),(0,E.jsxs)(`div`,{className:`mono act-axis`,"aria-hidden":`true`,children:[(0,E.jsx)(`span`,{children:S(r[0].key)}),(0,E.jsx)(`span`,{children:S(r[7].key)}),(0,E.jsx)(`span`,{children:`today`})]}),c&&(0,E.jsxs)(`span`,{className:`dim act-xs`,children:[`Hatched: older than the runs the log keeps`,n?` (last ${n})`:``,`.`]})]}):(0,E.jsx)(`p`,{className:`dim act-sm`,children:`The job log could not be read.`})]})}function ee({rows:e,gates:t,loading:n}){let r=e.reduce((e,t)=>e+t.n,0);return(0,E.jsxs)(`section`,{className:`card pad-md act-stat`,"aria-labelledby":`act-gates-h`,children:[(0,E.jsxs)(`div`,{className:`act-stat-head`,children:[(0,E.jsx)(`h2`,{id:`act-gates-h`,className:`act-lbl`,children:`Gate asks by rule · 30 days`}),t&&(0,E.jsx)(`span`,{className:`act-big`,children:r})]}),n?(0,E.jsx)(`p`,{className:`dim act-sm`,children:`Reading the gate ledger…`}):e.length?(0,E.jsx)(`ul`,{className:`gate-rows`,children:e.slice(0,6).map((e,t)=>(0,E.jsxs)(`li`,{children:[(0,E.jsxs)(`span`,{className:`act-ell`,children:[e.name,` `,(0,E.jsx)(`span`,{className:`mono dim act-xs`,children:e.rule})]}),(0,E.jsx)(_,{vals:e.per_day,i:t,sweep:!0}),(0,E.jsx)(`span`,{className:`mono`,children:e.n})]},e.rule))}):(0,E.jsx)(`p`,{className:`dim act-sm`,children:t?`No gate asked in 30 days.`:`The gate ledger could not be read.`})]})}var P={done:[`ok`,`done`],failed:[`bad`,`failed`],running:[``,`running`]};function F({job:e,longest:t}){let n=f(e),r=e.duration?Math.round(e.duration*10)/10:0,[i,a]=P[e.status]||[``,e.status||`…`],o=e.status===`running`?`Still running`:r?`Took ${r} second${r===1?``:`s`}`:`No duration`,s=e.started?new Date(e.started*1e3).toLocaleTimeString(`en-GB`,{hour:`2-digit`,minute:`2-digit`}):`—`;return(0,E.jsxs)(`li`,{className:`act-row`,children:[(0,E.jsx)(`span`,{className:`mono dim act-xs`,children:s}),(0,E.jsx)(c,{name:`play`,className:`glyph act-glyph`}),(0,E.jsxs)(`span`,{className:`act-what`,children:[(0,E.jsx)(`span`,{className:`act-row-title`,children:n.verb}),n.scope&&(0,E.jsx)(`span`,{className:`dim act-xs act-ell`,title:n.command,children:n.scope})]}),(0,E.jsx)(`span`,{className:`act-dur`,role:`img`,"aria-label":o,children:(0,E.jsx)(`span`,{"data-sweep":!0,style:{width:t>0?`${(e.duration||0)/t*100}%`:`0%`}})}),(0,E.jsx)(`span`,{className:`badge ${i}`,children:a})]})}function I({gate:e}){return(0,E.jsxs)(`li`,{className:`act-row gate`,children:[(0,E.jsx)(`span`,{className:`mono dim act-xs`,children:`—`}),(0,E.jsx)(c,{name:`rule`,className:`glyph act-glyph t-warn`}),(0,E.jsxs)(`span`,{className:`act-what`,children:[(0,E.jsx)(`span`,{className:`act-row-title`,children:e.title}),(0,E.jsx)(`span`,{className:`dim act-xs`,children:`Gate ledger`})]}),(0,E.jsx)(`span`,{className:`act-dur-none`,"aria-hidden":`true`}),(0,E.jsx)(`span`,{className:`badge warn`,children:`asked`})]})}var L=(e,t)=>[...new Set([...e.filter(Boolean),t].filter(Boolean))];function R(){let[e,t]=(0,T.useState)(null),[n,o]=(0,T.useState)(``),[c,f]=(0,T.useState)(A),g=e=>{let t={...c,...e};f(t),j(t)};w(e=>r.activity().then(n=>{e()&&(t(n),o(``))},t=>{e()&&o(t.message)}),2e3,[]);let _=a(()=>D(r.jobs()),[]),y=a(()=>D(r.gates()),[]),b=a(()=>D(r.catalog(`laws`)),[]),x=!e||e.enabled!==!1,S=[...e?.activity||[]].sort((e,t)=>e.session_id<t.session_id?-1:+(e.session_id>t.session_id)),P=u(),R=x&&e?S.filter(p).length:null,z=L(S.map(e=>e.host),c.host),B=L(S.map(e=>h(e.cwd)),c.project),V=c.host&&c.project?`host or project`:c.host?`host`:c.project?`project`:``,H=e=>(!c.host||e.host===c.host)&&(!c.project||h(e.cwd)===c.project),U=S.filter(e=>H(e)&&(c.f!==`needs`||p(e))),W=c.f===`all`||c.f===`needs`,G=!V&&(c.f===`all`||c.f===`runs`),K=!V&&(c.f===`all`||c.f===`gates`),q=_.data?.jobs||[],J=d(y.data,b.data),Y=v(q,J,y.data?.days).map(e=>({...e,runs:G?e.runs:[],gate:K?e.gate:null})).filter(e=>e.runs.length||e.gate),X=Math.max(0,...q.map(e=>e.duration||0)),Z=m(Y.flatMap(e=>e.runs.map(e=>`${e.id}:${e.duration}`)).join(`,`),`scaleX`),Q=async()=>{let e=!x;try{let n=await r.activityToggle(e);if(n.ok===!1){o(n.error||`Could not change tracking`);return}t(e=>({...e||{},enabled:n.enabled,activity:n.enabled&&e?.activity||[]})),o(``)}catch(e){o(e.message)}},$=(e,t,n)=>(0,E.jsxs)(`span`,{className:`row gap-8 act-sm`,children:[(0,E.jsx)(`label`,{htmlFor:`act-f-${e}`,children:t}),(0,E.jsxs)(`select`,{id:`act-f-${e}`,className:`sel`,value:c[e],disabled:n.length===0,title:n.length===0?`No source carries a ${e} yet`:void 0,onChange:t=>g({[e]:t.target.value}),children:[(0,E.jsxs)(`option`,{value:``,children:[`All `,e===`host`?`hosts`:`projects`]}),n.map(e=>(0,E.jsx)(`option`,{value:e,children:e},e))]})]});return(0,E.jsxs)(`div`,{className:`narrow`,children:[(0,E.jsx)(s,{title:`Activity`,sub:`What your agents ran, what the gates asked, and which sessions are waiting on you.`}),n&&(0,E.jsx)(`div`,{className:`act-gap`,children:(0,E.jsx)(l,{error:n})}),e&&(0,E.jsx)(M,{enabled:x,onToggle:Q}),(0,E.jsxs)(`div`,{className:`act-today`,children:[(0,E.jsx)(N,{jobs:_.data,loading:_.loading}),(0,E.jsx)(ee,{rows:J,gates:y.data,loading:y.loading}),(0,E.jsxs)(`section`,{className:`card pad-md act-stat`,"aria-labelledby":`act-wait-h`,children:[(0,E.jsx)(`h2`,{id:`act-wait-h`,className:`act-lbl`,children:`Waiting on you`}),(0,E.jsxs)(`span`,{className:`act-big act-wait`,children:[R??`—`,` `,(0,E.jsx)(`span`,{className:`dim act-sm`,children:`sessions`})]}),(0,E.jsx)(`p`,{className:`dim act-sm`,children:x?`A session that waits on an approval or on your answer counts here.`:`Turn tracking on to count the sessions that wait on you.`})]})]}),(0,E.jsxs)(`div`,{className:`row wrap gap-8 act-filters`,children:[(0,E.jsx)(`div`,{role:`group`,"aria-label":`Filter`,className:`row wrap gap-8`,children:k.map(([e,t])=>(0,E.jsxs)(`button`,{type:`button`,className:c.f===e?`chip-f on`:`chip-f`,"aria-pressed":c.f===e,onClick:()=>g({f:e}),children:[t,e===`needs`&&R>0?(0,E.jsxs)(`span`,{className:`mono`,children:[` `,R]}):null]},e))}),$(`host`,`Host`,z),$(`project`,`Project`,B)]}),V&&c.f!==`needs`&&(0,E.jsxs)(`p`,{className:`dim act-sm`,children:[`Runs and gate asks carry no `,V,`; showing sessions only.`]}),W&&(e?!x&&c.f!==`needs`?null:U.length===0?c.f===`needs`?(0,E.jsx)(C,{title:`Nothing waits on you`}):(0,E.jsxs)(C,{title:`No active sessions`,children:[`Run `,(0,E.jsx)(`code`,{children:`opencode`}),` and the sessions it spins up appear here.`]}):(0,E.jsx)(`div`,{className:`stack gap-12 act-live`,ref:P,children:U.map(e=>(0,E.jsx)(`div`,{"data-flip":e.session_id,children:(0,E.jsx)(O,{s:e})},e.session_id))}):(0,E.jsx)(i,{label:`Reading live sessions…`})),c.f!==`needs`&&(0,E.jsx)(`section`,{"aria-label":`Feed`,className:`stack gap-16 act-feed`,ref:Z,children:Y.map(e=>(0,E.jsxs)(`section`,{className:`card act-day`,children:[(0,E.jsxs)(`h3`,{className:`act-day-h`,children:[(0,E.jsx)(`span`,{children:e.title}),(0,E.jsx)(`span`,{className:`mono dim`,children:e.sum})]}),(0,E.jsxs)(`ul`,{className:`act-rows`,children:[e.runs.map(e=>(0,E.jsx)(F,{job:e,longest:X},e.id)),e.gate&&(0,E.jsx)(I,{gate:e.gate})]})]},e.key))})]})}export{R as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{i as t,t as n}from"./react-DlYQp10C.js";import{t as r}from"./api-BfpZmUMI.js";import{A as i,K as a,T as o,V as s,k as c}from"./index-Dwo3Gxek.js";import{a as l,i as u,t as d}from"./activity-BEWV9er4.js";import{t as f}from"./EmptyState-1sPNleqv.js";import{t as p}from"./usePoll-bDFN-Hr6.js";var m=e(t(),1),h=n();function g(e){return e.kind===`tool`?e.status===`error`?`bad`:e.status===`completed`?`ok`:`acc`:{retry:`warn`,error:`bad`,subtask:`acc`,text:`acc`}[e.kind]||``}function _({rec:e}){let t=e.who===`you`,n=[];t||(e.kind===`tool`&&e.ms!=null&&n.push(`${(e.ms/1e3).toFixed(1)}s`),e.kind===`step`&&(e.tokens&&n.push(`${l(e.tokens)} tok`),e.cost&&n.push(`$${e.cost.toFixed(2)}`)),e.kind===`subtask`&&e.agent&&n.unshift(e.agent));let r=!t&&(e.kind===`text`||e.kind===`thinking`||e.kind===`step`),i=t?e.text:e.label||e.snippet||e.kind;return(0,h.jsxs)(`div`,{className:`row gap-10 act-line`,children:[(0,h.jsx)(`span`,{className:`badge act-who ${t?``:`acc`}`,children:t?`you`:`agent`}),(0,h.jsxs)(`div`,{className:`act-grow act-sm`,children:[!t&&(0,h.jsx)(`span`,{className:`feed-dot act-inline-dot ${g(e)||`acc`}`}),e.kind===`thinking`&&(0,h.jsx)(`span`,{className:`dim`,children:`thinking: `}),r?(0,h.jsx)(`span`,{className:`dim`,children:i}):t?i:(0,h.jsx)(`b`,{children:i}),e.error&&(0,h.jsxs)(`span`,{className:`dim`,children:[`: `,e.error]})]}),n.length>0&&(0,h.jsx)(`span`,{className:`dim mono act-xs act-fixed`,children:n.join(` · `)}),e.t?(0,h.jsx)(`time`,{className:`mono dim act-xs act-fixed`,dateTime:new Date(e.t).toISOString(),title:`${a(e.t/1e3)} ago`,children:new Date(e.t).toTimeString().slice(0,8)}):null]})}function v({turns:e}){return!e||e.length===0?(0,h.jsx)(`div`,{className:`dim act-sm`,children:`No conversation captured yet.`}):(0,h.jsx)(`div`,{className:`stack gap-12`,children:e.map((e,t)=>{let n=e.role===`user`;return(0,h.jsxs)(`div`,{className:`row gap-10 act-line`,children:[(0,h.jsx)(`span`,{className:`badge act-who ${n?``:`acc`}`,children:n?`you`:`agent`}),(0,h.jsx)(`div`,{className:`act-min act-sm${n?``:` muted`}`,children:e.text})]},t)})})}function y({sid:e}){let[t,n]=(0,m.useState)(null),[l,g]=(0,m.useState)(``),[y,b]=(0,m.useState)(!1),[x,S]=(0,m.useState)(!1),C=(0,m.useId)();p(t=>y?void 0:r.activityDetail(e).then(e=>{t()&&(n(e),g(``),b(!1))},e=>{t()&&(e.status===404?b(!0):g(e.message))}),2e3,[e,y]);let w=(0,h.jsxs)(`a`,{className:`btn ghost sm act-back`,href:`#/activity`,children:[(0,h.jsx)(s,{name:`arrow`}),` Activity`]});if(y)return(0,h.jsxs)(`div`,{className:`narrow`,children:[w,(0,h.jsx)(f,{title:`Session ended`,action:(0,h.jsx)(`a`,{href:`#/activity`,children:`Back to Activity`}),children:`It's no longer live.`})]});if(!t)return(0,h.jsxs)(`div`,{className:`narrow`,children:[w,l?(0,h.jsx)(c,{error:l}):(0,h.jsx)(i,{label:`Loading session…`})]});let T=t.session,E=T.files,D=T.todos,O=!!(E&&E.items&&E.items.length>0),k=!!(D&&D.items&&D.items.length>0),A=t.conversation||[],j=t.timeline||[],M=[...A.filter(e=>e.role===`user`).map(e=>({who:`you`,text:e.text,t:e.t||0})),...j.map(e=>({...e,who:`agent`}))].sort((e,t)=>(e.t||0)-(t.t||0));return(0,h.jsxs)(`div`,{className:`narrow`,children:[w,(0,h.jsx)(o,{title:T.title||u(T.cwd)||T.session_id,sub:T.cwd?(0,h.jsx)(`span`,{className:`mono act-cwd`,title:T.cwd,children:T.cwd}):null}),l&&(0,h.jsx)(`div`,{className:`act-gap`,children:(0,h.jsx)(c,{error:l})}),(0,h.jsxs)(`div`,{className:`card pad-md`,children:[(0,h.jsx)(d,{s:T}),(0,h.jsxs)(`div`,{className:`dim act-updated`,children:[`updated `,a(T.updated_at),` ago`]})]}),(O||k)&&(0,h.jsxs)(`div`,{className:`grid gap-12 act-panels${O&&k?` two`:``}`,children:[O&&(0,h.jsxs)(`div`,{className:`card pad-md`,children:[(0,h.jsx)(`div`,{className:`card-head`,children:(0,h.jsxs)(`h2`,{children:[`Files touched `,(0,h.jsxs)(`span`,{className:`dim`,children:[`(`,E.count,`)`]})]})}),(0,h.jsx)(`div`,{className:`stack act-list`,children:E.items.map(e=>(0,h.jsxs)(`div`,{className:`row between gap-12 act-sm`,children:[(0,h.jsx)(`span`,{className:`mono act-ell act-grow`,title:e.file,children:e.file}),(0,h.jsxs)(`span`,{className:`act-fixed`,children:[(0,h.jsxs)(`span`,{className:`t-good`,children:[`+`,e.additions]}),` `,(0,h.jsxs)(`span`,{className:`t-bad`,children:[`−`,e.deletions]})]})]},e.file))})]}),k&&(0,h.jsxs)(`div`,{className:`card pad-md`,children:[(0,h.jsx)(`div`,{className:`card-head`,children:(0,h.jsxs)(`h2`,{children:[`Plan`,` `,(0,h.jsxs)(`span`,{className:`dim`,children:[`(`,D.done,`/`,D.total,`)`]})]})}),(0,h.jsx)(`div`,{className:`stack act-list`,children:D.items.map((e,t)=>(0,h.jsxs)(`div`,{className:`row gap-8 act-sm`,children:[(0,h.jsx)(`span`,{className:`feed-dot ${e.status===`completed`?`ok`:e.status===`in_progress`?`acc`:``}`}),(0,h.jsx)(`span`,{className:e.status===`completed`?`act-done`:void 0,children:e.content})]},t))})]})]}),(0,h.jsxs)(`div`,{className:`card pad-md act-mt`,children:[(0,h.jsxs)(`div`,{className:`card-head act-tl-head`,children:[(0,h.jsx)(`h2`,{children:`Timeline`}),j.length>0&&(0,h.jsx)(`button`,{className:`btn ghost sm`,"aria-expanded":x,"aria-controls":C,onClick:()=>S(e=>!e),children:x?`Show conversation`:`Show full stream (${M.length})`})]}),(0,h.jsx)(`div`,{id:C,children:x?(0,h.jsx)(`div`,{className:`stack gap-12`,children:M.map((e,t)=>(0,h.jsx)(_,{rec:e},t))}):(0,h.jsx)(v,{turns:A})})]})]})}export{y as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/GreenhouseView-BCiZP9f9.js","assets/rolldown-runtime-hePW80VL.js","assets/react-DlYQp10C.js","assets/sections-ChwaobfW.js","assets/index-Dwo3Gxek.js","assets/api-BfpZmUMI.js","assets/index-CDSHv_7s.css","assets/jobBuckets-Dpjvbfm1.js","assets/OperatorHudView-BLXm0zzn.js","assets/JournalView-BSR51TKR.js","assets/drawable-ixCquffB.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{n as e,r as t}from"./rolldown-runtime-hePW80VL.js";import{i as n,t as r}from"./react-DlYQp10C.js";import{t as i}from"./api-BfpZmUMI.js";import{t as a}from"./drawable-ixCquffB.js";import{n as o,r as s}from"./sections-ChwaobfW.js";import{A as c,G as l,J as u,K as d,M as f,O as p,U as m,V as h,W as g,at as _,ft as v,it as y,k as b,l as x,lt as S,ot as C,rt as w,t as T,tt as E,w as D}from"./index-Dwo3Gxek.js";import{r as O}from"./jobBuckets-Dpjvbfm1.js";var k=t(n(),1),A=r();function j({segments:e,value:t,max:n,size:r=120,stroke:i=12,label:o,sweepMs:s=650}){let c=n>0?n:0,l=e||[{key:`v`,label:o,n:Math.min(Math.max(t||0,0),c),tone:`accent`}],u=e?l.reduce((e,t)=>e+t.n,0):c,d=e?l.map(e=>`${e.label}: ${e.n} of ${u}`).join(`, `):`${l[0].n} of ${u}`,f=r/2-i/2,p=r/2,m=e=>[p+f*Math.cos(e),p+f*Math.sin(e)],h=[],g=0;for(let e of l)h.push(g),g+=e.n;let b=(0,k.useRef)(null),x=l.map(e=>e.n).join(`,`);return(0,k.useLayoutEffect)(()=>{let e=b.current?.querySelectorAll(`path.ring-arc`);if(!s||!e?.length||!y())return;let t=l.map(e=>e.n/u).filter(e=>e>0),n=t.map((e,n)=>t.slice(0,n).reduce((e,t)=>e+t,0)),r=a(e);S(r,{draw:`0 0`});let i=v(r,{draw:[`0 0`,`0 1`],duration:(e,n)=>Math.max(s*t[n],60),delay:(e,t)=>s*n[t],ease:`linear`});return _(i,s)},[x,s]),(0,A.jsxs)(`svg`,{className:`ring`,width:r,height:r,viewBox:`0 0 ${r} ${r}`,role:`img`,"aria-label":o?`${o}: ${d}`:d,children:[(0,A.jsx)(`circle`,{className:`ring-track`,cx:p,cy:p,r:f,fill:`none`,strokeWidth:i}),(0,A.jsx)(`g`,{ref:b,children:u>0?l.map((e,t)=>{let n=e.n/u;if(!(n>0))return null;let r=h[t]/u*2*Math.PI-Math.PI/2,a=r+n*2*Math.PI,[o,s]=m(r),[c,l]=m(a),d=n>=.9999?`M ${o} ${s} A ${f} ${f} 0 1 1 ${2*p-o} ${2*p-s} A ${f} ${f} 0 1 1 ${o} ${s}`:`M ${o} ${s} A ${f} ${f} 0 ${+(n>.5)} 1 ${c} ${l}`;return(0,A.jsx)(`path`,{className:`ring-arc tone-${e.tone||`muted`}`,d,fill:`none`,strokeWidth:i,children:(0,A.jsxs)(`title`,{children:[e.label,`: `,e.n]})},e.key)}):null})]})}var M={neutral:`Loaded & ready`,imperial:`The Codex in force`,military:`The unit stands ready`,cyberpunk:`Jacked in`,wizard:`Wards in place`,pirate:`The crew stands ready`,gamer:`Game loaded`,sports:`The squad takes the field`,biker:`The crew rolls out`,commentator:`Lights out, away we go`,verstappen:`Setup's in`,joker:`Mic check`,mean:`Rules are up`,marvin:`Online. Reluctantly.`},N=(e,t)=>e.deployed?t===void 0||t===`good`?M[e.theme]||`Loaded & ready`:`Deployed`:`Not deployed`,P={good:`ok`,warn:`warn`,bad:`bad`};function F({verdict:e}){return e?(0,A.jsxs)(`span`,{className:`badge ${P[e.tone]}`,role:`status`,style:{alignSelf:`flex-start`},children:[(0,A.jsx)(`span`,{className:`dot`}),e.head]}):null}function I({overview:e,dataRev:t}){let{data:n}=u(()=>Promise.resolve().then(()=>i.catalog(`laws`)),[t],`catalog:laws`),r=m(e.diff),a=e.counts||{},o=[{key:`agents`,label:`Agents`,hash:`#/agents`},{key:`skills`,label:`Skills`,hash:`#/skills`},{key:`laws`,label:n?.nouns?.laws||`Dictates`,hash:`#/laws`}];return(0,A.jsxs)(`div`,{className:`card kpiband rise mb-16`,children:[o.map(e=>{let t=a[e.key];return(0,A.jsxs)(`a`,{className:`kseg`,href:e.hash,title:`Open ${e.label}`,children:[(0,A.jsx)(`span`,{className:`kseg-n`+(t===0?` zero`:``),children:t==null?`—`:(0,A.jsx)(w,{value:t})}),(0,A.jsx)(`span`,{className:`kseg-l`,children:e.label})]},e.key)}),(0,A.jsx)(`div`,{className:`kseg-spacer`}),(0,A.jsxs)(`button`,{className:`kseg`+(r>0?` hot`:``),onClick:()=>E(`#/diff`),title:`Open changes`,children:[(0,A.jsx)(`span`,{className:`kseg-n`+(r===0?` zero`:``),children:(0,A.jsx)(w,{value:r})}),(0,A.jsx)(`span`,{className:`kseg-l`,children:`Local edits`}),r>0&&(0,A.jsx)(`span`,{className:`delta up`,children:`▲`})]})]})}function L({overview:e}){return(0,A.jsx)(`div`,{className:`genome`,children:s.map((t,n)=>{let r=o[t],i=e.counts?.[t];return(0,A.jsxs)(`div`,{className:`card gcell rise`,style:{"--i":n},onClick:()=>E(`#/section/`+t),children:[(0,A.jsxs)(`div`,{className:`gtop`,children:[(0,A.jsx)(`span`,{className:`gname`,children:r.label}),(0,A.jsx)(h,{name:r.icon,className:`gicon`})]}),(0,A.jsx)(`div`,{className:`gcount`+(i===0?` zero`:``),children:i==null?`—`:(0,A.jsx)(w,{value:i})}),(0,A.jsx)(`div`,{className:`gdesc`,children:r.desc})]},t)})})}function R({jobs:e}){if(!e||e.length===0)return(0,A.jsx)(`div`,{className:`feed`,children:(0,A.jsxs)(`div`,{className:`empty`,children:[(0,A.jsx)(`div`,{className:`big`,children:`No activity yet`}),`Actions you run appear here.`]})});let t={done:`ok`,running:`acc`,failed:`bad`},n=O(e,8);return(0,A.jsx)(`div`,{className:`feed`,children:n.map(e=>(0,A.jsxs)(`div`,{className:`feed-row`,children:[(0,A.jsx)(`span`,{className:`feed-dot ${t[e.status]||`ok`}`}),(0,A.jsx)(`span`,{className:`feed-txt`,children:(0,A.jsx)(`b`,{children:e.action})}),(0,A.jsxs)(`span`,{className:`feed-when`,children:[d(e.started),` ago`]})]},e.id))})}function z({value:e}){let t=C(e,1100)??0,n=Math.round(t*100);return(0,A.jsxs)(`div`,{className:`ring-box`,children:[(0,A.jsx)(j,{value:n,max:100,label:`germination`,size:232,stroke:10,sweepMs:0}),(0,A.jsxs)(`div`,{className:`ring-center`,children:[(0,A.jsxs)(`div`,{className:`pct`,children:[n,(0,A.jsx)(`span`,{className:`pct-unit`,children:`%`})]}),(0,A.jsx)(`div`,{className:`lbl`,children:`germination`})]})]})}function B({overview:e,sigil:t,setup:n,jobs:r,lens:i,dataRev:a}){let o=N(e,i?.tone),c=l(e,n,i?.tone);return(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`div`,{className:`card pad-lg rise mb-16`,children:(0,A.jsxs)(`div`,{className:`hero`,children:[(0,A.jsx)(z,{value:c}),(0,A.jsxs)(`div`,{className:`hero-facts`,children:[(0,A.jsx)(`div`,{className:`ttl`,children:o}),(0,A.jsx)(F,{verdict:i?.verdict}),t&&(0,A.jsxs)(`div`,{className:`voice-readout`,children:[(0,A.jsx)(`span`,{className:`vr-cur`,children:`▕`}),(0,A.jsx)(`span`,{className:`vr-txt`,children:t})]},e.theme),(0,A.jsxs)(`p`,{className:`sub`,children:[`One source rendered into `,(0,A.jsx)(`code`,{children:e.target}),`. Every repo on this machine inherits it.`]}),(0,A.jsxs)(`div`,{className:`hero-chips`,children:[(0,A.jsxs)(`span`,{className:`chip`,children:[(0,A.jsx)(`span`,{className:`ck`,children:`voice`}),(0,A.jsx)(`span`,{className:`cv t-cap`,children:e.theme})]}),(0,A.jsxs)(`span`,{className:`chip`,children:[(0,A.jsx)(`span`,{className:`ck`,children:`mode`}),(0,A.jsx)(`span`,{className:`cv`,children:e.emit})]}),(0,A.jsxs)(`span`,{className:`chip`,children:[(0,A.jsx)(`span`,{className:`ck`,children:`footprint`}),(0,A.jsx)(`span`,{className:`cv`,children:e.footprint})]}),(0,A.jsxs)(`span`,{className:`chip`,children:[(0,A.jsx)(`span`,{className:`ck`,children:`built`}),(0,A.jsx)(`span`,{className:`cv`,children:e.build_time||`unknown`})]}),(0,A.jsxs)(`span`,{className:`chip`,children:[(0,A.jsx)(`span`,{className:`ck`,children:`fp`}),(0,A.jsx)(`span`,{className:`cv`,children:n?.installed_fp||`—`})]})]})]})]})}),(0,A.jsx)(I,{overview:e,dataRev:a}),(0,A.jsxs)(`div`,{className:`grid split-status`,children:[(0,A.jsxs)(`div`,{className:`card pad-lg`,children:[(0,A.jsxs)(`div`,{className:`card-head`,children:[(0,A.jsx)(`h3`,{children:`Capability genome`}),(0,A.jsx)(`div`,{className:`right`,children:(0,A.jsxs)(`span`,{className:`tick`,children:[s.length,` sections`]})})]}),(0,A.jsx)(L,{overview:e})]}),(0,A.jsxs)(`div`,{className:`card pad-lg`,children:[(0,A.jsxs)(`div`,{className:`card-head`,children:[(0,A.jsx)(`h3`,{children:`Recent activity`}),(0,A.jsx)(`div`,{className:`right`,children:(0,A.jsxs)(`span`,{className:`badge acc`,children:[(0,A.jsx)(`span`,{className:`dot`}),`live`]})})]}),(0,A.jsx)(R,{jobs:r})]})]})]})}function V({k:e,overview:t,max:n}){let r=o[e],i=t.counts?.[e]??0;return(0,A.jsxs)(`div`,{className:`strand`,children:[(0,A.jsxs)(`span`,{className:`strand-name`,children:[(0,A.jsx)(`span`,{className:`strand-dot`}),(0,A.jsx)(`a`,{href:`#/section/`+e,className:`strand-link stretch-link`,children:r.label})]}),(0,A.jsx)(`div`,{className:`hbar`,children:(0,A.jsx)(`i`,{style:{width:`${i/n*100}%`}})}),(0,A.jsx)(`span`,{className:`strand-val`,children:i})]})}function H(e){return e?e.includes(`up to date`)?{label:`in sync`,tone:`ok`}:e.includes(`no Geneseed install`)?{label:`not installed`,tone:``}:{label:`behind source`,tone:`warn`}:null}function U({overview:e,sigil:t,setup:n,jobs:r,lens:i}){let a=g(e.counts),o=n?.version_verdict||``,c=H(o),l=m(e.diff),u=[[`Source`,`src/, the canonical genetic material`,n?.source_fp||`—`,!0],[`Render`,`geneseed build → ${e.emit}`,e.theme+` voice`,!0],[`Deployed`,e.target,`inherited by every repo`,!1]];return(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`div`,{className:`mb-16`,children:(0,A.jsxs)(`div`,{className:`card pad-lg rise`,style:{position:`relative`,overflow:`hidden`},children:[(0,A.jsx)(`h2`,{className:`h`,style:{fontSize:22,margin:`0 0 18px`},children:`Gene-seed lineage`}),(0,A.jsxs)(`div`,{className:`lineage-track`,children:[(0,A.jsx)(`div`,{className:`spine`}),u.map(([e,t,n,r],i)=>(0,A.jsxs)(`div`,{className:`lineage-step`,children:[(0,A.jsx)(`span`,{className:`node ${r?`on`:``}`}),(0,A.jsx)(`div`,{className:`lt`,children:e}),(0,A.jsx)(`div`,{className:`ld`,children:t}),(0,A.jsx)(`div`,{className:`ltag`,children:n})]},i))]}),(0,A.jsx)(`hr`,{className:`hr`}),t&&(0,A.jsxs)(`div`,{className:`voice-readout`,style:{marginBottom:14},children:[(0,A.jsx)(`span`,{className:`vr-cur`,children:`▕`}),(0,A.jsx)(`span`,{className:`vr-txt`,children:t})]},e.theme),(0,A.jsxs)(`div`,{className:`row wrap gap-10`,children:[(0,A.jsx)(F,{verdict:i?.verdict}),c&&(0,A.jsxs)(`span`,{className:`badge ${c.tone}`,title:o,children:[(0,A.jsx)(`span`,{className:`dot`}),c.label]}),(0,A.jsxs)(`span`,{className:`badge`,children:[(0,A.jsx)(`span`,{className:`dot`}),l,` local edits`]})]})]})}),(0,A.jsxs)(`div`,{className:`grid split-even`,children:[(0,A.jsxs)(`div`,{className:`card pad-lg`,children:[(0,A.jsxs)(`div`,{className:`card-head`,children:[(0,A.jsx)(`h3`,{children:`Genome strand`}),(0,A.jsx)(`div`,{className:`right`,children:(0,A.jsx)(`span`,{className:`tick`,children:`by volume`})})]}),s.map(t=>(0,A.jsx)(V,{k:t,overview:e,max:a},t))]}),(0,A.jsxs)(`div`,{className:`card pad-lg`,children:[(0,A.jsx)(`div`,{className:`card-head`,children:(0,A.jsx)(`h3`,{children:`Recent activity`})}),(0,A.jsx)(R,{jobs:r})]})]})]})}function W({overview:e,setup:t,jobs:n,lens:r}){let i=s.reduce((t,n)=>t+(e.counts?.[n]??0),0),a=g(e.counts),c=e.doctor?.ok,l=e.doctor?.problems?.length??0,u=m(e.diff);return(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`div`,{className:`card pad-md rise mb-16`,children:(0,A.jsx)(`div`,{className:`row wrap between gap-16`,children:(0,A.jsxs)(`div`,{className:`row`,style:{gap:20,flexWrap:`wrap`},children:[(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`div`,{className:`tick`,children:`status`}),(0,A.jsxs)(`div`,{className:`row`,style:{gap:8,marginTop:4},children:[(0,A.jsxs)(`span`,{className:`badge ${e.deployed?`ok`:`warn`}`,children:[(0,A.jsx)(`span`,{className:`dot`}),e.deployed?`deployed`:`not deployed`]}),(0,A.jsx)(F,{verdict:r?.verdict})]})]}),(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`div`,{className:`tick`,children:`voice`}),(0,A.jsx)(`div`,{className:`metric`,style:{fontSize:18,marginTop:6,textTransform:`capitalize`},children:e.theme})]}),(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`div`,{className:`tick`,children:`mode`}),(0,A.jsx)(`div`,{className:`mono`,style:{fontSize:14,marginTop:6},children:e.emit})]}),(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`div`,{className:`tick`,children:`fingerprint`}),(0,A.jsx)(`div`,{className:`mono`,style:{fontSize:14,marginTop:6,color:`var(--accent)`},children:t?.installed_fp||`—`})]}),(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`div`,{className:`tick`,children:`doctor`}),(0,A.jsx)(`div`,{className:`row`,style:{gap:8,marginTop:4},children:c?(0,A.jsxs)(`span`,{className:`badge ok`,children:[(0,A.jsx)(`span`,{className:`dot`}),`clean`]}):(0,A.jsxs)(`span`,{className:`badge warn`,children:[(0,A.jsx)(`span`,{className:`dot`}),l,` issue`,l===1?``:`s`]})})]}),(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`div`,{className:`tick`,children:`edits`}),(0,A.jsx)(`div`,{className:`metric`,style:{fontSize:18,marginTop:6},children:u})]})]})})}),(0,A.jsxs)(`div`,{className:`grid split-operator`,children:[(0,A.jsxs)(`div`,{className:`card rise`,style:{"--i":1},children:[(0,A.jsxs)(`div`,{className:`card-head pad-lg`,style:{padding:`18px 20px 0`,marginBottom:14},children:[(0,A.jsx)(`h3`,{children:`Sections`}),(0,A.jsx)(`div`,{className:`right`,children:(0,A.jsxs)(`span`,{className:`tick`,children:[i,` entries total`]})})]}),(0,A.jsxs)(`table`,{className:`tbl`,children:[(0,A.jsx)(`thead`,{children:(0,A.jsxs)(`tr`,{children:[(0,A.jsx)(`th`,{children:`Section`}),(0,A.jsx)(`th`,{children:`Detail`}),(0,A.jsx)(`th`,{style:{width:130},children:`Share`}),(0,A.jsx)(`th`,{className:`num`,children:`Count`})]})}),(0,A.jsx)(`tbody`,{children:s.map(t=>{let n=o[t],r=e.counts?.[t]??0;return(0,A.jsxs)(`tr`,{className:`clickable`,children:[(0,A.jsx)(`td`,{className:`name`,children:(0,A.jsx)(`a`,{href:`#/section/`+t,className:`stretch-link`,children:n.label})}),(0,A.jsx)(`td`,{className:`muted`,children:n.desc}),(0,A.jsx)(`td`,{children:(0,A.jsx)(`div`,{className:`hbar`,children:(0,A.jsx)(`i`,{style:{width:`${r/a*100}%`}})})}),(0,A.jsx)(`td`,{className:`num`,children:r})]},t)})})]})]}),(0,A.jsxs)(`div`,{className:`card pad-lg rise`,style:{"--i":2},children:[(0,A.jsx)(`div`,{className:`card-head`,children:(0,A.jsx)(`h3`,{children:`Run log`})}),(0,A.jsx)(R,{jobs:n})]})]})]})}var G=Symbol(`failed`),K=e=>Promise.resolve().then(e).catch(()=>G);function q({dataRev:e,needDoctor:t}){let n=u(()=>K(()=>i.fleet()),[e]),r=u(()=>t?K(()=>i.doctor()):Promise.resolve(null),[t,e]),a=n.data,o=a==null?`loading`:a===G?`failed`:`ok`,s=o===`ok`?a:null,c=s?x(s):null,l=r.data,d=t?l==null?`loading`:l===G?`failed`:`ok`:`idle`;return{fleet:s,fleetState:o,verdict:c,tone:o===`failed`?`failed`:c?.tone,doctor:{state:d,data:d===`ok`?r.data:null}}}var J=e({default:()=>Q}),Y=(0,k.lazy)(()=>T(()=>import(`./GreenhouseView-BCiZP9f9.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]))),X=(0,k.lazy)(()=>T(()=>import(`./OperatorHudView-BLXm0zzn.js`),__vite__mapDeps([8,1,2,3,4,5,6,7]))),Z=(0,k.lazy)(()=>T(()=>import(`./JournalView-BSR51TKR.js`),__vite__mapDeps([9,1,2,5,10,4,3,6])));function Q({overview:e,overviewError:t,onRetry:n,themes:r,setup:a,runs:o,onAction:s,layout:l=`cultivar`,dataRev:d}){let m=l,[h,g]=(0,k.useState)(`status`),_=e&&r.find(t=>t.name===e.theme)?.sigil||``,v=q({dataRev:d,needDoctor:m===`greenhouse`||m===`operator`}),{data:y}=u(()=>m===`journal`?i.recent().catch(()=>null):Promise.resolve(null),[m,d]);if(!e)return t?(0,A.jsx)(b,{error:`Could not load the harness overview: ${t}`,onRetry:n}):(0,A.jsx)(c,{});let x=e.daemon_stale?(0,A.jsx)(p,{}):null;return e.deployed?h===`status`&&m===`journal`?(0,A.jsxs)(k.Suspense,{fallback:(0,A.jsx)(c,{}),children:[x,(0,A.jsx)(Z,{overview:e,recent:y,lens:v,onDirection:g,dataRev:d})]}):(0,A.jsxs)(A.Fragment,{children:[x,(0,A.jsx)(`div`,{className:`head-row`,children:(0,A.jsx)(f,{"aria-label":`Dashboard view`,children:[[`status`,`Status`],[`lineage`,`Lineage`],[`operator`,`Operator`,`Operator data`]].map(([e,t,n])=>(0,A.jsx)(`button`,{className:h===e?`on`:``,onClick:()=>g(e),"aria-pressed":h===e,"aria-label":n,children:t},e))})}),(0,A.jsxs)(`div`,{className:`view-in`,children:[h===`status`&&m===`cultivar`&&(0,A.jsx)(B,{overview:e,sigil:_,setup:a,jobs:o,lens:v,dataRev:d}),h===`status`&&m===`greenhouse`&&(0,A.jsx)(k.Suspense,{fallback:(0,A.jsx)(c,{}),children:(0,A.jsx)(Y,{overview:e,sigil:_,jobs:o,lens:v,onAction:s})}),h===`status`&&m===`operator`&&(0,A.jsx)(k.Suspense,{fallback:(0,A.jsx)(c,{}),children:(0,A.jsx)(X,{overview:e,jobs:o,lens:v})}),h===`lineage`&&(0,A.jsx)(U,{overview:e,sigil:_,setup:a,jobs:o,lens:v}),h===`operator`&&(0,A.jsx)(W,{overview:e,setup:a,jobs:o,lens:v})]},h)]}):(0,A.jsxs)(A.Fragment,{children:[x,(0,A.jsx)(D,{onAction:s})]})}export{Q as default,j as i,F as n,N as r,J as t};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{i as t,t as n}from"./react-DlYQp10C.js";import{t as r}from"./api-BfpZmUMI.js";import{A as i,F as a,I as o,J as s,M as c,P as l,T as u,V as d,a as f,c as p,i as m,k as h,n as g,o as _,r as v,s as ee,tt as y}from"./index-Dwo3Gxek.js";import{t as b}from"./EmptyState-1sPNleqv.js";import{a as te,n as ne,o as x,r as S,t as C}from"./RailCats-DNlJKicm.js";import{i as w,n as T,r as E}from"./Markdown-OReRRoEV.js";var D=e(t(),1);function O(e,t=0){let n=String(e).toLowerCase().trim().replace(/[^a-z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-+|-+$/g,``);return n&&/^[a-z]/.test(n)?n:`h-${t}-${n||`section`}`}function k(e){let t=[],n=[],r=`before`;for(let i of(e||``).split(`
|
|
2
|
+
`))r===`before`&&/^\|\s*piece\s*\|/i.test(i)?r=`map`:r===`map`&&!i.trimStart().startsWith(`|`)&&(r=`after`),r===`before`?t.push(i):r===`after`&&n.push(i);return[t.join(`
|
|
3
|
+
`),n.join(`
|
|
4
|
+
`)]}function A(e,t){let n=document.createElement(`template`);return n.innerHTML=e,n.content.querySelectorAll(`h1, h2, h3`).forEach(e=>{e.tagName!==`H1`&&(t.idx+=1);let n=e.id||O(e.textContent||``,t.idx),r=n;for(let e=2;t.ids.has(r);e++)r=`${n}-${e}`;t.ids.add(r),e.id=r,e.tagName!==`H1`&&t.toc.push({level:Number(e.tagName[1]),title:(e.textContent||``).trim(),id:r})}),n.content.querySelectorAll(`table`).forEach(e=>{let t=document.createElement(`div`);t.className=`table-scroll`,t.setAttribute(`tabindex`,`0`),t.setAttribute(`role`,`region`),t.setAttribute(`aria-label`,`Table`),e.replaceWith(t),t.appendChild(e)}),n.innerHTML}function j(e){let t={ids:new Set,idx:0,toc:[]},n=n=>A(T(n,e?.links),t);if(e?.rows){let[r,i]=k(e.body);return{before:n(r),after:n(i),toc:t.toc}}return{html:n(e?.body),toc:t.toc}}var M=n(),N={"opencode-global":[`install-opencode`,`Global (recommended)`],opencode:[`install-opencode`,`Per repo`],"claude-global":[`install-claude-code`],claude:[`install-claude-code`],"openclaude-global":[`install-openclaude`],openclaude:[`install-openclaude`],"bob-global":[`install-bob`],bob:[`install-bob`],files:[`install-agent-md`]},P=`you already know this`;function F({page:e,overview:t,onAction:n}){let r=(0,D.useRef)(null),i=(0,D.useMemo)(()=>j({body:e.body,links:e.links}).html,[e.body,e.links]);(0,D.useEffect)(()=>{let e=r.current;e&&e.querySelectorAll(`blockquote`).forEach(e=>{(e.querySelector(`strong`)?.textContent||``).toLowerCase().startsWith(P)&&e.classList.add(`analogy`)})},[i]),(0,D.useEffect)(()=>{let e=r.current;if(!e)return;let t=e=>{let t=e.target.closest(`a[href]`);if(!t)return;let n=t.getAttribute(`href`);n&&n.startsWith(`#/`)&&(e.preventDefault(),y(n))};return e.addEventListener(`click`,t),()=>e.removeEventListener(`click`,t)},[i]),(0,D.useEffect)(()=>{let n=r.current;if(!n)return;n.querySelectorAll(`.docs-here`).forEach(e=>e.classList.remove(`docs-here`));let[i,a]=N[t?.emit]||[];if(!i)return;let o=null;e.id===`install`?o=n.querySelector(`a[href="#/docs/${i}"]`)?.closest(`li`):e.id===i&&a&&(o=[...n.querySelectorAll(`h2`)].find(e=>O(e.textContent||``)===O(a))),o?.classList.add(`docs-here`)},[i,e.id,t?.emit]);let a=[];return e.id===`install`&&(a.push({label:`Run doctor`,action:`doctor`}),a.push({label:`Rebuild`,action:`build`})),e.id===`verify`&&a.push({label:`Run doctor`,action:`doctor`}),e.id===`upgrade`&&a.push({label:`Update`,action:`update`}),(0,M.jsxs)(`div`,{className:`detail-doc`,children:[(0,M.jsx)(u,{title:e.title,actions:a.length>0&&a.map(e=>e.hash?(0,M.jsx)(`a`,{className:`btn ghost sm`,href:e.hash,children:e.label},e.label):(0,M.jsx)(`button`,{className:`btn ghost sm`,onClick:()=>n&&n(e.action),children:e.label},e.label))}),e.source&&(0,M.jsx)(`div`,{className:`doc-meta`,children:(0,M.jsxs)(`span`,{className:`badge`,children:[(0,M.jsx)(`span`,{className:`dot`}),e.source]})}),(0,M.jsx)(`div`,{className:`markdown`,ref:r,dangerouslySetInnerHTML:{__html:i}}),e.link&&(0,M.jsx)(`div`,{className:`doc-link`,children:(0,M.jsx)(`a`,{className:`btn soft sm`,href:e.link.hash,children:e.link.label})})]})}var I=e=>`cmd-`+String(e).replace(/[^\w-]+/g,`-`),L=1200;function R({a:e,kind:t}){let n=t===`positional`?e.dest:e.names.join(`, `),r=[];return e.metavar&&r.push(e.metavar),e.choices&&r.push(`{${e.choices.join(`|`)}}`),e.default!==null&&e.default!==void 0&&e.default!==``&&!e.is_flag&&r.push(`default: ${e.default}`),e.required&&r.push(`required`),(0,M.jsxs)(`div`,{className:`cli-arg`,children:[(0,M.jsx)(`code`,{className:`cli-arg-name`,children:n}),r.length>0&&(0,M.jsxs)(`code`,{className:`cli-arg-meta`,children:[` `,r.join(` · `)]}),e.help&&(0,M.jsx)(`div`,{className:`cli-arg-help`,children:e.help})]})}function z({text:e}){let[t,n]=(0,D.useState)(!1);return(0,M.jsxs)(`button`,{className:`btn ghost sm`,onClick:async()=>{try{await navigator.clipboard.writeText(e),n(!0),setTimeout(()=>n(!1),L)}catch{}},title:`Copy command`,children:[(0,M.jsx)(d,{name:t?`spark`:`copy`}),t?`Copied`:`Copy`]})}function B({cmd:e,prog:t}){let n=[t,e.name];for(let t of e.positionals||[]){let e=(t.metavar||t.dest||``).toUpperCase();n.push(t.required?e:`[${e}]`)}(e.options||[]).length&&n.push(`[OPTIONS]`);let r=n.join(` `);return(0,M.jsxs)(`div`,{className:`card pad-md mb-12 cli-card`,children:[(0,M.jsxs)(`div`,{className:`row wrap between cli-head`,children:[(0,M.jsxs)(`div`,{className:`stack gap-4`,children:[(0,M.jsx)(`h2`,{id:I(e.name),children:(0,M.jsx)(`code`,{children:e.name})}),e.help&&(0,M.jsx)(`p`,{className:`sub`,children:e.help})]}),(0,M.jsx)(z,{text:`${t} ${e.name}`})]}),(0,M.jsx)(`pre`,{className:`cli-syn`,children:r}),(e.positionals||[]).length>0&&(0,M.jsxs)(`div`,{className:`cli-block`,children:[(0,M.jsx)(`div`,{className:`cli-block-head`,children:`Arguments`}),e.positionals.map(e=>(0,M.jsx)(R,{a:e,kind:`positional`},e.dest))]}),(e.options||[]).length>0&&(0,M.jsxs)(`div`,{className:`cli-block`,children:[(0,M.jsx)(`div`,{className:`cli-block-head`,children:`Options`}),e.options.map(e=>(0,M.jsx)(R,{a:e,kind:`option`},e.names.join(`,`)))]})]})}function V({page:e}){let t=e.prog||`geneseed`,n=e.commands||[];return(0,M.jsxs)(`div`,{className:`detail-doc`,children:[(0,M.jsx)(u,{title:e.title,sub:(0,M.jsxs)(M.Fragment,{children:[`Every subcommand of `,(0,M.jsx)(`code`,{children:t}),`. Generated from the parser at request time (the same one `,(0,M.jsx)(`code`,{children:`geneseed`}),` actually parses), so this page cannot drift.`]})}),(0,M.jsx)(`div`,{children:n.map(e=>(0,M.jsx)(B,{cmd:e,prog:t},e.name))})]})}function H({page:e}){let t=e.rows||[],n=e.theme||`neutral`;return(0,M.jsxs)(`div`,{className:`detail-doc`,children:[(0,M.jsx)(u,{title:e.title,sub:(0,M.jsxs)(M.Fragment,{children:[`Geneseed's invented vocabulary, decoded. Left: the neutral, plain-English term. Right: the word your `,(0,M.jsx)(`code`,{className:`cap`,children:n}),` theme actually uses in the agent's voice. Last: the developer idea it maps to.`]})}),(0,M.jsx)(`div`,{className:`card pad-md`,children:(0,M.jsxs)(`table`,{className:`glossary-table`,children:[(0,M.jsx)(`thead`,{children:(0,M.jsxs)(`tr`,{children:[(0,M.jsx)(`th`,{children:`Concept`}),(0,M.jsx)(`th`,{children:`Neutral term`}),(0,M.jsxs)(`th`,{children:[`In `,n]}),(0,M.jsx)(`th`,{children:`Meaning`}),(0,M.jsx)(`th`,{children:`In dev terms`})]})}),(0,M.jsx)(`tbody`,{children:t.map(e=>(0,M.jsxs)(`tr`,{children:[(0,M.jsx)(`td`,{children:(0,M.jsx)(`strong`,{children:e.label})}),(0,M.jsx)(`td`,{children:(0,M.jsx)(`code`,{children:e.neutral||`—`})}),(0,M.jsx)(`td`,{children:(0,M.jsx)(`code`,{children:e.themed||e.neutral||`—`})}),(0,M.jsx)(`td`,{className:`dim`,children:e.desc}),(0,M.jsx)(`td`,{className:`dim`,children:e.analogy||`—`})]},e.label))})]})})]})}var U={enforced:`ok`,automatic:`ok`,asked:`warn`,"on demand":`warn`},W=({text:e})=>(0,M.jsx)(`span`,{dangerouslySetInnerHTML:{__html:E(w.parseInline(e||``))}}),G=({kind:e})=>(0,M.jsx)(`span`,{className:`tag ${U[e]||``}`,children:e});function K({page:e,overview:t,onAction:n}){let[r,i]=(0,D.useState)(0),{before:a,after:o}=(0,D.useMemo)(()=>j(e),[e]);if(!e.rows)return(0,M.jsx)(F,{page:e,overview:t,onAction:n});let s=e.rows[r]||e.rows[0];return(0,M.jsxs)(`div`,{className:`detail-doc`,children:[(0,M.jsx)(u,{title:e.title}),(0,M.jsx)(`div`,{className:`markdown`,dangerouslySetInnerHTML:{__html:a}}),(0,M.jsxs)(`div`,{className:`docs-map`,children:[(0,M.jsx)(`ul`,{className:`map-tree`,"aria-label":`Pieces`,children:e.rows.map((e,t)=>(0,M.jsx)(`li`,{children:(0,M.jsxs)(`button`,{className:`map-node ${t===r?`on`:``}`,"aria-pressed":t===r,onClick:()=>i(t),children:[(0,M.jsx)(`span`,{className:`map-piece`,children:(0,M.jsx)(W,{text:e.piece})}),(0,M.jsx)(G,{kind:e.kind}),(0,M.jsx)(`span`,{className:`mono dim map-cost`,children:(0,M.jsx)(W,{text:e.cost})})]})},t))}),s&&(0,M.jsxs)(`div`,{className:`card pad-md map-detail`,"aria-live":`polite`,children:[(0,M.jsx)(`h2`,{children:(0,M.jsx)(W,{text:s.piece})}),(0,M.jsx)(G,{kind:s.kind}),(0,M.jsxs)(`dl`,{children:[(0,M.jsx)(`dt`,{children:`Does`}),(0,M.jsx)(`dd`,{children:(0,M.jsx)(W,{text:s.does})}),(0,M.jsx)(`dt`,{children:`Costs`}),(0,M.jsx)(`dd`,{children:(0,M.jsx)(W,{text:s.cost})}),(0,M.jsx)(`dt`,{children:`Turn it off`}),(0,M.jsx)(`dd`,{children:(0,M.jsx)(W,{text:s.off})})]})]})]}),o.trim()&&(0,M.jsx)(`div`,{className:`markdown`,dangerouslySetInnerHTML:{__html:o}})]})}var q=5,J=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);function Y(e,t){let n=e||``,r=[];for(let e of t||[])if([...new Set([e.themed,e.neutral,e.label].filter(Boolean))].some(e=>RegExp(`(?<![\\w-])${J(e)}s?(?![\\w-])`,`i`).test(n))&&r.push(e),r.length===q)break;return r}var X=e=>document.getElementById(e)?.scrollIntoView({behavior:`smooth`});function Z({page:e,glossaryRows:t}){let n=e?.body,r=(0,D.useMemo)(()=>e?.kind===`cli`?(e.commands||[]).map(e=>({id:I(e.name),title:e.name,level:2})):j(e).toc,[e]),i=(0,D.useMemo)(()=>Y(n,t),[n,t]);return!r.length&&!i.length?null:(0,M.jsxs)(`aside`,{className:`docs-margin`,children:[r.length>0&&(0,M.jsxs)(`nav`,{className:`docs-toc`,"aria-label":`On this page`,children:[(0,M.jsx)(`div`,{className:`docs-toc-head`,children:`On this page`}),(0,M.jsx)(`ul`,{children:r.map(e=>(0,M.jsx)(`li`,{className:`lvl-${e.level}`,children:(0,M.jsx)(`a`,{href:`#${e.id}`,onClick:t=>{t.preventDefault(),X(e.id)},children:e.title})},e.id))})]}),i.length>0&&(0,M.jsxs)(`div`,{className:`docs-gloss`,children:[(0,M.jsx)(`div`,{className:`docs-toc-head`,children:`Terms on this page`}),i.map(e=>(0,M.jsxs)(`div`,{className:`docs-gloss-card`,children:[(0,M.jsx)(`b`,{children:e.themed||e.neutral||e.label}),(0,M.jsx)(`p`,{children:e.desc})]},e.label))]})]})}function re({page:e}){let t=e.version||{},n=[[`Theme`,e.theme],[`Install mode`,e.emit],[`Deployed`,e.deployed?`yes`:`no`],[`Target`,(0,M.jsx)(`code`,{children:e.target},`t`)],[`Source root`,(0,M.jsx)(`code`,{children:e.root},`r`)],[`Installed build`,(0,M.jsx)(`code`,{children:t.installed_fp||`(none)`},`i`)],[`Source build`,(0,M.jsx)(`code`,{children:t.source_fp||`—`},`s`)],[`Match?`,t.verdict||`—`],[`License`,e.license]];return(0,M.jsxs)(`div`,{className:`detail-doc`,children:[(0,M.jsx)(u,{title:e.title,sub:`Live snapshot of the install behind this UI, plus where to go next.`}),(0,M.jsx)(`div`,{className:`card pad-md mb-18`,children:n.map(([e,t])=>(0,M.jsxs)(`div`,{className:`kv`,children:[(0,M.jsx)(`span`,{className:`k`,children:e}),(0,M.jsx)(`span`,{className:`v`,children:t??`—`})]},e))}),(0,M.jsxs)(`div`,{className:`row wrap gap-10`,children:[(0,M.jsxs)(`a`,{className:`btn ghost`,href:e.repo,target:`_blank`,rel:`noreferrer`,children:[(0,M.jsx)(d,{name:`external`}),e.repo_is_github?`GitHub repo`:`Source repo`]}),e.repo_is_github&&(0,M.jsxs)(M.Fragment,{children:[(0,M.jsxs)(`a`,{className:`btn ghost`,href:`${e.repo}/issues`,target:`_blank`,rel:`noreferrer`,children:[(0,M.jsx)(d,{name:`external`}),`File an issue`]}),(0,M.jsxs)(`a`,{className:`btn ghost`,href:`${e.repo}/blob/main/LICENSE`,target:`_blank`,rel:`noreferrer`,children:[(0,M.jsx)(d,{name:`external`}),`License`]})]})]})]})}function Q(e){return e?.groups?.[0]?.pages?.[0]?.id||``}function ie({data:e,error:t,overview:n,onAction:r}){if(t)return(0,M.jsx)(h,{error:t,style:{margin:18}});if(!e)return(0,M.jsx)(i,{label:`Loading page…`});switch(e.kind){case`markdown`:case`concept`:return(0,M.jsx)(F,{page:e,overview:n,onAction:r});case`map`:return(0,M.jsx)(K,{page:e,overview:n,onAction:r});case`cli`:return(0,M.jsx)(V,{page:e});case`glossary`:return(0,M.jsx)(H,{page:e});case`about`:return(0,M.jsx)(re,{page:e});default:return(0,M.jsx)(b,{title:`Unknown page kind`,children:e.kind})}}function $(e){return(e?.pages||[]).map(e=>({name:e.id,title:e.title,desc:e.description||``,group:e.section||`General`,groupC:`var(--accent)`}))}function ae({page:e,overview:t,onAction:n}){let[u,d]=o(a(t?.emit)),{data:y,error:b}=s(()=>r.docs(u),[u]),w=e||Q(y),{data:T,error:E,loading:O}=s(()=>w?r.docsPage(w,u):Promise.resolve(null),[w,u]),{data:k}=s(()=>r.docsPage(`glossary`,u).catch(()=>null),[u],`docs:glossary`);(0,D.useEffect)(()=>{if(y&&w&&!y.groups.some(e=>e.pages.some(e=>e.id===w))){let e=Q(y);e&&e!==w&&window.location.replace(f(e))}},[y,w]),(0,D.useEffect)(()=>{let e=document.scrollingElement||document.documentElement;for(let t of[document.getElementById(`main`),e])t&&(t.scrollTop=0)},[w]);let A=ee(y,w),j=A.part||y?.groups?.[0]||null,N=j?.id===v;(0,D.useEffect)(()=>{N&&T?.id===w&&_(w)},[N,T,w]);let P=N?[...p(),w]:[],[F,I]=(0,D.useState)(``),[L,R]=(0,D.useState)(`all`),[z,B]=(0,D.useState)(j?.id);j?.id!==z&&(B(j?.id),I(``),R(`all`));let V=$(j),H=ne(V),U=L===`all`?V:V.filter(e=>e.group===L),W=x(U,F);return b?(0,M.jsx)(h,{error:b}):(0,M.jsx)(`div`,{className:`docs-wrap`,children:(0,M.jsxs)(`div`,{className:`library docs-lib`,children:[(0,M.jsxs)(`aside`,{className:`lib-kinds`,"aria-label":`Docs parts`,children:[(0,M.jsxs)(`div`,{className:`lib-title`,children:[(0,M.jsx)(`p`,{className:`h`,children:`Docs`}),(0,M.jsx)(`span`,{className:`dim`,children:`How it works, and how to use it`})]}),(0,M.jsx)(c,{"aria-label":`Harness`,children:l.map(e=>(0,M.jsx)(`button`,{className:u===e.id?`on`:``,onClick:()=>d(e.id),"aria-pressed":u===e.id,children:e.label},e.id))}),(0,M.jsx)(`nav`,{className:`kind-list`,"aria-label":`Parts`,children:(y?.groups||[]).map(e=>(0,M.jsxs)(D.Fragment,{children:[(0,M.jsxs)(`a`,{href:e.pages[0]?f(e.pages[0].id):`#/docs`,className:j?.id===e.id?`on`:``,"aria-current":j?.id===e.id?`page`:void 0,children:[e.label,(0,M.jsx)(`span`,{className:`mono dim`,children:e.pages.length})]}),j?.id===e.id&&(0,M.jsx)(C,{label:`Sections`,total:V.length,cats:H,cat:L,onChange:R})]},e.id))})]}),(0,M.jsx)(te,{label:j?.label||`Docs`,count:F.trim()?`${W.length} of ${U.length}`:U.length||``,extra:N&&(0,M.jsx)(m,{pages:j.pages,seen:P}),q:F,onQ:I,matched:W.length,inView:[j?.id,w],children:y?(0,M.jsx)(S,{rows:W,activeName:w,hrefOf:e=>f(e.name),pills:N?e=>P.includes(e.name)&&e.name!==w?(0,M.jsx)(`span`,{className:`docs-read-mark`,role:`img`,"aria-label":`, read`,children:`✓`}):null:void 0}):(0,M.jsx)(i,{label:`Loading docs…`})}),(0,M.jsxs)(`article`,{className:`lib-reader docs-reader`,"aria-label":`Page`,children:[A.page&&(0,M.jsxs)(`nav`,{className:`docs-crumbs mono`,"aria-label":`Breadcrumb`,children:[(0,M.jsx)(`a`,{href:f(A.part.pages[0].id),children:A.part.label}),(0,M.jsx)(`span`,{"aria-hidden":`true`,children:`›`}),(0,M.jsx)(`a`,{href:f(A.part.pages.find(e=>(e.section||`General`)===A.section).id),children:A.section}),(0,M.jsx)(`span`,{"aria-hidden":`true`,children:`›`}),(0,M.jsx)(`span`,{"aria-current":`page`,children:A.page.title})]}),(0,M.jsxs)(`div`,{className:`docs-read`,children:[(0,M.jsxs)(`div`,{className:`docs-article`,children:[(0,M.jsx)(ie,{data:O?null:T,error:E,overview:t,onAction:n},`${w}|${u}`),!O&&(0,M.jsx)(g,{menu:y,pageId:w})]}),!O&&(0,M.jsx)(Z,{page:T,glossaryRows:k?.rows})]})]})]})})}export{ae as default,$ as docRows};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./rolldown-runtime-hePW80VL.js";import{i as e,t}from"./react-DlYQp10C.js";e();var n=t();function r({title:e,children:t,action:r,docs:i}){return(0,n.jsxs)(`div`,{className:`empty`,children:[e?(0,n.jsx)(`div`,{className:`big`,children:e}):null,t?(0,n.jsx)(`div`,{children:t}):null,r||i?(0,n.jsxs)(`div`,{className:`empty-actions`,children:[r,i?(0,n.jsx)(`a`,{href:i.href,children:i.label}):null]}):null]})}export{r as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./rolldown-runtime-hePW80VL.js";import{i as e,t}from"./react-DlYQp10C.js";import{n,r}from"./sections-ChwaobfW.js";import{K as i,U as a,V as o,rt as s}from"./index-Dwo3Gxek.js";import{n as c,r as l,t as u}from"./jobBuckets-Dpjvbfm1.js";import{i as d,n as f,r as p}from"./Dashboard-BZmw2a7d.js";e();var m=t(),h=12,g=[`#2BB673`,`#16A6A6`,`#E8A23B`,`#E07A5F`,`#8E7DBE`,`#5BD08A`,`#79856E`],_=650;function v({segments:e,size:t=186,stroke:n=26,caption:r=`capabilities`}){let i=e.reduce((e,t)=>e+t.n,0);return(0,m.jsxs)(`div`,{className:`ring-box`,children:[(0,m.jsx)(d,{segments:e,size:t,stroke:n,label:r,sweepMs:_}),(0,m.jsxs)(`div`,{className:`ring-center`,children:[(0,m.jsx)(`div`,{className:`donut-c-num`,children:(0,m.jsx)(s,{value:i,duration:_})}),(0,m.jsx)(`div`,{className:`donut-c-cap`,children:r})]})]})}function y(e){if(e.length<2)return e.length?`M${e[0][0]},${e[0][1]}`:``;let t=`M${e[0][0]},${e[0][1]}`;for(let n=0;n<e.length-1;n++){let r=e[n-1]||e[n],i=e[n],a=e[n+1],o=e[n+2]||a,s=i[0]+(a[0]-r[0])/6,c=i[1]+(a[1]-r[1])/6,l=a[0]-(o[0]-i[0])/6,u=a[1]-(o[1]-i[1])/6;t+=` C${s},${c} ${l},${u} ${a[0]},${a[1]}`}return t}function b({data:e,height:t=156,accent:n}){if(!e.length)return null;let r=t,i=Math.max(...e.map(e=>e.v),1)+1,a=e.length>1?588/(e.length-1):588,o=e.map((e,t)=>[6+t*a,r-6-e.v/i*(r-14-6)]),s=y(o),c=o[o.length-1],l=o[0],u=`${s} L${c[0]},${r} L${l[0]},${r} Z`;return(0,m.jsxs)(`svg`,{viewBox:`0 0 600 ${r}`,preserveAspectRatio:`none`,style:{width:`100%`,height:t,display:`block`,overflow:`visible`},children:[(0,m.jsx)(`defs`,{children:(0,m.jsxs)(`linearGradient`,{id:`b-grad`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,m.jsx)(`stop`,{offset:`0`,stopColor:n,stopOpacity:`.28`}),(0,m.jsx)(`stop`,{offset:`1`,stopColor:n,stopOpacity:`0`})]})}),(0,m.jsx)(`path`,{d:u,fill:`url(#b-grad)`}),(0,m.jsx)(`path`,{d:s,fill:`none`,stroke:n,strokeWidth:`2`,strokeLinejoin:`round`,strokeLinecap:`round`,vectorEffect:`non-scaling-stroke`}),(0,m.jsx)(`circle`,{cx:c[0],cy:c[1],r:`3.5`,fill:n,vectorEffect:`non-scaling-stroke`})]})}function x({label:e,value:t,sub:n,color:r,icon:i}){return(0,m.jsxs)(`div`,{className:`b-tile`,children:[(0,m.jsx)(`span`,{className:`b-tile-ic`,style:{background:`color-mix(in srgb, ${r} 18%, transparent)`,color:r},children:(0,m.jsx)(o,{name:i})}),(0,m.jsxs)(`div`,{className:`b-tile-body`,children:[(0,m.jsx)(`div`,{className:`b-tile-val`+(t===0?` zero`:``),children:t}),(0,m.jsx)(`div`,{className:`b-tile-label`,children:e})]}),(0,m.jsx)(`div`,{className:`b-tile-sub`,children:n})]})}function S({overview:e,sigil:t,jobs:d,lens:_,onAction:y}){let S=e.counts||{},C=_?.doctor?.state||`loading`,w=_?.doctor?.data?.groups||[],T=C===`ok`,E=w.filter(e=>e.problems.length===0).length,D=w.length,O=p(e,_?.tone),k=l(d,h),A=a(e.diff),j=r.filter(e=>(S[e]||0)>0).map((e,t)=>({key:e,label:n[e].label,n:S[e]||0,tone:`cat`+t%g.length,color:g[t%g.length]})),M=j.reduce((e,t)=>e+t.n,0),N=u(d||[],10),P=N.reduce((e,t)=>e+t.v,0);return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:`b-greet`,children:(0,m.jsxs)(`div`,{children:[(0,m.jsx)(`div`,{className:`eyebrow`,children:`your harness`}),(0,m.jsx)(`h2`,{className:`h b-h`,children:O}),(0,m.jsx)(f,{verdict:_?.verdict}),(0,m.jsx)(`p`,{className:`sub`,children:t||`A friendly read of every layer growing in your harness.`})]})}),(0,m.jsxs)(`div`,{className:`grid b-hero-grid mb-16`,children:[(0,m.jsxs)(`div`,{className:`card b-hero`,children:[(0,m.jsx)(`div`,{className:`b-hero-ring`,children:(0,m.jsx)(v,{segments:[{key:`pass`,label:`pass`,n:E,tone:`good`},{key:`attention`,label:`attention`,n:Math.max(D-E,0),tone:`warn`}],size:168,stroke:20,caption:`checks`})}),(0,m.jsxs)(`div`,{className:`b-hero-side`,children:[(0,m.jsx)(`h3`,{className:`b-hero-title`,children:T?`${E} of ${D} checks pass`:C===`failed`?`Doctor did not answer`:`Checking…`}),C===`failed`&&(0,m.jsxs)(`button`,{className:`btn ghost b-hero-retry`,"aria-label":`Run doctor again`,onClick:()=>y(`doctor`),children:[(0,m.jsx)(o,{name:`doctor`}),`Run doctor`]}),(0,m.jsxs)(`p`,{className:`sub`,children:[`One source, rendered into `,(0,m.jsx)(`code`,{children:e.target}),` and inherited by every repo on this machine.`]}),T&&(0,m.jsx)(`ul`,{className:`b-hero-checks`,children:w.map(e=>{let t=e.problems.length===0;return(0,m.jsxs)(`li`,{className:`b-hcheck ${t?`ok`:`bad`}`,title:t?`clean`:e.problems.join(`; `),children:[(0,m.jsx)(`span`,{className:`b-hcheck-mark`,children:t?`✓`:`!`}),(0,m.jsx)(`span`,{className:`b-hcheck-label`,children:e.label})]},e.label)})}),(0,m.jsxs)(`div`,{className:`b-chips`,children:[(0,m.jsxs)(`span`,{className:`b-chip`,children:[(0,m.jsx)(`b`,{className:`t-cap`,children:e.theme}),` voice`]}),(0,m.jsx)(`span`,{className:`b-chip`,children:(0,m.jsx)(`b`,{children:e.emit})}),(0,m.jsxs)(`span`,{className:`b-chip`,children:[`built `,(0,m.jsx)(`b`,{children:e.build_time||`unknown`})]})]})]})]}),(0,m.jsxs)(`div`,{className:`b-tiles`,children:[(0,m.jsx)(x,{label:`Agents`,value:S.agents??`—`,sub:`specialists`,color:g[0],icon:`layers`}),(0,m.jsx)(x,{label:`Skills`,value:S.skills??`—`,sub:`workflows`,color:g[1],icon:`skill`}),(0,m.jsx)(x,{label:`Dictates`,value:S.laws??`—`,sub:S.doctrines?`${S.doctrines.active}/${S.doctrines.total} packs · ${S.doctrines.rules} rules`:`all upheld`,color:g[2],icon:`law`}),(0,m.jsx)(x,{label:`Edits`,value:A,sub:`to graft`,color:g[3],icon:`changes`})]})]}),(0,m.jsxs)(`div`,{className:`grid split-even mb-16`,children:[(0,m.jsxs)(`div`,{className:`card pad-lg b-mix-card`,children:[(0,m.jsxs)(`div`,{className:`card-head`,children:[(0,m.jsx)(`h3`,{children:`Capability mix`}),(0,m.jsx)(`div`,{className:`right`,children:(0,m.jsxs)(`span`,{className:`tick`,children:[M,` total`]})})]}),(0,m.jsxs)(`div`,{className:`b-mix`,children:[(0,m.jsx)(v,{segments:j,size:186,stroke:26}),(0,m.jsx)(`div`,{className:`b-legend`,children:j.map(e=>(0,m.jsxs)(`div`,{className:`b-leg-row`,children:[(0,m.jsx)(`span`,{className:`b-leg-dot`,style:{background:e.color}}),(0,m.jsx)(`span`,{className:`b-leg-name`,children:e.label}),(0,m.jsx)(`span`,{className:`b-leg-bar`,children:(0,m.jsx)(`i`,{style:{width:`${e.n/M*100}%`,background:e.color}})}),(0,m.jsx)(`span`,{className:`b-leg-val`,children:e.n})]},e.label))})]})]}),(0,m.jsxs)(`div`,{className:`card pad-lg`,children:[(0,m.jsxs)(`div`,{className:`card-head`,children:[(0,m.jsx)(`h3`,{children:`Recent runs`}),(0,m.jsx)(`div`,{className:`right`,children:(0,m.jsxs)(`span`,{className:`badge ok`,children:[(0,m.jsx)(`span`,{className:`dot`}),`job log`]})})]}),(0,m.jsxs)(`div`,{className:`b-stat-lead`,children:[(0,m.jsx)(`span`,{className:`b-stat-big`,children:(0,m.jsx)(s,{value:P})}),(0,m.jsxs)(`span`,{className:`b-stat-cap`,children:[`runs in the last 10 days`,T&&D>0&&` · ${E}/${D} checks pass now`]})]}),(0,m.jsx)(b,{data:N,accent:g[0],height:156})]})]}),(0,m.jsxs)(`div`,{className:`card pad-lg`,children:[(0,m.jsxs)(`div`,{className:`card-head`,children:[(0,m.jsx)(`h3`,{children:`Recent activity`}),(0,m.jsx)(`div`,{className:`right`,children:(0,m.jsxs)(`span`,{className:`tick`,children:[`last `,k.length,` runs`]})})]}),(0,m.jsxs)(`div`,{className:`b-timeline`,children:[k.map(e=>{let t=e.status===`done`,n=e.status===`failed`?`warn`:t?`ok`:`acc`,r=c(e);return(0,m.jsxs)(`div`,{className:`b-tl-row`,children:[(0,m.jsx)(`span`,{className:`b-tl-node ${n}`}),(0,m.jsxs)(`div`,{className:`b-tl-body`,title:r.command||void 0,children:[(0,m.jsx)(`b`,{children:r.verb}),[r.scope,r.result,r.duration].map(e=>e?` · ${e}`:``).join(``)]}),(0,m.jsx)(`span`,{className:`b-tl-when`,children:e.started?`${i(e.started)} ago`:`—`})]},e.id)}),(!d||d.length===0)&&(0,m.jsxs)(`div`,{className:`b-tl-row`,children:[(0,m.jsx)(`span`,{className:`b-tl-node`}),(0,m.jsx)(`div`,{className:`b-tl-body sub`,children:`No runs yet. Trigger an action to populate this.`}),(0,m.jsx)(`span`,{className:`b-tl-when`,children:`—`})]})]})]})]})}export{S as default};
|