@ucsandman/legcli 0.8.0 → 0.10.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.
Files changed (125) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/NOTICE +8 -0
  3. package/README.md +639 -560
  4. package/bin/fake-agent.mjs +4 -4
  5. package/bin/leg.mjs +43 -12
  6. package/docs/DECISIONS.md +20 -2
  7. package/docs/ERRORS.md +205 -0
  8. package/docs/README.md +5 -1
  9. package/docs/REUSE.md +1 -1
  10. package/docs/VOCABULARY.md +22 -0
  11. package/docs/board-guide.md +33 -1
  12. package/docs/cli-contracts.md +36 -1
  13. package/docs/concepts.md +42 -3
  14. package/docs/configuration.md +23 -1
  15. package/docs/faq.md +19 -0
  16. package/docs/getting-started.md +272 -251
  17. package/docs/harness.md +319 -0
  18. package/docs/history.md +172 -0
  19. package/docs/runtime-tap.md +156 -0
  20. package/fixtures/verified.json +1 -1
  21. package/package.json +7 -3
  22. package/scripts/build-docs-site.mjs +18 -4
  23. package/scripts/check-branding.mjs +118 -0
  24. package/scripts/check-claims.mjs +1 -1
  25. package/scripts/license-sign.mjs +1 -1
  26. package/scripts/limits-table.mjs +1 -1
  27. package/scripts/live-limits.mjs +1 -1
  28. package/scripts/npm-publish-gate.mjs +114 -0
  29. package/scripts/probe.mjs +4 -3
  30. package/scripts/seed-fake-cards.mjs +4 -3
  31. package/scripts/seed-floor-board.mjs +5 -4
  32. package/scripts/seed-wes-board.mjs +5 -4
  33. package/scripts/stripe-setup.mjs +1 -1
  34. package/scripts/sync-harness-engine.mjs +159 -0
  35. package/scripts/sync-leg-agents.mjs +127 -0
  36. package/src/accounts.mjs +6 -4
  37. package/src/adapters/codex.mjs +1 -1
  38. package/src/attach.mjs +125 -23
  39. package/src/auth.mjs +2 -2
  40. package/src/board/board.css +23 -1
  41. package/src/board/board.js +17 -5
  42. package/src/board/history.js +377 -0
  43. package/src/board/index.html +33 -0
  44. package/src/board/sessions.js +95 -7
  45. package/src/bundle.mjs +54 -8
  46. package/src/chain.mjs +1 -1
  47. package/src/contract.mjs +4 -3
  48. package/src/fsx.mjs +5 -2
  49. package/src/handoff.mjs +6 -6
  50. package/src/harness/cli.mjs +281 -0
  51. package/src/harness/fingerprint.mjs +68 -0
  52. package/src/harness/index.mjs +407 -0
  53. package/src/harness/registry.mjs +124 -0
  54. package/src/harness/vendor/agnostic-ai/LICENSE +21 -0
  55. package/src/harness/vendor/agnostic-ai/UPSTREAM.json +30 -0
  56. package/src/harness/vendor/agnostic-ai/core/safety/guards.json +96 -0
  57. package/src/harness/vendor/agnostic-ai/core/templates/targets.json +252 -0
  58. package/src/harness/vendor/agnostic-ai/engine/harness/README.md +199 -0
  59. package/src/harness/vendor/agnostic-ai/engine/harness/apply.cjs +247 -0
  60. package/src/harness/vendor/agnostic-ai/engine/harness/bundle.cjs +243 -0
  61. package/src/harness/vendor/agnostic-ai/engine/harness/capture.cjs +119 -0
  62. package/src/harness/vendor/agnostic-ai/engine/harness/common.cjs +375 -0
  63. package/src/harness/vendor/agnostic-ai/engine/harness/index.cjs +55 -0
  64. package/src/harness/vendor/agnostic-ai/engine/harness/sources/claude.cjs +330 -0
  65. package/src/harness/vendor/agnostic-ai/engine/harness/sources/codex.cjs +314 -0
  66. package/src/harness/vendor/agnostic-ai/engine/harness/status.cjs +171 -0
  67. package/src/harness/vendor/agnostic-ai/engine/harness/targets/agy.cjs +113 -0
  68. package/src/harness/vendor/agnostic-ai/engine/harness/targets/claude.cjs +158 -0
  69. package/src/harness/vendor/agnostic-ai/engine/harness/targets/codex.cjs +832 -0
  70. package/src/harness/vendor/agnostic-ai/engine/harness/targets/cursor.cjs +87 -0
  71. package/src/harness/vendor/agnostic-ai/engine/harness/targets/gemini.cjs +128 -0
  72. package/src/harness/vendor/agnostic-ai/engine/harness/targets/generic.cjs +424 -0
  73. package/src/harness/vendor/agnostic-ai/engine/harness/toml.cjs +149 -0
  74. package/src/harness/vendor/agnostic-ai/engine/hooks/shim.cjs +431 -0
  75. package/src/history/cli.mjs +159 -0
  76. package/src/history/common.mjs +119 -0
  77. package/src/history/index.mjs +429 -0
  78. package/src/history/providers/agy.mjs +91 -0
  79. package/src/history/providers/claude.mjs +161 -0
  80. package/src/history/providers/codex.mjs +133 -0
  81. package/src/history/providers/copilot.mjs +94 -0
  82. package/src/history/providers/grok.mjs +138 -0
  83. package/src/history/worktrees.mjs +116 -0
  84. package/src/hook.mjs +49 -49
  85. package/src/land.mjs +7 -35
  86. package/src/launcher.mjs +38 -26
  87. package/src/ledger.mjs +6 -6
  88. package/src/license.mjs +10 -9
  89. package/src/live-capture.mjs +1 -1
  90. package/src/mergequeue.mjs +5 -5
  91. package/src/orchestrator.mjs +28 -4
  92. package/src/preferences.mjs +37 -3
  93. package/src/redact.mjs +24 -6
  94. package/src/resume.mjs +17 -15
  95. package/src/runner.mjs +2 -2
  96. package/src/scheduler.mjs +1 -1
  97. package/src/server.mjs +224 -18
  98. package/src/session-detail.mjs +15 -1
  99. package/src/sessions.mjs +15 -3
  100. package/src/share.mjs +2 -2
  101. package/src/stations/agent.mjs +1 -1
  102. package/src/sync/dashclaw.mjs +4 -4
  103. package/src/synthesis.mjs +165 -0
  104. package/src/taps/agy.mjs +2 -2
  105. package/src/taps/claude-usage.mjs +1 -1
  106. package/src/taps/claude.mjs +177 -170
  107. package/src/taps/codex.mjs +286 -286
  108. package/src/taps/grok.mjs +2 -2
  109. package/src/taps/mod.mjs +340 -0
  110. package/src/trust.mjs +205 -36
  111. package/src/usage.mjs +5 -1
  112. package/src/worktree.mjs +6 -5
  113. package/fixtures/live/agy/attempt-1-scratch-workspace.out.log +0 -1
  114. package/fixtures/live/agy/err.log +0 -0
  115. package/fixtures/live/agy/out.log +0 -1
  116. package/fixtures/live/agy/supervisor.log +0 -2
  117. package/fixtures/live/claude/err.log +0 -0
  118. package/fixtures/live/claude/out.log +0 -1
  119. package/fixtures/live/claude/supervisor.log +0 -2
  120. package/fixtures/live/codex/err.log +0 -1
  121. package/fixtures/live/codex/out.log +0 -8
  122. package/fixtures/live/codex/supervisor.log +0 -2
  123. package/fixtures/live/grok/err.log +0 -32
  124. package/fixtures/live/grok/out.log +0 -7
  125. package/fixtures/live/grok/supervisor.log +0 -2
