@buildaharness/aielia 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -35
- package/dist/PlanGraphPane.d.ts +19 -0
- package/dist/_memory-core-generated.d.ts +1764 -0
- package/dist/action-approval-service.d.ts +34 -2
- package/dist/action-record.d.ts +13 -0
- package/dist/activity-log.d.ts +4 -0
- package/dist/agent-loop.d.ts +106 -9
- package/dist/ambiguity-guard-flag.d.ts +12 -0
- package/dist/ambiguity-guard.d.ts +20 -0
- package/dist/answer-claim.d.ts +13 -1
- package/dist/ask-clarification-service.d.ts +12 -1
- package/dist/ask-response-format.d.ts +6 -0
- package/dist/assistant-session.d.ts +32 -2
- package/dist/assistant-source.d.ts +7 -0
- package/dist/assistant-types.d.ts +20 -2
- package/dist/assistant.d.ts +160 -6
- package/dist/benchmark-injected-failure.d.ts +6 -0
- package/dist/bin-BYRl4xXM.js +4985 -0
- package/dist/bin-BYRl4xXM.js.map +1 -0
- package/dist/cli-config.d.ts +3 -0
- package/dist/cli-session.d.ts +19 -5
- package/dist/cli.d.ts +26 -2
- package/dist/cli.js +1 -1
- package/dist/code-plan-templates.d.ts +21 -0
- package/dist/config.d.ts +31 -0
- package/dist/constraint-check.d.ts +35 -0
- package/dist/contradiction-checker.d.ts +7 -0
- package/dist/debug-log.d.ts +10 -1
- package/dist/decomposed-answer.d.ts +13 -0
- package/dist/decomposition-classifier.d.ts +2 -0
- package/dist/doctor-checks.d.ts +3 -0
- package/dist/email.d.ts +5 -3
- package/dist/episodic-digest.d.ts +89 -0
- package/dist/fact-extraction.d.ts +39 -0
- package/dist/file-tools-mcp-server.mjs +288 -37
- package/dist/file-tools.d.ts +6 -0
- package/dist/first-run.d.ts +0 -2
- package/dist/git-exclude.d.ts +9 -0
- package/dist/goal-graph-store.d.ts +18 -18
- package/dist/grounding-check.d.ts +33 -0
- package/dist/harness-bridge.d.ts +75 -2
- package/dist/harness-token-budget.d.ts +9 -0
- package/dist/index.d.ts +21 -2
- package/dist/index.js +166 -94
- package/dist/index.js.map +1 -1
- package/dist/ink-select-prompt.d.ts +2 -0
- package/dist/ink-test-render.d.ts +2 -0
- package/dist/layer-policy-flag.d.ts +13 -0
- package/dist/layer-policy-wiring.d.ts +77 -0
- package/dist/layer-settings.d.ts +49 -0
- package/dist/layer-telemetry.d.ts +2 -0
- package/dist/lexical/lexical-mode.d.ts +29 -0
- package/dist/memory-consolidation.d.ts +80 -0
- package/dist/memory-governance.d.ts +30 -0
- package/dist/memory-reviewer.d.ts +114 -0
- package/dist/memory-service.d.ts +356 -9
- package/dist/model-json.d.ts +17 -0
- package/dist/next-step-context.d.ts +51 -0
- package/dist/next-step-proposer.d.ts +10 -2
- package/dist/plan-drafting-service.d.ts +3 -0
- package/dist/plan-graph-flag.d.ts +20 -0
- package/dist/plan-question.d.ts +60 -0
- package/dist/plan-service.d.ts +6 -2
- package/dist/plan-step-prompt.d.ts +15 -0
- package/dist/plan-store.d.ts +12 -1
- package/dist/plan-viz/normalize.d.ts +14 -0
- package/dist/plan-viz/plan-detail-lines.d.ts +3 -0
- package/dist/plan-viz/plan-layout.d.ts +48 -0
- package/dist/plan-viz/plan-nav.d.ts +29 -0
- package/dist/plan-viz/plan-raster.d.ts +36 -0
- package/dist/plan-viz/plan-routes.d.ts +6 -0
- package/dist/plan-viz/plan-snapshot.d.ts +73 -0
- package/dist/plan-viz/plan-viewport.d.ts +29 -0
- package/dist/plan-viz/plan-width.d.ts +15 -0
- package/dist/plan-viz/testkit/display-width.d.ts +12 -0
- package/dist/plan-viz/testkit/generators.d.ts +61 -0
- package/dist/plan-viz/testkit/grid-oracles.d.ts +38 -0
- package/dist/plan-viz/testkit/nav-oracles.d.ts +79 -0
- package/dist/plan-viz/testkit/types.d.ts +8 -0
- package/dist/plan-viz/types.d.ts +34 -0
- package/dist/{provider-setup-CPbB5y_V.js → provider-setup-CV3S_TAS.js} +10792 -5731
- package/dist/provider-setup-CV3S_TAS.js.map +1 -0
- package/dist/recall-tool.d.ts +43 -0
- package/dist/recovery-note.d.ts +22 -0
- package/dist/reply-audit.d.ts +67 -0
- package/dist/response-service.d.ts +11 -1
- package/dist/review-checker.d.ts +10 -4
- package/dist/reviewer-revision.d.ts +23 -0
- package/dist/risk-classifier.d.ts +7 -0
- package/dist/scripted-llm-client.d.ts +26 -1
- package/dist/semantic-compaction.d.ts +15 -0
- package/dist/semantic-hypotheses.d.ts +40 -0
- package/dist/side-call-policy.d.ts +30 -0
- package/dist/source-reliability.d.ts +71 -0
- package/dist/task-completion-check.d.ts +24 -0
- package/dist/tool-control-plane.d.ts +33 -1
- package/dist/tool-effect-class.d.ts +9 -0
- package/dist/tool-step.d.ts +6 -0
- package/dist/trace-events.d.ts +1 -1
- package/dist/transcript-compaction.d.ts +9 -0
- package/dist/trust-tagging.d.ts +2 -0
- package/dist/{tui-app-DeyZ4Pr9.js → tui-app-CJq6YaiP.js} +436 -21
- package/dist/tui-app-CJq6YaiP.js.map +1 -0
- package/dist/tui-app.d.ts +73 -0
- package/dist/turn-abort.d.ts +18 -0
- package/dist/turn-intent-classifier.d.ts +81 -14
- package/dist/turn-interpreter.d.ts +27 -3
- package/dist/version.d.ts +1 -1
- package/package.json +6 -6
- package/dist/bin-CdVTAe7j.js +0 -2209
- package/dist/bin-CdVTAe7j.js.map +0 -1
- package/dist/provider-setup-CPbB5y_V.js.map +0 -1
- package/dist/tui-app-DeyZ4Pr9.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,6 +7,30 @@ what it may do, what it may believe, and what a job may cost — light enough fo
|
|
|
7
7
|
"what's the weather", and it stages anything that can't be undone (`write_file`,
|
|
8
8
|
`run_shell_command`, `send_email`) for your approval. Website: https://myaielia.com.
|
|
9
9
|
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# macOS / Linux — standalone binary, installed to ~/.local/bin (override with AIELIA_INSTALL_DIR)
|
|
14
|
+
curl -fsSL https://myaielia.com/install.sh | sh
|
|
15
|
+
curl -fsSL https://myaielia.com/install.sh | sh -s -- --force # replace a non-aielia file at the target path
|
|
16
|
+
|
|
17
|
+
# Windows (PowerShell) — installs to %LOCALAPPDATA%\Aielia\aielia.exe and adds it to your user PATH
|
|
18
|
+
irm https://myaielia.com/install.ps1 | iex # set $env:AIELIA_FORCE = '1' first to force
|
|
19
|
+
|
|
20
|
+
# or from npm
|
|
21
|
+
npm install -g @buildaharness/aielia
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Both installers read the manifest at `https://myaielia.com/aielia-latest.json`, download
|
|
25
|
+
the binary for your platform over HTTPS only, verify its SHA-256 against the manifest and
|
|
26
|
+
install it; re-running upgrades in place, or says it is already up to date. They refuse
|
|
27
|
+
to overwrite an unrelated file (or a symlink, such as an npm-linked `aielia`) without
|
|
28
|
+
`--force`. `aielia update` does the same upgrade later (see "Updates and the update check"
|
|
29
|
+
below). On the first interactive launch with nothing configured, the CLI asks which
|
|
30
|
+
provider to use and for its API key (live-checked with a free read-only call) and saves
|
|
31
|
+
the choice to the persisted config; piped/scripted stdin skips this and keeps the
|
|
32
|
+
`proxy` default.
|
|
33
|
+
|
|
10
34
|
## Design
|
|
11
35
|
|
|
12
36
|
The harness here is a governance and reliability control plane, not just a
|
|
@@ -142,7 +166,7 @@ contradiction detection considers it:
|
|
|
142
166
|
|
|
143
167
|
| Tier | Answers | Allowed `FactSource` | Retention | Contradiction-checked | Where it lives |
|
|
144
168
|
|---|---|---|---|---|---|
|
|
145
|
-
| **Episodic** | "What was said or mused, unconfirmed?" | any | session | no | `facts:<sessionId>` — also every `model_inferred`/`observed` `UserFact` lands here regardless of its `durable` bit; an unconfirmed model guess is never Knowledge |
|
|
169
|
+
| **Episodic** | "What was said or mused, unconfirmed?" | any | session | no | `facts:<sessionId>`, plus `episodic:<sessionId>` session digests when `AUDIT_EPISODIC_DIGEST` is on (see below) — also every `model_inferred`/`observed` `UserFact` lands here regardless of its `durable` bit; an unconfirmed model guess is never Knowledge |
|
|
146
170
|
| **Semantic** | "What's currently stated as true?" | `user_asserted`, `externally_verified` | durable (by tier policy) | yes | `facts:<sessionId>` or `facts:durable`, depending on the existing promotion policy (`durable` bit) — the tier a fact belongs to and whether it's actually promoted are tracked separately today |
|
|
147
171
|
| **Identity** | "Who is this?" (name, "call me X") | `user_asserted` | durable | yes | `facts:durable` |
|
|
148
172
|
| **Preference** | "What does the user want?" (stated preference) | `user_asserted` | durable | yes | `facts:durable`; a *configured* preference (backend, model, `enableShell`) is separately `AssistantConfig` (`config.ts`), not a `UserFact` at all |
|
|
@@ -158,6 +182,40 @@ the other half is that `isKnowledgeTier()` only returns true for `semantic`,
|
|
|
158
182
|
`identity`, and `preference` — episodic entries, procedural weights, and
|
|
159
183
|
commitments never enter contradiction detection as if they were beliefs.
|
|
160
184
|
|
|
185
|
+
**Episodic memory now has a store and a writer, behind a flag.** With
|
|
186
|
+
`AUDIT_EPISODIC_DIGEST` on (off by default; the cross-session scenario improved on 2 of 2 seeds, one scenario only), the assistant
|
|
187
|
+
writes one short handoff digest per session (objective, what was done,
|
|
188
|
+
decisions, open items, next step) at the session edge (`/new`, exit), never
|
|
189
|
+
inside a turn, to `episodic:<sessionId>`. A second use of the same writer runs
|
|
190
|
+
just before transcript compaction drops old messages, so facts in those
|
|
191
|
+
messages are queued for confirmation instead of being lost. Digests are kept
|
|
192
|
+
apart from durable facts and are never injected into the prompt: they reach the
|
|
193
|
+
model only through the read-only `recall_memory` tool (`AUDIT_RECALL_TOOL`, off
|
|
194
|
+
by default), which returns an index of recent digests and then one digest by id,
|
|
195
|
+
wrapped as untrusted context. The model picks which digest to open; there is no
|
|
196
|
+
keyword search. Digest text passes the same secret judgement as any other
|
|
197
|
+
memory write, and a digest can never populate a Knowledge tier (the extended
|
|
198
|
+
INV-16: a non-user origin is episodic only). Digests are kept for a retention
|
|
199
|
+
window (default 90 days, `AUDIT_EPISODIC_RETENTION_DAYS`) and are covered by
|
|
200
|
+
`/memory forget` and `/memory export`. This changes what `/new` keeps: durable
|
|
201
|
+
facts as before, plus digests when the flag is on. Evidence is one scenario and two seeds; it also adds one model call per session edge.
|
|
202
|
+
|
|
203
|
+
Related write-path controls: `AUDIT_MEMORY_BUDGETED_RENDER` is **on by default**
|
|
204
|
+
(character-budgeted, priority-ordered facts block with keyed supersession, so a
|
|
205
|
+
corrected fact replaces the old one; `=0` restores the old 20-fact slice; budget
|
|
206
|
+
`memoryBudgetChars`, default 4000). In a six-week corrections scenario it fixed a
|
|
207
|
+
stale-fact failure on 3 of 3 seeds. Off by default: `AUDIT_MEMORY_WRITE_GATE`
|
|
208
|
+
(semantic secret redaction and instruction-shaped-text flagging before a fact is
|
|
209
|
+
promoted; a missing judgement means the fact is not promoted; no outcome
|
|
210
|
+
difference was seen because the base model already resisted the planted secret),
|
|
211
|
+
`AUDIT_MEMORY_AUDIT_LOG` (`/memory history`, `/memory undo <seq>`),
|
|
212
|
+
`AUDIT_MEMORY_REVIEWER` (post-turn reviewer; its writes are staged for
|
|
213
|
+
`/memory confirm` unless `memoryWriteMode` is `auto`) and
|
|
214
|
+
`AUDIT_MEMORY_CONSOLIDATION` (staged merge and archive proposals; not measured as
|
|
215
|
+
an outcome). Known gaps: the model sometimes keys the same attribute two ways, so
|
|
216
|
+
a correction can miss the old fact, and a natural-language "forget that" request
|
|
217
|
+
is staged for approval rather than applied.
|
|
218
|
+
|
|
161
219
|
The conversation transcript itself (`transcript:<sessionId>`, "what was
|
|
162
220
|
said" verbatim) and a single turn's `AnswerClaim` (evidence vs. claim for one
|
|
163
221
|
reply, see below) sit outside this tier system — they're the raw material a
|
|
@@ -273,8 +331,9 @@ await assistant.turn('Summarize this into notes.md', { approved: true, pendingAc
|
|
|
273
331
|
|
|
274
332
|
Declining (`{ approved: false, pendingActionId }`) discards the staged record
|
|
275
333
|
without writing. A pending action left over from a crashed/abandoned turn sits
|
|
276
|
-
in `.pending-actions/`
|
|
277
|
-
`approved: true` with the matching ID)
|
|
334
|
+
in `.pending-actions/` — harmless (never applied without an explicit
|
|
335
|
+
`approved: true` with the matching ID), and swept on the next startup unless a
|
|
336
|
+
session still has a resumable checkpoint (`sweepAbandonedPendingActionsOnStartup`). This same
|
|
278
337
|
staging record shape (a `kind` discriminator) is shared with `run_shell_command`
|
|
279
338
|
(see "Shell access via tools" below) and `send_email`.
|
|
280
339
|
|
|
@@ -314,7 +373,7 @@ Both backends enforce the same "never write inline" rule, by different
|
|
|
314
373
|
mechanisms:
|
|
315
374
|
|
|
316
375
|
- **Proxy/Anthropic backend** (`LLMClient`): `PersonalAssistant`'s tool loop
|
|
317
|
-
(
|
|
376
|
+
(bounded by `maxSteps`, default 15, minus a few steps held back for recovery) calls `callChatStructured` directly, executes
|
|
318
377
|
non-mutating tool calls for real, and intercepts `write_file` itself before
|
|
319
378
|
it ever reaches `file-tools.ts`'s staging code.
|
|
320
379
|
- **Claude CLI backend** (`ClaudeCliLLMClient`): Claude Code's own agentic loop
|
|
@@ -331,8 +390,10 @@ mechanisms:
|
|
|
331
390
|
|
|
332
391
|
v1 is deliberately read/list/write only — no delete/move tool (higher
|
|
333
392
|
consequence than a write, no "undo" via re-approval). One workspace root per
|
|
334
|
-
assistant instance; no multi-root or per-request override.
|
|
335
|
-
|
|
393
|
+
assistant instance; no multi-root or per-request override. File tools need a
|
|
394
|
+
real workspace directory, so they are CLI/desktop-only; chat-ui's approval card
|
|
395
|
+
(with the exact change shown) is what resolves a staged write or shell command
|
|
396
|
+
on the desktop build.
|
|
336
397
|
|
|
337
398
|
## Clarifying questions
|
|
338
399
|
|
|
@@ -370,8 +431,8 @@ follow-up `needs_clarification` batch if it's still unresolved once the first ba
|
|
|
370
431
|
folded in, resolved through this exact same path.
|
|
371
432
|
|
|
372
433
|
Two kinds of sites can raise a `questions` batch: the Trajectory Supervisor's `ASK_USER` directive
|
|
373
|
-
(see ADR-005 —
|
|
374
|
-
`HARNESS_TRAJECTORY_SUPERVISOR`
|
|
434
|
+
(see ADR-005 — the supervisor is on by default in Aielia;
|
|
435
|
+
`HARNESS_TRAJECTORY_SUPERVISOR=0` turns it off) and a handful of deterministic sites with a genuinely
|
|
375
436
|
enumerable option set, e.g. a batch-research budget running out ("continue with N more steps" /
|
|
376
437
|
"stop and summarize" / "let me clarify the goal"). A site with no discrete option set keeps
|
|
377
438
|
today's plain `missing_info` halt unchanged — this mechanism never forces a multiple-choice
|
|
@@ -448,6 +509,9 @@ without ever exposing the filesystem or shell.
|
|
|
448
509
|
|
|
449
510
|
## Batch research budget
|
|
450
511
|
|
|
512
|
+
> The list detector below is a lexical check (the `batch-list` family), **off by default**: set
|
|
513
|
+
> `ASSISTANT_LEXICAL_ON=batch-list` (or `ASSISTANT_LEXICAL_MODE=enabled`) to use batch research.
|
|
514
|
+
|
|
451
515
|
The flat `maxSteps` cap that governs an ordinary chat turn (see below) doesn't
|
|
452
516
|
know the difference between a one-question turn and a turn asking for the same
|
|
453
517
|
lookup across many items — a 7-item batch and a 1-item question get the same
|
|
@@ -705,18 +769,9 @@ non-functional `web_search`. The active state is shown in the startup banner
|
|
|
705
769
|
running session with `/config set` instead of an env var — see
|
|
706
770
|
"Configuration" below.
|
|
707
771
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
`claude` binary path if it's not on `PATH`):
|
|
712
|
-
|
|
713
|
-
```bash
|
|
714
|
-
ASSISTANT_LLM_BACKEND=claude-cli npm run cli --workspace=packages/aielia
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
Or skip both the proxy and claude-cli and call a provider directly with your
|
|
718
|
-
own API key — `ASSISTANT_LLM_BACKEND=anthropic|openai|openrouter` plus
|
|
719
|
-
`ASSISTANT_API_KEY`:
|
|
772
|
+
`ASSISTANT_LLM_BACKEND` also accepts `claude-cli` (shells out to the `claude` CLI already on
|
|
773
|
+
your PATH, no API key needed; CLI and desktop only). Skip the proxy and call a provider directly with your own API
|
|
774
|
+
key — `ASSISTANT_LLM_BACKEND=anthropic|openai|openrouter` plus `ASSISTANT_API_KEY`:
|
|
720
775
|
|
|
721
776
|
```bash
|
|
722
777
|
ASSISTANT_LLM_BACKEND=anthropic ASSISTANT_API_KEY=sk-ant-... \
|
|
@@ -734,7 +789,8 @@ These three go straight from this process to the provider's own API
|
|
|
734
789
|
— no proxy deployment needed, but unlike `authToken` (a self-hosted proxy's
|
|
735
790
|
own bearer token), `ASSISTANT_API_KEY`/`apiKey` is a *real* provider key.
|
|
736
791
|
It's stored the same way as every other secret field here — plaintext in
|
|
737
|
-
`config.json
|
|
792
|
+
`config.json` (written with mode `0600`, in a `0700` directory), not an OS
|
|
793
|
+
keychain — so treat that file accordingly. When
|
|
738
794
|
`ASSISTANT_MODEL`/`/config set model` isn't set, each backend falls back to the
|
|
739
795
|
current-generation default id exported from `@buildaharness/runtime`'s
|
|
740
796
|
`model-defaults.ts` (`openai` → `gpt-5-mini`, `openrouter` →
|
|
@@ -767,9 +823,13 @@ you> /config
|
|
|
767
823
|
model (not set)
|
|
768
824
|
enableWeb false
|
|
769
825
|
braveApiKey (not set)
|
|
826
|
+
webBackend direct
|
|
770
827
|
enableShell false
|
|
771
828
|
shellTimeoutMs (not set)
|
|
829
|
+
shellNetworkAllowlist (not set)
|
|
772
830
|
workspaceRoot (not set)
|
|
831
|
+
enableEmail false
|
|
832
|
+
... (one line per key; the full list is `CONFIG_KEYS` in config.ts)
|
|
773
833
|
dangerouslySkipPermissions false
|
|
774
834
|
|
|
775
835
|
you> /config set enableWeb true
|
|
@@ -785,7 +845,9 @@ you> /config reset enableWeb
|
|
|
785
845
|
✓ Reset enableWeb to default
|
|
786
846
|
```
|
|
787
847
|
|
|
788
|
-
- `/config` lists every field's current (resolved) value
|
|
848
|
+
- `/config` lists every field's current (resolved) value; secret fields
|
|
849
|
+
(`authToken`, `apiKey`, `braveApiKey`, `resendApiKey`, `smtpPass`) print as
|
|
850
|
+
`********`, and credentials or query strings inside `proxyUrl` are masked. A field currently
|
|
789
851
|
pinned by an env var shows `(env-pinned: VAR_NAME)` and cannot be changed
|
|
790
852
|
with `/config set` — unset the env var first.
|
|
791
853
|
- `/config set <key> <value>` validates the change (e.g. `enableWeb true`
|
|
@@ -798,15 +860,67 @@ you> /config reset enableWeb
|
|
|
798
860
|
|
|
799
861
|
**Precedence**: env var > persisted config > built-in default, evaluated
|
|
800
862
|
independently per field. Settings persist as plain JSON at
|
|
801
|
-
`~/.buildaharness/personal-assistant/config.json`
|
|
802
|
-
|
|
803
|
-
|
|
863
|
+
`~/.buildaharness/personal-assistant/config.json` (created `0600` inside a
|
|
864
|
+
`0700` directory) — like the rest of this
|
|
865
|
+
package's persistence, it's a real file, not encrypted, so `authToken`,
|
|
866
|
+
`apiKey`, `braveApiKey` and the email credentials are stored in plaintext there. This is the same trust boundary
|
|
804
867
|
the repo's root `.env` already has, not a new one.
|
|
805
868
|
|
|
869
|
+
Settings beyond those above (each has an env var, a `/config set` key, and a built-in default;
|
|
870
|
+
mode flags take `enabled`/`disabled`):
|
|
871
|
+
|
|
872
|
+
| Key (env var) | Default | What it does |
|
|
873
|
+
|---|---|---|
|
|
874
|
+
| `webBackend` | `direct` | Browser build only (see chat-ui README); the CLI always calls Brave directly |
|
|
875
|
+
| `shellNetworkAllowlist` (`ASSISTANT_SHELL_NETWORK_ALLOWLIST`) | none (deny all) | Hosts an approved shell command may reach |
|
|
876
|
+
| `enableEmail`, `emailProvider` (`resend`/`smtp`), `emailFrom`, `resendApiKey`, `smtpHost`/`smtpPort`/`smtpUser`/`smtpPass` (`ASSISTANT_ENABLE_EMAIL`, `ASSISTANT_EMAIL_*`, `ASSISTANT_RESEND_API_KEY`, `ASSISTANT_SMTP_*`) | off | Registers the staged `send_email` tool; `enableEmail` needs `emailFrom` and the provider's credentials |
|
|
877
|
+
| `sessionCostLimitUsd`, `sessionCallLimit` (`ASSISTANT_SESSION_COST_LIMIT_USD`, `ASSISTANT_SESSION_CALL_LIMIT`) | unbounded | Refuses a new turn once the cross-session estimated spend or completed-turn count reaches the ceiling; shown in `/status` and `/cost` |
|
|
878
|
+
| `memoryBudgetChars` (`ASSISTANT_MEMORY_BUDGET_CHARS`) | 4000 | Character budget for the facts block in the prompt |
|
|
879
|
+
| `memoryWriteMode` (`ASSISTANT_MEMORY_WRITE_MODE`) | `staged` | `auto`, `staged` or `user_only`; see "Memory tiers" |
|
|
880
|
+
| `oneLoopMode` (`ASSISTANT_ONE_LOOP`) | `enabled` | See "Design" |
|
|
881
|
+
| `askMode` (`ASSISTANT_ASK_MODE`) | `disabled` | See "Clarifying questions" |
|
|
882
|
+
| `planMode` (`ASSISTANT_PLAN_MODE`) | `legacy` | `gated` or `legacy` plan rollout |
|
|
883
|
+
| `ambiguityGuardMode` (`ASSISTANT_AMBIGUITY_GUARD`) | `disabled` | Ambiguity guard |
|
|
884
|
+
| `tuiMode` (`ASSISTANT_TUI`) | `disabled` | Full-screen terminal UI (Ink); only on a real TTY |
|
|
885
|
+
| `updateCheck` (`ASSISTANT_UPDATE_CHECK`) | `enabled` | Passive update check |
|
|
886
|
+
| `activeProject` (`ASSISTANT_ACTIVE_PROJECT`) | none | Project new project-scoped facts are tagged with (`/project`) |
|
|
887
|
+
| `goalGraphMode`, `goalGraphSuggestMode` (`ASSISTANT_GOAL_GRAPH`, `ASSISTANT_GOAL_GRAPH_SUGGEST`) | `enabled` in the CLI | Goal tree, steering and next-step options |
|
|
888
|
+
| `planGraphMode` (`ASSISTANT_PLAN_GRAPH`) | `disabled` | `/plan graph` |
|
|
889
|
+
| `layerPolicyMode` (`ASSISTANT_LAYER_POLICY`) | `static` | `static`, `shadow` or `adaptive` |
|
|
890
|
+
| `layers` | `{}` | Per-layer on/off, edited with `/layers`, not `/config set` |
|
|
891
|
+
|
|
892
|
+
`ASSISTANT_ACTIVITY_LOG=1` additionally appends a debug activity log to
|
|
893
|
+
`activity-log.jsonl` in the data directory (created `0600`). All CLI output has
|
|
894
|
+
terminal escape sequences stripped, so text echoed from a fetched page or file
|
|
895
|
+
cannot rewrite what an approval prompt shows.
|
|
896
|
+
|
|
897
|
+
### Lexical checks (off by default)
|
|
898
|
+
|
|
899
|
+
Every lexical pass in this package (regex / keyword / phrase-list checks over natural-language text) sits
|
|
900
|
+
behind one switch, `lexicalMode`, and **every one is off by default** in the CLI, the browser tab and the
|
|
901
|
+
desktop app — the LLM-based checks do the work instead. The ten families (`fact-markers`, `coding-fact`,
|
|
902
|
+
`injection`, `enumeration`, `risk`, `task-cancel`, `plan-mode`, `batch-list`, `tool-yield`,
|
|
903
|
+
`template-keywords`) and what "off" means for each are listed in `src/lexical/lexical-mode.ts`.
|
|
904
|
+
|
|
905
|
+
- `ASSISTANT_LEXICAL_MODE=enabled` turns every family back on (the pre-2026-09-28 behaviour).
|
|
906
|
+
- `ASSISTANT_LEXICAL_ON=batch-list,task-cancel` turns only those families back on (`all` for every one).
|
|
907
|
+
- `ASSISTANT_LEXICAL_OFF=<families>` turns families off even under `enabled`; it wins over ON.
|
|
908
|
+
|
|
909
|
+
The mode is handed to `@buildaharness/harness`'s own lexical switch at the start of every run, so
|
|
910
|
+
`enabled` turns the harness's checks back on too (see that package's README).
|
|
911
|
+
|
|
912
|
+
Some families have no LLM replacement, so with them off the feature they drive does not run: batch
|
|
913
|
+
research (`batch-list`), matching "skip that step" to one step of an active plan (`task-cancel`), leaving
|
|
914
|
+
plan drafting by phrase (`plan-mode`; `/plan` still works), and the batch sub-loop's lexical dead-end
|
|
915
|
+
detection (`tool-yield`; the web tool's own "No results found." still counts). With `risk` off, a durable
|
|
916
|
+
plan step saved without its own risk level is treated as HIGH.
|
|
917
|
+
|
|
806
918
|
## REPL commands
|
|
807
919
|
|
|
808
|
-
Type `/help` inside a running CLI session for this list.
|
|
809
|
-
change local session/config state
|
|
920
|
+
Type `/help` inside a running CLI session for this list. Almost all of them read or
|
|
921
|
+
change local session/config state without an LLM call; the exceptions are `/plan sketch`
|
|
922
|
+
and `/memory consolidate`, each of which makes one. `/exit` (also `/quit`, `exit`, `quit`)
|
|
923
|
+
ends the session.
|
|
810
924
|
|
|
811
925
|
| Command | What it does |
|
|
812
926
|
|---|---|
|
|
@@ -815,15 +929,28 @@ change local session/config state — none of them make an LLM call themselves.
|
|
|
815
929
|
| `/status` | Show the resolved config (model, backend, workspace, enabled capabilities — same as the startup banner) plus this session's transcript length and whether a plan is active |
|
|
816
930
|
| `/export [file]` | Save this session's transcript to a markdown file (default: `assistant-transcript-<timestamp>.md` in the current directory) |
|
|
817
931
|
| `/undo` | Remove the last exchange from conversation history — a completed turn drops both the user message and the reply; a turn still awaiting approval drops just the pending message. Only affects what the model remembers: a real `write_file`/`run_shell_command` effect from that turn is **not** reversed |
|
|
818
|
-
| `/
|
|
932
|
+
| `/undo-action [id]` | List the real filesystem effects of approved actions that can still be reverted (see `/status`'s undo-log line), or stage a revert of one for your approval |
|
|
933
|
+
| `/memory` | Show facts learned about you, pending-confirmation guesses, reminders created so far, and the learning-layer `ExperienceStore`'s real content — every strategy weight, plus the 20 most recently learned decompositions/recovery sequences (newest first), not just counts |
|
|
934
|
+
| `/memory confirm <n\|category>` / `/memory reject <n\|category>` | Promote a pending-confirmation guess (or a whole category) to durable memory, or discard it |
|
|
935
|
+
| `/memory forget <n> [erase]` | Remove a learned fact by its number in "Facts I know". It stays restorable through the audit log (`/memory undo`) unless you add `erase`, which scrubs its text from the log too. `/memory forget digest [id]` erases one stored session digest, or all of them |
|
|
936
|
+
| `/memory history` / `/memory undo <seq>` | Show recent memory changes with their sequence numbers, and restore one change's pre-image (needs `AUDIT_MEMORY_AUDIT_LOG`) |
|
|
937
|
+
| `/memory status` | Store size vs budget, pending count, write mode, last consolidation |
|
|
938
|
+
| `/memory archive [restore <n> \| forget <n>]` | List facts set aside or replaced by a newer statement; restore one, or erase one for good |
|
|
939
|
+
| `/memory consolidate [accept\|dismiss <n>]` | Propose merging or retiring overlapping facts; nothing changes until you accept (needs `AUDIT_MEMORY_CONSOLIDATION`) |
|
|
940
|
+
| `/memory off` / `/memory on` | Stop or resume all memory writes for this install; existing facts stay readable and removable |
|
|
819
941
|
| `/memory export [file]` | Write the full, unbounded `ExperienceStore` contents (every strategy weight/decomposition/recovery sequence, not the 20-entry preview `/memory` prints) plus facts/reminders to a JSON file (default: `assistant-memory-<timestamp>.json`). Read-only: there's no matching import path, so exported data can't be hand-edited and loaded back in |
|
|
820
942
|
| `/search <query>` | Ranked search over past messages, across every session in this install — a hit is the one message that matched, not the whole session transcript around it. Read-only: never an LLM call or network request. Scoring is tokenized/graduated, not exact-substring-only (see "Conversation history" above), and a query matching nothing returns an explicit "no results" line |
|
|
943
|
+
| `/project [name]` | Show or switch the project new project-scoped facts are tagged with; `/project clear` reverts to the workspace default |
|
|
821
944
|
| `/model [name]` | Show the active model, or switch it — a thin alias over `/config set model <name>` (see "Configuration" above); rejected the same way if `model` is pinned by `ASSISTANT_MODEL` |
|
|
822
945
|
| `/cost` | Show token usage for the last turn and the running session total |
|
|
823
946
|
| `/doctor` | Check proxy reachability (proxy backend) or the `claude` binary (claude-cli backend), plus workspace root and data dir health — no dedicated check yet for the anthropic/openai/openrouter backends, only the backend-agnostic checks run for those |
|
|
824
947
|
| `/why` | Explain the harness path the last turn took (verification confidence + node sequence) |
|
|
948
|
+
| `/layers` | Show all 11 harness layers: fired or skipped, and why, for the last turn. `/layers settings` lists the reasoning layers with their cost/evidence; `/layers on\|off\|reset <id>` changes a layer's persisted on/off choice (an operator-set `AUDIT_*` env flag wins and shows as pinned) |
|
|
825
949
|
| `/sources` | List files/URLs the last turn actually consulted |
|
|
826
950
|
| `/plan` | Show the active structured plan's task status |
|
|
951
|
+
| `/plan sketch <request>` | One-shot, advisory plan sketch: no plan record, nothing staged, cannot execute |
|
|
952
|
+
| `/goals` | Review every known goal thread this session: status, tasks and visibility (freshly computed, carried over, done, suggested) |
|
|
953
|
+
| `/plan graph [thread-id]` | Draw the active plan as a read-only dependency graph (needs `planGraphMode` enabled; full-screen pane in the terminal UI with arrows/Tab/Enter/q, one static render in the plain REPL). Glyphs, mapping and keys: `docs/plan-visualization.md` |
|
|
827
954
|
| `/checkpoint [clear]` | Inspect a stuck in-progress harness checkpoint (step, node, failed-resume count so far), or `/checkpoint clear` to discard it — see "Recovering a stuck checkpoint" above. Scoped to just the checkpoint: unlike `/clear`, transcript/facts/plan are untouched |
|
|
828
955
|
|
|
829
956
|
### `/cost` and real vs. estimated dollar figures
|
|
@@ -831,13 +958,7 @@ change local session/config state — none of them make an LLM call themselves.
|
|
|
831
958
|
Token counts are always real, on every backend. The dollar figure attached to
|
|
832
959
|
them is not always the same kind of number:
|
|
833
960
|
|
|
834
|
-
- **
|
|
835
|
-
--output-format json`'s own `total_cost_usd` field — real Anthropic
|
|
836
|
-
accounting. It may read `$0` if the underlying `claude` session is
|
|
837
|
-
authenticated against a Pro/Max subscription rather than API billing, in
|
|
838
|
-
which case `$0` does *not* mean "this turn was free" — `/cost`'s output
|
|
839
|
-
says so explicitly.
|
|
840
|
-
- **every other backend** (`proxy`, `anthropic`, `openai`, `openrouter`):
|
|
961
|
+
- **every backend** (`proxy`, `anthropic`, `openai`, `openrouter`):
|
|
841
962
|
none of these compute a dollar cost themselves — only the raw token counts
|
|
842
963
|
each provider's response already includes (`@buildaharness/proxy` is a thin
|
|
843
964
|
pass-through, see `packages/proxy/src/forward.ts`; the three direct clients
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { VizNode } from './plan-viz/types.js';
|
|
2
|
+
/** Width at which the detail drawer docks to the right instead of being toggled. */
|
|
3
|
+
export declare const DRAWER_DOCK_COLUMNS = 120;
|
|
4
|
+
export interface PlanGraphPaneProps {
|
|
5
|
+
nodes: readonly VizNode[];
|
|
6
|
+
columns: number;
|
|
7
|
+
rows: number;
|
|
8
|
+
/** False while an approval prompt owns the keyboard: the pane stays drawn but ignores keys. */
|
|
9
|
+
active?: boolean;
|
|
10
|
+
color?: boolean;
|
|
11
|
+
ascii?: boolean;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read-only plan graph pane (plans/plan_visualization_plan.html, R2). Keys: arrows (or [ ]) move along edges and ranks, j/k and PgUp/PgDn scroll the detail drawer,
|
|
16
|
+
* Tab/Shift+Tab walk task order, Enter or d toggles the detail drawer below 120 columns, q or Esc closes.
|
|
17
|
+
* No key edits anything: the plan changes only through the approval gate.
|
|
18
|
+
*/
|
|
19
|
+
export declare function PlanGraphPane({ nodes, columns, rows, active, color, ascii, onClose }: PlanGraphPaneProps): React.JSX.Element;
|