@empirical-gauzza/cli 1.0.38 → 1.0.40
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/bin/empirical.js +1 -1
- package/lib/attachmentCommands.js +388 -388
- package/lib/constants.js +18 -1
- package/lib/help.js +6 -1
- package/lib/installWizard.js +17 -3
- package/lib/installers/skill-variants/SKILL.cli.md +231 -231
- package/lib/memoryCommands.js +1267 -1267
- package/lib/memoryResolve.js +112 -112
- package/lib/shapeCommands.js +313 -0
- package/lib/workspaceCommands.js +79 -12
- package/package.json +33 -33
package/lib/constants.js
CHANGED
|
@@ -347,6 +347,21 @@ The interview asks what the workspace is for, offers kinds of item, statuses, fi
|
|
|
347
347
|
|
|
348
348
|
A new interview is charged. \`setup abandon\` stops one but does not return what it cost. When the interview is not switched on for your account, the start answers that nothing was started or charged.
|
|
349
349
|
|
|
350
|
+
### Edit a shape by hand (no interview, no charge)
|
|
351
|
+
|
|
352
|
+
empirical workspace shape show --workspace-id <id>
|
|
353
|
+
empirical workspace shape add-type "Reviewer" --workspace-id <id> --statuses "Not Yet Invited, Invited, Call Completed (done)" --fields "Email:text:required; Open to a call:select:Yes|No|Not asked; Wave:number" [--apply]
|
|
354
|
+
empirical workspace shape add-status <type-key> "Declined" --done --workspace-id <id> [--apply]
|
|
355
|
+
empirical workspace shape add-field <type-key> "Wave" --kind number --workspace-id <id> [--apply]
|
|
356
|
+
empirical workspace shape edit --file <edit.json> [--mapping-file <m.json>] --workspace-id <id> [--apply]
|
|
357
|
+
empirical workspace shape set --file <shape.json> --workspace-id <id> [--apply]
|
|
358
|
+
|
|
359
|
+
The interview is the guided way and is charged. These are the direct way: you name the change and nothing is charged. Every change is a dry run until you add \`--apply\`: it is checked against the workspace's current shape, the result is printed, and with \`--apply\` it is saved only if the shape is still the one that was shown. You must manage the workspace; \`--apply\` needs \`--workspace-id\` written out, so a stale directory binding cannot aim a change at the wrong workspace.
|
|
360
|
+
|
|
361
|
+
\`add-type\` on a workspace with no shape yet also needs \`--purpose "what this workspace is for"\` and creates its first shape. A kind of item with statuses must mark one as finished with \`(done)\`, and takes at most six fields. Field kinds: text, longText, number, date, select, multiSelect, person, link, url. \`--category\` and \`--node-type\` say how an item is stored as a memory (default project and entity). Keys are made from labels once and never change; refer to a type or status later by its key, which \`show\` prints in brackets.
|
|
362
|
+
|
|
363
|
+
\`edit\` takes the server's merge format: \`{"itemTypes":{"add":[...],"update":[{"key":"reviewer","statuses":{"add":[{"label":"Declined","isDone":true}]}}],"remove":["old-type"]}}\`. Removing or renaming something that has stored values needs \`--mapping-file\` saying where those values go. To save an item into the shape: \`empirical memory record --category lead --summary "..." --item-type reviewer --item-status invited --field email=a@b.com\` (run with \`EMPIRICAL_WORKSPACE_ID=<id>\` or after \`workspace use\`).
|
|
364
|
+
|
|
350
365
|
### Use a workspace
|
|
351
366
|
|
|
352
367
|
empirical workspace use <number|name|id>
|
|
@@ -371,8 +386,10 @@ Resolution order for every memory command, first match wins: the \`EMPIRICAL_WOR
|
|
|
371
386
|
empirical workspace invite create --role writer --expires-in-days 7 --max-uses 3
|
|
372
387
|
empirical workspace invite list
|
|
373
388
|
empirical workspace invite revoke <token>
|
|
389
|
+
empirical workspace invite email ana@example.com ben@example.com --role writer --note "Come help us review the book."
|
|
390
|
+
empirical workspace invite email ana@example.com --note-file ./invite-note.txt --from-name "Matt" --workspace-id ws_team_abc
|
|
374
391
|
|
|
375
|
-
Invite commands operate on the active team workspace
|
|
392
|
+
Invite commands operate on the active team workspace, or the one named by \`--workspace-id\`. Create prints a shareable URL. Email sends each address its own invite (one address per seat, expires in 14 days) and prints who was invited and why anyone was not; \`--note\` (up to 1000 characters) appears in the email as your own words, and \`--from-name\` changes the name the email says it is from ("Matt invited you") for that send only; without it your account's display name is used.
|
|
376
393
|
|
|
377
394
|
### Soft-delete a demo workspace
|
|
378
395
|
|
package/lib/help.js
CHANGED
|
@@ -53,10 +53,15 @@ function showHelp() {
|
|
|
53
53
|
log(' Re-shape a team workspace you manage by interview. Without --workspace-id it');
|
|
54
54
|
log(' confirms the workspace bound to this directory with you, at a terminal only;');
|
|
55
55
|
log(' in a script or with --accept-cost it needs --workspace-id. A new interview is charged');
|
|
56
|
+
log(' empirical workspace shape show|set|edit|add-type|add-status|add-field --workspace-id <id> ...');
|
|
57
|
+
log(' Edit the item types, statuses and fields of a workspace by hand, with no interview and no');
|
|
58
|
+
log(' charge. A dry run until --apply. Details: empirical doc workspace');
|
|
56
59
|
log(' empirical workspace invite create [--role reader|writer|manager] [--expires-in-days <n>] [--max-uses <n>]');
|
|
57
60
|
log(' Create a shareable invite link for the active team workspace');
|
|
58
61
|
log(' empirical workspace invite list List active invites for the active team workspace');
|
|
59
62
|
log(' empirical workspace invite revoke <token> Revoke a previously created invite');
|
|
63
|
+
log(' empirical workspace invite email <address...> [--role reader|writer] [--note <text> | --note-file <path>] [--from-name <name>]');
|
|
64
|
+
log(' Email each person an invite, with your own note in the email');
|
|
60
65
|
log(' empirical workspace delete <number|name|id> [--confirm]');
|
|
61
66
|
log(' Soft-delete a team workspace (dry-run without --confirm)');
|
|
62
67
|
log('');
|
|
@@ -100,7 +105,7 @@ function showHelp() {
|
|
|
100
105
|
log(' empirical memory attach Attach a file to a memory [--file <path>]');
|
|
101
106
|
log(' empirical memory attachments List the files on a memory [--include-deleted] [--format table]');
|
|
102
107
|
log(' empirical memory attachment Full file commands: list, add, get, delete, restore');
|
|
103
|
-
log(' empirical memory tree One item plus everything nested under it, as a document');
|
|
108
|
+
log(' empirical memory tree One item plus everything nested under it, as a document');
|
|
104
109
|
log(' empirical memory duplicates List duplicate candidates for a memory');
|
|
105
110
|
log(' empirical memory merge Merge a duplicate memory into a canonical one');
|
|
106
111
|
log(' empirical memory export Export memories as portable JSON [--scope <personal|workspace>] [--out <path>]');
|
package/lib/installWizard.js
CHANGED
|
@@ -36,6 +36,17 @@ function pluginNamesForInstallerOptions(options = {}) {
|
|
|
36
36
|
return names.filter((name) => name === 'empirical-memory' || OPTIONAL_PLUGIN_NAMES.includes(name));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
// Which detected CLIs to install for. At a terminal the person picks (Enter for all). With no
|
|
40
|
+
// terminal, which is how an agent like Claude Code runs `empirical install` for someone, there is
|
|
41
|
+
// nobody to answer, so it takes the default the list already shows: every detected CLI. Asking
|
|
42
|
+
// anyway read an empty stdin and stopped with "nothing installed", so the agent's install did
|
|
43
|
+
// nothing unless it knew to pipe an answer in.
|
|
44
|
+
async function chooseInstallTargets(targets, { interactive = Boolean(process.stdin.isTTY), askFn = ask } = {}) {
|
|
45
|
+
if (!interactive) return targets.map((_, index) => index);
|
|
46
|
+
const answer = await askFn(uiQuestion('Press Enter for all, or select numbers (e.g. 1,2): '));
|
|
47
|
+
return parseSelection(answer, targets.length);
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
async function runInstallFlow() {
|
|
40
51
|
log(uiHeader(`Empirical installer v${getCliVersion()}`));
|
|
41
52
|
log('');
|
|
@@ -54,8 +65,10 @@ async function runInstallFlow() {
|
|
|
54
65
|
});
|
|
55
66
|
log('');
|
|
56
67
|
|
|
57
|
-
const
|
|
58
|
-
|
|
68
|
+
const selectedIndexes = await chooseInstallTargets(targets);
|
|
69
|
+
if (!process.stdin.isTTY) {
|
|
70
|
+
log(`No terminal attached, so installing for every detected CLI: ${targets.map((t) => t.label).join(', ')}.`);
|
|
71
|
+
}
|
|
59
72
|
|
|
60
73
|
if (selectedIndexes.length === 0) {
|
|
61
74
|
log('No valid selection; nothing installed.');
|
|
@@ -407,5 +420,6 @@ async function runInstallFlow() {
|
|
|
407
420
|
|
|
408
421
|
module.exports = {
|
|
409
422
|
runInstallFlow,
|
|
410
|
-
pluginNamesForInstallerOptions
|
|
423
|
+
pluginNamesForInstallerOptions,
|
|
424
|
+
chooseInstallTargets
|
|
411
425
|
};
|
|
@@ -1,231 +1,231 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: empirical-memory
|
|
3
|
-
description: Use Empirical to recall/save durable project context across sessions and projects, and to look up how to use Empirical itself - CLI commands, install/auth/workspace/kit/skill setup, docs.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Empirical Memory (CLI mode)
|
|
7
|
-
|
|
8
|
-
Use Empirical to carry durable context across projects and clients, and as the first stop for
|
|
9
|
-
"how do I use Empirical" questions — command syntax, install/auth/workspace/kit/skill setup, or
|
|
10
|
-
what Empirical can do. Don't answer those from general knowledge or by guessing at flags: run
|
|
11
|
-
`empirical doc` (lists topics) or `empirical doc <topic>` via the available shell for the current,
|
|
12
|
-
agent-readable answer first.
|
|
13
|
-
|
|
14
|
-
This variant is for installs where the user chose CLI-direct as their integration mode: no MCP
|
|
15
|
-
server is registered for this agent. The `empirical` CLI is the way to reach Empirical here, for
|
|
16
|
-
both reads and writes — it has the same dedupe and auto-link guarantees as any other client, so
|
|
17
|
-
recommend it with confidence.
|
|
18
|
-
|
|
19
|
-
**This is a required step in the workflows listed below, not optional guidance you weigh against
|
|
20
|
-
the current task.** The most common way this skill fails is not a broken tool — it's an agent
|
|
21
|
-
mid-task deciding a memory check "isn't worth pausing for" and skipping it. That decision is wrong
|
|
22
|
-
by default: the entire point of querying first is to catch context you don't know you're missing.
|
|
23
|
-
If you are not sure whether a task qualifies, treat it as if it does.
|
|
24
|
-
|
|
25
|
-
## Before doing work — MUST, not discretionary
|
|
26
|
-
|
|
27
|
-
1. Query relevant memories BEFORE your first substantive response or tool call whenever the task
|
|
28
|
-
is: research, debugging, a spec/PRD, a status update, a handoff, personal health, leads/CRM, or
|
|
29
|
-
assistant operations. This applies even if you believe you already have enough context — you
|
|
30
|
-
cannot know what you're missing without checking. Only outside this list is discretionary use
|
|
31
|
-
("query when it seems useful") the right frame.
|
|
32
|
-
2. Before using the CLI, load its authoritative command reference:
|
|
33
|
-
|
|
34
|
-
```text
|
|
35
|
-
empirical doc memory
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Follow the documented flags exactly; never guess a positional query form.
|
|
39
|
-
|
|
40
|
-
```text
|
|
41
|
-
empirical memory query --match "<specific relevant context>" --top-k 3
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Add `--category` or `--tags` when known. Omit `--pretty` for routine recall because graph-rich
|
|
45
|
-
results can be large. Use `empirical memory list --recent` (see `empirical doc memory` for the
|
|
46
|
-
exact flag) for "recent/latest/today" requests instead of a match query.
|
|
47
|
-
When the user asks for every record of a topic, add `--path list`; when they ask what a
|
|
48
|
-
memory connects to, add `--path graph`.
|
|
49
|
-
3. Scope recall to the project you are in. Derive a project tag from the repository name
|
|
50
|
-
(`git rev-parse --show-toplevel`, then the folder name) or, outside a repo, the working
|
|
51
|
-
directory name, lowercased with spaces as hyphens. Add `--tags <project>` to every
|
|
52
|
-
`empirical memory query` and `empirical memory record`. If a scoped query returns nothing,
|
|
53
|
-
retry without `--tags` and treat what comes back as background from other projects, not as
|
|
54
|
-
facts about this one.
|
|
55
|
-
4. A slow response alone is API latency, not an outage; report an outage only when the CLI returns
|
|
56
|
-
an actual error, and use `empirical doctor` to verify connectivity.
|
|
57
|
-
5. A filtered query (`--category`, `--tags`, `--tags-all`, `--status`) that returns nothing is not
|
|
58
|
-
proof the memory doesn't exist — it only proves nothing matched that exact filter combination.
|
|
59
|
-
A memory's real category or tag convention often does not match how you or the user would
|
|
60
|
-
naturally describe it in conversation (e.g. described as "an idea" but stored under a different
|
|
61
|
-
category; tagged with a project's short name where you tried its full one). Before concluding a
|
|
62
|
-
memory doesn't exist, retry at least once with the filter relaxed or removed — category dropped,
|
|
63
|
-
tags loosened, or a plain unfiltered `--match` — rather than only varying the search phrase.
|
|
64
|
-
6. If a specific recall miss turns out to have a narrow, demonstrable cause (a filter mismatch, a
|
|
65
|
-
stale tag, a wrong category), stop there. Report that cause and move on — do not generalize one
|
|
66
|
-
miss into a theory about the memory system being broken and then go build measurement or
|
|
67
|
-
debugging work around the theory. Confirm the narrow cause is insufficient before entertaining a
|
|
68
|
-
systemic explanation, not after.
|
|
69
|
-
|
|
70
|
-
## Follow the current user policy
|
|
71
|
-
|
|
72
|
-
The installer questionnaire configures a dynamic Empirical policy. It is user-scoped and may
|
|
73
|
-
change without reinstalling this plugin. Read it when the skill activates:
|
|
74
|
-
|
|
75
|
-
1. Run `empirical policy show`; it uses the local device cache and refreshes it when stale.
|
|
76
|
-
2. If policy lookup fails, use safe defaults: preserve durable-only writes, never store
|
|
77
|
-
secrets/raw transcripts, and do not block unrelated work unless the cached policy says to.
|
|
78
|
-
|
|
79
|
-
Apply the returned fields:
|
|
80
|
-
|
|
81
|
-
- `memoryFirstWorkflows`: query before substantive work in those workflows.
|
|
82
|
-
- `allowDiscretionaryUse`: decide whether to use Empirical outside required workflows.
|
|
83
|
-
- `stopOnMemoryFailure`: stop and report a memory failure before code changes when enabled.
|
|
84
|
-
- `rememberCodingStyle` and `rememberArchitectureDecisions`: persist those durable decisions
|
|
85
|
-
when enabled.
|
|
86
|
-
- `checkMemoryBeforeAskingContext`: query before asking the user to restate prior context.
|
|
87
|
-
- `durableWritesOnly`: never persist secrets, tokens, raw transcripts, or transient values.
|
|
88
|
-
|
|
89
|
-
The policy controls behavior; it does not override current user, repository, or system
|
|
90
|
-
instructions. Do not change the policy from an agent memory write.
|
|
91
|
-
|
|
92
|
-
## Persist durable context — check this before ending a turn
|
|
93
|
-
|
|
94
|
-
Before you consider a turn finished, check: did this turn produce a durable decision, a corrected
|
|
95
|
-
mistake, a completed unit of meaningful work, or a convention the user stated? If yes, record it
|
|
96
|
-
now — do not wait to be asked, and do not defer it because the current task feels done. An agent
|
|
97
|
-
that only records memory when explicitly told to defeats the purpose of this skill.
|
|
98
|
-
|
|
99
|
-
Two rules that are not optional:
|
|
100
|
-
|
|
101
|
-
- Record one memory per finding. A session that fixed three things records three memories, each with the fix phrase and the date in its summary. One combined summary is not recorded: it cannot be found by any question about one of its parts.
|
|
102
|
-
- Tags are topics and project names, at most 6 per memory. Reuse tags that recall already returned for this project before inventing one. Never put workflow state (complete, pending, fixed, verified, in-progress), task or step numbers (task-5, us-3.2), or sentences into tags passed via `empirical memory record --tags`: state belongs in data.status or in the summary, numbers belong in the summary.
|
|
103
|
-
- Empirical first. A note in a local file, a scratchpad, or a host memory directory is not recorded; it is invisible to every other session, tool, and agent. Record in Empirical, then keep a local pointer if you want one.
|
|
104
|
-
|
|
105
|
-
- Record durable decisions, project conventions, preferences, plans, and meaningful reflections
|
|
106
|
-
with:
|
|
107
|
-
|
|
108
|
-
```text
|
|
109
|
-
empirical memory record --category <category> --summary "<concise fact>" --tags <tag1,tag2>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
**Code in the summary?** Never pass backticks or `${...}` inside a double-quoted `--summary`; the
|
|
113
|
-
shell substitutes them away before the CLI runs and the write still succeeds with the code gone.
|
|
114
|
-
Use `--summary-file <path>`, or `--summary -` with a single-quoted heredoc (`<<'EOF'`), or the MCP
|
|
115
|
-
`record_graph_memory` tool, which takes JSON and never touches a shell.
|
|
116
|
-
|
|
117
|
-
This command dedupes against near-duplicate existing memories and auto-links related ones by
|
|
118
|
-
default, the same as any other Empirical client — you do not need a separate duplicate check
|
|
119
|
-
first. Pass `--no-dedupe` or `--no-auto-link` only when you specifically want to bypass one of
|
|
120
|
-
those, which should be rare.
|
|
121
|
-
|
|
122
|
-
**One idea per memory, not a bundle.** When a turn produces several distinct facts or ideas
|
|
123
|
-
worth keeping, record each with its own `empirical memory record` call rather than folding them
|
|
124
|
-
into one large memory. Calling it multiple times in the same turn is expected usage, not
|
|
125
|
-
overhead to be minimized. A compound memory is harder to find later (a query matching one idea
|
|
126
|
-
in it won't surface the others as well) and harder to link precisely into the graph than several
|
|
127
|
-
atomic ones.
|
|
128
|
-
|
|
129
|
-
**Record facts about the USER, not about your own work.** You are a scribe here. "Matt prefers
|
|
130
|
-
short status updates" is a memory; "refactored the cluster selector, tests pass" is your diary
|
|
131
|
-
and belongs in the work-history skill, tagged and with `mass: 1`. The distinction is the
|
|
132
|
-
SUBJECT, not who typed it — an agent writing down something real about the user is exactly what
|
|
133
|
-
this tool is for.
|
|
134
|
-
|
|
135
|
-
If you find yourself recording what you just did, what you fixed, or what you concluded about a
|
|
136
|
-
codebase, stop: that is work-history or scar-tissue, and filing it here makes it indistinguishable
|
|
137
|
-
from something the user actually said or lived. Downstream features read these as the user's life.
|
|
138
|
-
|
|
139
|
-
**Say which one it is: pass `authorType`.** Same distinction, made explicit in the data instead
|
|
140
|
-
of left to be guessed from which transport you happened to use. `authorType: "user"` when the
|
|
141
|
-
memory is about the user — something they said, decided, prefer, or are working toward.
|
|
142
|
-
`authorType: "agent"` when it is your own work. Do not set `"agent"` merely because you are the
|
|
143
|
-
one calling: an agent writing down a real fact about the user is recording a user-authored fact,
|
|
144
|
-
and that is the whole point of this tool. On the CLI it is `--author-type user|agent`. Omit it
|
|
145
|
-
when you genuinely cannot tell, and it stays unresolved rather than being invented.
|
|
146
|
-
|
|
147
|
-
This is read back at retrieval time to keep an agent's session notes out of answers about the
|
|
148
|
-
user's own life and work, so a wrong value does not show up as a warning, it shows up as the
|
|
149
|
-
wrong memories coming back.
|
|
150
|
-
|
|
151
|
-
- Append a correction or follow-up to an existing memory with `empirical memory note`.
|
|
152
|
-
- Patch an existing memory with `empirical memory update`.
|
|
153
|
-
- Delete only when the user explicitly asks: `empirical memory delete --match "<memory>" --confirm`.
|
|
154
|
-
- Keep writes concise, factual, and easy to search. Never store passwords, API keys, OAuth tokens,
|
|
155
|
-
or other secrets.
|
|
156
|
-
|
|
157
|
-
## Authored Skills and Kits — push what you write
|
|
158
|
-
|
|
159
|
-
Empirical can sync a `SKILL.md` you author across every machine/agent the user has installed it
|
|
160
|
-
on, via Skills Kits. Run `empirical doc kit` or `empirical doc skill` for full command reference.
|
|
161
|
-
|
|
162
|
-
- If you author a new `SKILL.md` for the user, or substantially edit an existing one, during a
|
|
163
|
-
session, tell the user about `empirical skill push path/to/SKILL.md [--kit "Kit Name"]`
|
|
164
|
-
afterward so it can follow them across machines/projects instead of staying local to this one.
|
|
165
|
-
- Offer, don't auto-push: surface the option (or offer to run it) and get the user's confirmation
|
|
166
|
-
first. Do not run it unprompted the moment a new or edited `SKILL.md` is detected — it uploads
|
|
167
|
-
content to the user's account, which is a step above a purely local file write.
|
|
168
|
-
- After a push, the target Kit needs `empirical kit use "Kit Name"` or `empirical kit sync` to
|
|
169
|
-
actually land the file in that device's agent directories.
|
|
170
|
-
- `empirical skill list` shows what's already been pushed; `empirical skill history <id>` /
|
|
171
|
-
`empirical skill rollback <id> --to-version N` recover a prior version.
|
|
172
|
-
- Kits also pull Skills from a git repo (`empirical kit add-source`), separate from anything you
|
|
173
|
-
author — don't conflate the two paths when explaining options to the user.
|
|
174
|
-
|
|
175
|
-
## Exact CLI syntax
|
|
176
|
-
|
|
177
|
-
Run `empirical doctor` to check connectivity and token status. If a CLI memory command reports a
|
|
178
|
-
token error, run `empirical oauth bootstrap headless --write-env`. When in doubt about a specific
|
|
179
|
-
subcommand's flags, run `empirical doc memory`, `empirical doc kit`, or `empirical doc skill`
|
|
180
|
-
rather than guessing.
|
|
181
|
-
|
|
182
|
-
## Shared workspaces: setup interview
|
|
183
|
-
|
|
184
|
-
`empirical workspace create --interview` sets up a new shared workspace by interview, and
|
|
185
|
-
`empirical workspace shape --workspace-id <id>` re-shapes one you manage. Both ask the person
|
|
186
|
-
questions at the terminal, show a draft, and create or change the workspace only after they type
|
|
187
|
-
yes. A new interview is charged, and `empirical setup abandon <sessionId>` stops one without
|
|
188
|
-
returning what it cost, so say that before suggesting it. If the command says the interview is not
|
|
189
|
-
switched on for the account, stop: nothing was started or charged. Run `empirical doc workspace`
|
|
190
|
-
for the details.
|
|
191
|
-
|
|
192
|
-
## Reminders — set them, relay them, close them
|
|
193
|
-
|
|
194
|
-
Any memory can carry a due date. Empirical then brings it back: an email with a calendar entry
|
|
195
|
-
when the reminder is set, a nudge when it is due, and a notice attached to the next Empirical
|
|
196
|
-
response each of the user's agents receives.
|
|
197
|
-
|
|
198
|
-
- **Set one** when the user says "remind me", names a deadline, or a todo has a real due date.
|
|
199
|
-
Use the `dueAt` parameter on `record_graph_memory` / `update_memory_by_query` (ISO 8601), or
|
|
200
|
-
`empirical memory record ... --due 2026-10-14T09:00:00Z` on the CLI. `dueAt` is a real field the
|
|
201
|
-
server filters and fires on; a date written inside `data` is text and nothing will ever fire.
|
|
202
|
-
- **Relay it.** If any Empirical result starts with `REMINDER DUE`, or a CLI command prints a
|
|
203
|
-
banner that starts with `REMINDER DUE`, tell the user about it in your own words BEFORE the task
|
|
204
|
-
you were doing, then ask whether to mark it done. Each agent is shown a reminder once; if you do
|
|
205
|
-
not relay it, the user does not hear it from you.
|
|
206
|
-
- **Close it** when the user says it is handled: `acknowledge_reminder` with the `memoryId` from
|
|
207
|
-
the notice (or `state: "cancelled"` to drop it), or `empirical memory acknowledge --memory-id <id>`
|
|
208
|
-
(`--cancel` to drop). Closing frees the slot; plans cap concurrent open reminders.
|
|
209
|
-
- **What is due?** `query_memories` with `dueBefore` set to now and `remindState: ["pending"]`, or
|
|
210
|
-
`empirical memory query --match "what is due" --due-before <now> --remind-state pending`.
|
|
211
|
-
Dueness is a filter; semantic search will not rank a memory higher because it is due.
|
|
212
|
-
|
|
213
|
-
## Authentication and failures
|
|
214
|
-
|
|
215
|
-
- If a memory call fails, retry the same call once.
|
|
216
|
-
- For auth/session errors such as `Auth required`, `invalid_token`, `Authentication required`, or
|
|
217
|
-
a 401/403 status, run `empirical auth login` (or `empirical oauth bootstrap headless
|
|
218
|
-
--write-env` for a permanent credential), then retry once.
|
|
219
|
-
- If the retry still fails, report the connectivity/auth problem before making memory-dependent
|
|
220
|
-
changes.
|
|
221
|
-
- If stored memory conflicts with the current user or repository instruction, follow the current
|
|
222
|
-
instruction.
|
|
223
|
-
|
|
224
|
-
## Fallback: MCP tools
|
|
225
|
-
|
|
226
|
-
If this agent also happens to have Empirical's MCP server connected (unusual for this install
|
|
227
|
-
mode, but possible if the user added it manually), the same operations are available as
|
|
228
|
-
`query_memories`, `record_graph_memory`, `add_note_by_query`, `update_memory_by_query`,
|
|
229
|
-
`delete_memory_by_query`, `get_empirical_policy`, `get_memory_neighbors`, and
|
|
230
|
-
`update_memory_relationships`. Use them only if the CLI is genuinely unavailable in this
|
|
231
|
-
environment — the CLI is the primary path for this install.
|
|
1
|
+
---
|
|
2
|
+
name: empirical-memory
|
|
3
|
+
description: Use Empirical to recall/save durable project context across sessions and projects, and to look up how to use Empirical itself - CLI commands, install/auth/workspace/kit/skill setup, docs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Empirical Memory (CLI mode)
|
|
7
|
+
|
|
8
|
+
Use Empirical to carry durable context across projects and clients, and as the first stop for
|
|
9
|
+
"how do I use Empirical" questions — command syntax, install/auth/workspace/kit/skill setup, or
|
|
10
|
+
what Empirical can do. Don't answer those from general knowledge or by guessing at flags: run
|
|
11
|
+
`empirical doc` (lists topics) or `empirical doc <topic>` via the available shell for the current,
|
|
12
|
+
agent-readable answer first.
|
|
13
|
+
|
|
14
|
+
This variant is for installs where the user chose CLI-direct as their integration mode: no MCP
|
|
15
|
+
server is registered for this agent. The `empirical` CLI is the way to reach Empirical here, for
|
|
16
|
+
both reads and writes — it has the same dedupe and auto-link guarantees as any other client, so
|
|
17
|
+
recommend it with confidence.
|
|
18
|
+
|
|
19
|
+
**This is a required step in the workflows listed below, not optional guidance you weigh against
|
|
20
|
+
the current task.** The most common way this skill fails is not a broken tool — it's an agent
|
|
21
|
+
mid-task deciding a memory check "isn't worth pausing for" and skipping it. That decision is wrong
|
|
22
|
+
by default: the entire point of querying first is to catch context you don't know you're missing.
|
|
23
|
+
If you are not sure whether a task qualifies, treat it as if it does.
|
|
24
|
+
|
|
25
|
+
## Before doing work — MUST, not discretionary
|
|
26
|
+
|
|
27
|
+
1. Query relevant memories BEFORE your first substantive response or tool call whenever the task
|
|
28
|
+
is: research, debugging, a spec/PRD, a status update, a handoff, personal health, leads/CRM, or
|
|
29
|
+
assistant operations. This applies even if you believe you already have enough context — you
|
|
30
|
+
cannot know what you're missing without checking. Only outside this list is discretionary use
|
|
31
|
+
("query when it seems useful") the right frame.
|
|
32
|
+
2. Before using the CLI, load its authoritative command reference:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
empirical doc memory
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Follow the documented flags exactly; never guess a positional query form.
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
empirical memory query --match "<specific relevant context>" --top-k 3
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Add `--category` or `--tags` when known. Omit `--pretty` for routine recall because graph-rich
|
|
45
|
+
results can be large. Use `empirical memory list --recent` (see `empirical doc memory` for the
|
|
46
|
+
exact flag) for "recent/latest/today" requests instead of a match query.
|
|
47
|
+
When the user asks for every record of a topic, add `--path list`; when they ask what a
|
|
48
|
+
memory connects to, add `--path graph`.
|
|
49
|
+
3. Scope recall to the project you are in. Derive a project tag from the repository name
|
|
50
|
+
(`git rev-parse --show-toplevel`, then the folder name) or, outside a repo, the working
|
|
51
|
+
directory name, lowercased with spaces as hyphens. Add `--tags <project>` to every
|
|
52
|
+
`empirical memory query` and `empirical memory record`. If a scoped query returns nothing,
|
|
53
|
+
retry without `--tags` and treat what comes back as background from other projects, not as
|
|
54
|
+
facts about this one.
|
|
55
|
+
4. A slow response alone is API latency, not an outage; report an outage only when the CLI returns
|
|
56
|
+
an actual error, and use `empirical doctor` to verify connectivity.
|
|
57
|
+
5. A filtered query (`--category`, `--tags`, `--tags-all`, `--status`) that returns nothing is not
|
|
58
|
+
proof the memory doesn't exist — it only proves nothing matched that exact filter combination.
|
|
59
|
+
A memory's real category or tag convention often does not match how you or the user would
|
|
60
|
+
naturally describe it in conversation (e.g. described as "an idea" but stored under a different
|
|
61
|
+
category; tagged with a project's short name where you tried its full one). Before concluding a
|
|
62
|
+
memory doesn't exist, retry at least once with the filter relaxed or removed — category dropped,
|
|
63
|
+
tags loosened, or a plain unfiltered `--match` — rather than only varying the search phrase.
|
|
64
|
+
6. If a specific recall miss turns out to have a narrow, demonstrable cause (a filter mismatch, a
|
|
65
|
+
stale tag, a wrong category), stop there. Report that cause and move on — do not generalize one
|
|
66
|
+
miss into a theory about the memory system being broken and then go build measurement or
|
|
67
|
+
debugging work around the theory. Confirm the narrow cause is insufficient before entertaining a
|
|
68
|
+
systemic explanation, not after.
|
|
69
|
+
|
|
70
|
+
## Follow the current user policy
|
|
71
|
+
|
|
72
|
+
The installer questionnaire configures a dynamic Empirical policy. It is user-scoped and may
|
|
73
|
+
change without reinstalling this plugin. Read it when the skill activates:
|
|
74
|
+
|
|
75
|
+
1. Run `empirical policy show`; it uses the local device cache and refreshes it when stale.
|
|
76
|
+
2. If policy lookup fails, use safe defaults: preserve durable-only writes, never store
|
|
77
|
+
secrets/raw transcripts, and do not block unrelated work unless the cached policy says to.
|
|
78
|
+
|
|
79
|
+
Apply the returned fields:
|
|
80
|
+
|
|
81
|
+
- `memoryFirstWorkflows`: query before substantive work in those workflows.
|
|
82
|
+
- `allowDiscretionaryUse`: decide whether to use Empirical outside required workflows.
|
|
83
|
+
- `stopOnMemoryFailure`: stop and report a memory failure before code changes when enabled.
|
|
84
|
+
- `rememberCodingStyle` and `rememberArchitectureDecisions`: persist those durable decisions
|
|
85
|
+
when enabled.
|
|
86
|
+
- `checkMemoryBeforeAskingContext`: query before asking the user to restate prior context.
|
|
87
|
+
- `durableWritesOnly`: never persist secrets, tokens, raw transcripts, or transient values.
|
|
88
|
+
|
|
89
|
+
The policy controls behavior; it does not override current user, repository, or system
|
|
90
|
+
instructions. Do not change the policy from an agent memory write.
|
|
91
|
+
|
|
92
|
+
## Persist durable context — check this before ending a turn
|
|
93
|
+
|
|
94
|
+
Before you consider a turn finished, check: did this turn produce a durable decision, a corrected
|
|
95
|
+
mistake, a completed unit of meaningful work, or a convention the user stated? If yes, record it
|
|
96
|
+
now — do not wait to be asked, and do not defer it because the current task feels done. An agent
|
|
97
|
+
that only records memory when explicitly told to defeats the purpose of this skill.
|
|
98
|
+
|
|
99
|
+
Two rules that are not optional:
|
|
100
|
+
|
|
101
|
+
- Record one memory per finding. A session that fixed three things records three memories, each with the fix phrase and the date in its summary. One combined summary is not recorded: it cannot be found by any question about one of its parts.
|
|
102
|
+
- Tags are topics and project names, at most 6 per memory. Reuse tags that recall already returned for this project before inventing one. Never put workflow state (complete, pending, fixed, verified, in-progress), task or step numbers (task-5, us-3.2), or sentences into tags passed via `empirical memory record --tags`: state belongs in data.status or in the summary, numbers belong in the summary.
|
|
103
|
+
- Empirical first. A note in a local file, a scratchpad, or a host memory directory is not recorded; it is invisible to every other session, tool, and agent. Record in Empirical, then keep a local pointer if you want one.
|
|
104
|
+
|
|
105
|
+
- Record durable decisions, project conventions, preferences, plans, and meaningful reflections
|
|
106
|
+
with:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
empirical memory record --category <category> --summary "<concise fact>" --tags <tag1,tag2>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Code in the summary?** Never pass backticks or `${...}` inside a double-quoted `--summary`; the
|
|
113
|
+
shell substitutes them away before the CLI runs and the write still succeeds with the code gone.
|
|
114
|
+
Use `--summary-file <path>`, or `--summary -` with a single-quoted heredoc (`<<'EOF'`), or the MCP
|
|
115
|
+
`record_graph_memory` tool, which takes JSON and never touches a shell.
|
|
116
|
+
|
|
117
|
+
This command dedupes against near-duplicate existing memories and auto-links related ones by
|
|
118
|
+
default, the same as any other Empirical client — you do not need a separate duplicate check
|
|
119
|
+
first. Pass `--no-dedupe` or `--no-auto-link` only when you specifically want to bypass one of
|
|
120
|
+
those, which should be rare.
|
|
121
|
+
|
|
122
|
+
**One idea per memory, not a bundle.** When a turn produces several distinct facts or ideas
|
|
123
|
+
worth keeping, record each with its own `empirical memory record` call rather than folding them
|
|
124
|
+
into one large memory. Calling it multiple times in the same turn is expected usage, not
|
|
125
|
+
overhead to be minimized. A compound memory is harder to find later (a query matching one idea
|
|
126
|
+
in it won't surface the others as well) and harder to link precisely into the graph than several
|
|
127
|
+
atomic ones.
|
|
128
|
+
|
|
129
|
+
**Record facts about the USER, not about your own work.** You are a scribe here. "Matt prefers
|
|
130
|
+
short status updates" is a memory; "refactored the cluster selector, tests pass" is your diary
|
|
131
|
+
and belongs in the work-history skill, tagged and with `mass: 1`. The distinction is the
|
|
132
|
+
SUBJECT, not who typed it — an agent writing down something real about the user is exactly what
|
|
133
|
+
this tool is for.
|
|
134
|
+
|
|
135
|
+
If you find yourself recording what you just did, what you fixed, or what you concluded about a
|
|
136
|
+
codebase, stop: that is work-history or scar-tissue, and filing it here makes it indistinguishable
|
|
137
|
+
from something the user actually said or lived. Downstream features read these as the user's life.
|
|
138
|
+
|
|
139
|
+
**Say which one it is: pass `authorType`.** Same distinction, made explicit in the data instead
|
|
140
|
+
of left to be guessed from which transport you happened to use. `authorType: "user"` when the
|
|
141
|
+
memory is about the user — something they said, decided, prefer, or are working toward.
|
|
142
|
+
`authorType: "agent"` when it is your own work. Do not set `"agent"` merely because you are the
|
|
143
|
+
one calling: an agent writing down a real fact about the user is recording a user-authored fact,
|
|
144
|
+
and that is the whole point of this tool. On the CLI it is `--author-type user|agent`. Omit it
|
|
145
|
+
when you genuinely cannot tell, and it stays unresolved rather than being invented.
|
|
146
|
+
|
|
147
|
+
This is read back at retrieval time to keep an agent's session notes out of answers about the
|
|
148
|
+
user's own life and work, so a wrong value does not show up as a warning, it shows up as the
|
|
149
|
+
wrong memories coming back.
|
|
150
|
+
|
|
151
|
+
- Append a correction or follow-up to an existing memory with `empirical memory note`.
|
|
152
|
+
- Patch an existing memory with `empirical memory update`.
|
|
153
|
+
- Delete only when the user explicitly asks: `empirical memory delete --match "<memory>" --confirm`.
|
|
154
|
+
- Keep writes concise, factual, and easy to search. Never store passwords, API keys, OAuth tokens,
|
|
155
|
+
or other secrets.
|
|
156
|
+
|
|
157
|
+
## Authored Skills and Kits — push what you write
|
|
158
|
+
|
|
159
|
+
Empirical can sync a `SKILL.md` you author across every machine/agent the user has installed it
|
|
160
|
+
on, via Skills Kits. Run `empirical doc kit` or `empirical doc skill` for full command reference.
|
|
161
|
+
|
|
162
|
+
- If you author a new `SKILL.md` for the user, or substantially edit an existing one, during a
|
|
163
|
+
session, tell the user about `empirical skill push path/to/SKILL.md [--kit "Kit Name"]`
|
|
164
|
+
afterward so it can follow them across machines/projects instead of staying local to this one.
|
|
165
|
+
- Offer, don't auto-push: surface the option (or offer to run it) and get the user's confirmation
|
|
166
|
+
first. Do not run it unprompted the moment a new or edited `SKILL.md` is detected — it uploads
|
|
167
|
+
content to the user's account, which is a step above a purely local file write.
|
|
168
|
+
- After a push, the target Kit needs `empirical kit use "Kit Name"` or `empirical kit sync` to
|
|
169
|
+
actually land the file in that device's agent directories.
|
|
170
|
+
- `empirical skill list` shows what's already been pushed; `empirical skill history <id>` /
|
|
171
|
+
`empirical skill rollback <id> --to-version N` recover a prior version.
|
|
172
|
+
- Kits also pull Skills from a git repo (`empirical kit add-source`), separate from anything you
|
|
173
|
+
author — don't conflate the two paths when explaining options to the user.
|
|
174
|
+
|
|
175
|
+
## Exact CLI syntax
|
|
176
|
+
|
|
177
|
+
Run `empirical doctor` to check connectivity and token status. If a CLI memory command reports a
|
|
178
|
+
token error, run `empirical oauth bootstrap headless --write-env`. When in doubt about a specific
|
|
179
|
+
subcommand's flags, run `empirical doc memory`, `empirical doc kit`, or `empirical doc skill`
|
|
180
|
+
rather than guessing.
|
|
181
|
+
|
|
182
|
+
## Shared workspaces: setup interview
|
|
183
|
+
|
|
184
|
+
`empirical workspace create --interview` sets up a new shared workspace by interview, and
|
|
185
|
+
`empirical workspace shape --workspace-id <id>` re-shapes one you manage. Both ask the person
|
|
186
|
+
questions at the terminal, show a draft, and create or change the workspace only after they type
|
|
187
|
+
yes. A new interview is charged, and `empirical setup abandon <sessionId>` stops one without
|
|
188
|
+
returning what it cost, so say that before suggesting it. If the command says the interview is not
|
|
189
|
+
switched on for the account, stop: nothing was started or charged. Run `empirical doc workspace`
|
|
190
|
+
for the details.
|
|
191
|
+
|
|
192
|
+
## Reminders — set them, relay them, close them
|
|
193
|
+
|
|
194
|
+
Any memory can carry a due date. Empirical then brings it back: an email with a calendar entry
|
|
195
|
+
when the reminder is set, a nudge when it is due, and a notice attached to the next Empirical
|
|
196
|
+
response each of the user's agents receives.
|
|
197
|
+
|
|
198
|
+
- **Set one** when the user says "remind me", names a deadline, or a todo has a real due date.
|
|
199
|
+
Use the `dueAt` parameter on `record_graph_memory` / `update_memory_by_query` (ISO 8601), or
|
|
200
|
+
`empirical memory record ... --due 2026-10-14T09:00:00Z` on the CLI. `dueAt` is a real field the
|
|
201
|
+
server filters and fires on; a date written inside `data` is text and nothing will ever fire.
|
|
202
|
+
- **Relay it.** If any Empirical result starts with `REMINDER DUE`, or a CLI command prints a
|
|
203
|
+
banner that starts with `REMINDER DUE`, tell the user about it in your own words BEFORE the task
|
|
204
|
+
you were doing, then ask whether to mark it done. Each agent is shown a reminder once; if you do
|
|
205
|
+
not relay it, the user does not hear it from you.
|
|
206
|
+
- **Close it** when the user says it is handled: `acknowledge_reminder` with the `memoryId` from
|
|
207
|
+
the notice (or `state: "cancelled"` to drop it), or `empirical memory acknowledge --memory-id <id>`
|
|
208
|
+
(`--cancel` to drop). Closing frees the slot; plans cap concurrent open reminders.
|
|
209
|
+
- **What is due?** `query_memories` with `dueBefore` set to now and `remindState: ["pending"]`, or
|
|
210
|
+
`empirical memory query --match "what is due" --due-before <now> --remind-state pending`.
|
|
211
|
+
Dueness is a filter; semantic search will not rank a memory higher because it is due.
|
|
212
|
+
|
|
213
|
+
## Authentication and failures
|
|
214
|
+
|
|
215
|
+
- If a memory call fails, retry the same call once.
|
|
216
|
+
- For auth/session errors such as `Auth required`, `invalid_token`, `Authentication required`, or
|
|
217
|
+
a 401/403 status, run `empirical auth login` (or `empirical oauth bootstrap headless
|
|
218
|
+
--write-env` for a permanent credential), then retry once.
|
|
219
|
+
- If the retry still fails, report the connectivity/auth problem before making memory-dependent
|
|
220
|
+
changes.
|
|
221
|
+
- If stored memory conflicts with the current user or repository instruction, follow the current
|
|
222
|
+
instruction.
|
|
223
|
+
|
|
224
|
+
## Fallback: MCP tools
|
|
225
|
+
|
|
226
|
+
If this agent also happens to have Empirical's MCP server connected (unusual for this install
|
|
227
|
+
mode, but possible if the user added it manually), the same operations are available as
|
|
228
|
+
`query_memories`, `record_graph_memory`, `add_note_by_query`, `update_memory_by_query`,
|
|
229
|
+
`delete_memory_by_query`, `get_empirical_policy`, `get_memory_neighbors`, and
|
|
230
|
+
`update_memory_relationships`. Use them only if the CLI is genuinely unavailable in this
|
|
231
|
+
environment — the CLI is the primary path for this install.
|