package/CHANGELOG.md CHANGED
@@ -1,7 +1,125 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.0 (2026-09-17)
4
+
5
+ - **The board is responsive again, `leg` starts straight away, and the board
6
+ opens every time.** One running terminal was enough to saturate the board
7
+ server: it rewrites its record every few seconds and takes a control lock
8
+ about once a second, and the watcher over the sessions directory rebuilt the
9
+ whole terminals view — over a second of `git` — for every one of those
10
+ touches, including the lock files and the temp files atomic writes leave
11
+ behind. The server spent all its time in that loop, so it answered a
12
+ stylesheet in fourteen seconds and `/api/health` in seven. Four consequences,
13
+ all fixed:
14
+ - The watcher now drops locks and temp files by name, and checks the rest
15
+ against a stat fingerprint of the files the view is actually built from,
16
+ because a lock taken inside a session directory changes that directory's
17
+ own mtime and arrives as an event naming nothing else. What survives is
18
+ floored to one rebuild per interval. `canLand` is cached per record
19
+ revision with staggered expiries, so twenty worktrees are never re-read in
20
+ one pass. The terminals view went from 2,000 ms to 115 ms; on a board with
21
+ 66 sessions `/api/health` went from 14.2 s to 2.4 ms and `/board.css` from
22
+ 14.2 s to 1.5 ms.
23
+ - `leg claude` treated a board too busy to answer a health probe as no board
24
+ at all, spawned a second server that could only die of `EADDRINUSE`, then
25
+ polled the dead child for fifteen seconds. A listener on the port is now a
26
+ board: `leg` attaches to it.
27
+ - The board is opened whether or not this terminal is the one that started
28
+ it. Previously the browser was only opened on the path that spawned the
29
+ server, so with a board already running nothing ever opened.
30
+ - One push rebuilt the terminals grid three times (two listeners registered
31
+ for `leg:sessions` and one for the legacy alias, with the payload parsed
32
+ twice per push and one dispatch outside the staleness guard). Every button
33
+ was destroyed and recreated several times a second. One push now rebuilds
34
+ once, and an open confirm row is left alone until it is answered.
35
+
36
+ - **Remove, Remove record, End and Land work.** Confirming any of them did
37
+ nothing at all. `confirmRow` clears `pendingConfirm` and then calls its
38
+ callback, and the callback read `pendingConfirm.action` — off the variable it
39
+ had just cleared. Every Yes on the Terminals panel threw
40
+ `TypeError: Cannot read properties of null (reading 'action')` into the
41
+ console and never reached the request. The callback now closes over a
42
+ snapshot taken before the row is built.
43
+
44
+ - **Every conversation on this machine (`leg history`, `leg worktrees`, the
45
+ board's Conversations cell).** One read-only index over the conversations
46
+ Claude Code, Codex, Grok, Antigravity and Copilot CLI keep in their own
47
+ stores, plus Leg's own sessions, deduplicated (a session Leg started and
48
+ the same conversation in the agent's store are one row, marked `leg`; the
49
+ rest are `external`). List, filter by agent, repository or text, open one
50
+ (its last messages, read from the tail of the transcript only when asked),
51
+ and `leg history continue <id>` to start a supervised leg on it where the
52
+ installed CLI documents resume-by-id (claude, codex, grok, agy; copilot
53
+ lists and reads but is not an agent Leg runs). Nothing in an agent's store
54
+ is moved or written; Leg writes only `~/.leg/history/index.json`, refreshed
55
+ incrementally by size and mtime, and never opens a SQLite file. Every
56
+ checkout Leg can see, git's and its own and the ones conversations ran in,
57
+ with owner, uncommitted count, orphaned, stale and missing verdicts, read
58
+ only. On a shared board the whole group is the owner's. Redaction learned
59
+ the shapes another agent's transcript carries (Stripe, Google, xAI, npm,
60
+ GitLab, Hugging Face keys, JWTs, private-key blocks, basic auth, URL
61
+ credentials, `password=`), and the board token joined the values it strips.
62
+ Support matrix and every file read: docs/history.md.
63
+ - **History, after its review.** The board's Conversations cell pages past
64
+ 150 rows (the total no longer shrank with each cursor page); the board
65
+ refreshes a stale index in a child process instead of its own event loop;
66
+ a cwd on an unreachable network share no longer stalls a refresh; an
67
+ Antigravity retitle or a touched presence lock is seen by an incremental
68
+ refresh, and only that conversation is re-read; an older Leg session id
69
+ still opens the conversation it was one leg of; `leg history` prints a
70
+ failed refresh whatever the last index still lists, `refresh` fails cleanly
71
+ when another Leg holds the lock, `--limit 0` is a usage error (`--all`),
72
+ `--offset` works, a Leg-only row's id prints whole; a malformed id on
73
+ `/api/history/<id>` is a 400; an account name that is a path is ignored;
74
+ titles are cut to 200 as documented and go through the held-value
75
+ redaction too; the Copilot chip has a colour. Redaction no longer eats
76
+ `Basic authentication/authorization`, `cache_key = ...` or
77
+ `refresh_token: string`, and a value never crosses a line break.
78
+
79
+ ## 0.9.0 (2026-09-16)
80
+
81
+ - **The portable harness (`leg harness`), off by default.** A hand-off can now
82
+ carry the working environment with the task: the source agent's global rules
83
+ (imports inlined), identity, hooks, skills, subagents, slash commands, MCP
84
+ servers and permissions, rendered into the destination client's own files as
85
+ far as it can represent them, with every dropped item explained.
86
+ `leg harness enable` detects clients, captures, shows the plan and writes
87
+ only after consent; `status`, `inspect`, `check`, `explain`, `diff`,
88
+ `history` and `doctor` are read-only; `sync`, `capture`, `source`, `policy`
89
+ and `disable` are the writes. Policies `warn`, `sync` and `strict` decide
90
+ what an unattended hand-off may do; strict refuses a destination it cannot
91
+ make safe and tries the next option. Every written file carries
92
+ `GENERATED by Leg harness`, lives in a marked region or owned key inside
93
+ files you also own, is backed up before an overwrite and skipped when
94
+ hand-edited. Credentials never move (`${NAME}` references). The session
95
+ record, its timeline (`harness`, `harness_blocked`), the card ledger and the
96
+ board (a chip on the row, a **Harness** section in the drawer) show what
97
+ transferred. Source changes are fingerprinted so an unchanged environment
98
+ costs a few stat calls at a hand-off. Docs: `docs/harness.md`.
99
+ - **Engine.** The capture, bundle and apply engine is the Agnostic AI port
100
+ engine (MIT), vendored byte for byte under `src/harness/vendor/agnostic-ai/`
101
+ with its upstream commit and per-file hashes pinned; `npm test` refuses a
102
+ local edit. Attribution in `NOTICE`.
103
+ - **Existing installs are unchanged.** No client file is touched until
104
+ `leg harness enable`; `preferences.json` gains a `harness` key that reads as
105
+ off when absent.
106
+
107
+ ## 0.8.1 (2026-09-16)
108
+
109
+ - **Antigravity CLI (`agy`) workspace trust in worktrees and repos.** Leg writes
110
+ the folder trust record to `~/.gemini/antigravity-cli/settings.json`'s
111
+ `trustedWorkspaces` for both the repo root and the worktree directory, with
112
+ exact Windows drive and separator normalization matching Go's `runtime.memequal`
113
+ check so `leg agy` runs completely unattended without interactive trust prompts.
114
+ - **Board server resolution in worktrees.** Fixed board asset resolution when
115
+ Leg is executed from within a git worktree.
116
+
3
117
  ## 0.8.0 (2026-09-16)
4
118
 
119
+ - **The product is called Leg.** Website, CLI help, board logs and onboarding
120
+ copy say **Leg**; the command is `leg`; `legcli.com` is the domain, not the
121
+ product name. `leg up` prefixes lines with `[leg]`. Historical changelog
122
+ entries keep the previous name.
5
123
  - **Grok is a supervised and handoff agent.** `leg grok` starts Grok the same
6
124
  way `leg claude`, `leg codex` and `leg agy` start those agents: board
7
125
  alongside, usage tracking, and a live context handoff bundle. At the limit
@@ -11,6 +129,9 @@
11
129
  and agy, `--ask-for-approval never` for Codex, `--always-approve` for Grok).
12
130
  Opt out with `--no-auto-approve`, `LEG_AUTO_APPROVE=0` /
13
131
  `LEG_NO_AUTO_APPROVE=1`, or `"auto_approve": false` in `preferences.json`.
132
+ - **`leg-agents` is the unscoped alias installer.** It pins the same version of
133
+ `@ucsandman/legcli` and exposes the same `leg` binary. CI publishes both
134
+ packages together; `npm test` fails if their versions drift.
14
135
 
15
136
  ## 0.7.0 (2026-09-15)
16
137
 
package/NOTICE CHANGED
@@ -2,3 +2,11 @@ Portions of this software (src/runner.mjs, src/ledger.mjs, src/git-snapshot.mjs
2
2
  and their tests) were ported on 2026-09-10 from a private ucsandman repository
3
3
  (team tooling) under the MIT license; that code is included here under the Leg License Agreement (see LICENSE), which its author also holds. Telegram delivery, chat identifiers,
4
4
  and machine-specific paths were removed in the port.
5
+
6
+ The portable-harness engine under src/harness/vendor/agnostic-ai/ is the
7
+ Agnostic AI port engine (https://github.com/ucsandman/Agnostic-AI), copyright
8
+ (c) 2026 Wes Sander, included byte for byte under the MIT License, whose full
9
+ text is in src/harness/vendor/agnostic-ai/LICENSE. That copy is not
10
+ relicensed: it stays MIT, and its upstream commit and per-file hashes are
11
+ recorded in src/harness/vendor/agnostic-ai/UPSTREAM.json. Leg's own
12
+ harness code (src/harness/*.mjs) is under the Leg License Agreement.