@bli-cockpit/cli 0.2.85 → 0.2.87
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/dist/commands/local-args-collector-status.js +18 -2
- package/dist/commands/local-help-commands.js +6 -1
- package/dist/commands/local-help.js +1 -1
- package/dist/commands/local.js +3 -0
- package/dist/commands/memory-log.js +28 -0
- package/dist/commands/ops.js +9 -4
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/sync.js +3 -0
- package/package.json +4 -4
|
@@ -170,9 +170,25 @@ export function parseAgentRulesArgs(args) {
|
|
|
170
170
|
*/
|
|
171
171
|
export function parseMemoryArgs(args) {
|
|
172
172
|
const values = parseNamedArgs(args, {
|
|
173
|
-
allowedFlags: ["--home", "--dashboard-url", "--dry-run", "--json"],
|
|
174
|
-
valueFlags: ["--home", "--dashboard-url"],
|
|
173
|
+
allowedFlags: ["--home", "--dashboard-url", "--dry-run", "--json", "--store", "--reason-stdin"],
|
|
174
|
+
valueFlags: ["--home", "--dashboard-url", "--store"],
|
|
175
175
|
});
|
|
176
|
+
if (values.positionals[0] === "log") {
|
|
177
|
+
const [, verdict, reason = ""] = values.positionals;
|
|
178
|
+
const store = values.flags.get("--store");
|
|
179
|
+
const reasonStdin = values.booleans.has("--reason-stdin");
|
|
180
|
+
if (values.booleans.has("--dry-run") || values.positionals.length > 3 || (reasonStdin && reason))
|
|
181
|
+
throw new Error("memory log takes one reason or --reason-stdin, never --dry-run");
|
|
182
|
+
if (verdict !== "win" && verdict !== "loss" && verdict !== "noise")
|
|
183
|
+
throw new Error("memory log needs win|loss|noise");
|
|
184
|
+
if (store !== "bli" && store !== "supermemory" && store !== "both")
|
|
185
|
+
throw new Error("memory log needs --store bli|supermemory|both");
|
|
186
|
+
if (!reasonStdin && !reason.trim())
|
|
187
|
+
throw new Error("memory log needs a reason");
|
|
188
|
+
return { kind: "memory-log", verdict, store, reason, reasonStdin, homeDir: optionalNonEmpty(values.flags.get("--home")), dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")), json: values.booleans.has("--json") };
|
|
189
|
+
}
|
|
190
|
+
if (values.flags.has("--store") || values.booleans.has("--reason-stdin"))
|
|
191
|
+
throw new Error("--store and --reason-stdin require memory log");
|
|
176
192
|
if (values.positionals.length > 1) {
|
|
177
193
|
throw new Error("memory accepts at most one action (install|status).");
|
|
178
194
|
}
|
|
@@ -526,7 +526,7 @@ export function localSubcommandHelp(command) {
|
|
|
526
526
|
[
|
|
527
527
|
"memory",
|
|
528
528
|
[
|
|
529
|
-
"Usage: cockpit memory [install|status] [--dashboard-url <url>] [--dry-run] [--json]",
|
|
529
|
+
"Usage: cockpit memory [install|status|log <win|loss|noise> --store <bli|supermemory|both> \"<reason>\"] [--dashboard-url <url>] [--dry-run] [--json]",
|
|
530
530
|
"",
|
|
531
531
|
"Registers BLI Memory on this machine: the `bli-memory` MCP server plus the",
|
|
532
532
|
"recall/save hooks, for Claude Code (~/.claude.json, ~/.claude/settings.json)",
|
|
@@ -535,6 +535,11 @@ export function localSubcommandHelp(command) {
|
|
|
535
535
|
"entries, and reads the stored config back before reporting success.",
|
|
536
536
|
"`do-everything` runs it, and the sync tick re-runs it at most once a day.",
|
|
537
537
|
"Action defaults to `install`. See docs/runbooks/bli-memory-install.md.",
|
|
538
|
+
"log appends an opinion to ~/.codex/AGENT-EXPERIENCE.md and posts it to Tower.",
|
|
539
|
+
"Use --reason-stdin instead of a quoted reason; --json reports shipped status.",
|
|
540
|
+
"Reasons: one line, max 500 characters; no prompts, memory bodies or secrets.",
|
|
541
|
+
"Markers: [bli] = BLI Memory, ◪ = Supermemory, [bli]+◪ = both.",
|
|
542
|
+
"Offline entries stay queued; the next collector sync retries with the same ID.",
|
|
538
543
|
],
|
|
539
544
|
],
|
|
540
545
|
[
|
|
@@ -86,7 +86,7 @@ export function localCommandHelp(command) {
|
|
|
86
86
|
" cockpit serve [--port <port>] [--workspace <path>]",
|
|
87
87
|
" cockpit autostart [install|uninstall|status] [--workspace <path>] [--dashboard-url <url>] [--interval-seconds <n>] [--json]",
|
|
88
88
|
" cockpit agent-rules [install|uninstall|status] [--host codex|claude|all] [--workspace <path>] [--json]",
|
|
89
|
-
" cockpit memory [install|status] [--dashboard-url <url>] [--dry-run] [--json]",
|
|
89
|
+
" cockpit memory [install|status|log <win|loss|noise> --store <bli|supermemory|both> \"<reason>\"] [--dashboard-url <url>] [--dry-run] [--json]",
|
|
90
90
|
" cockpit clean [--dry-run] [--all-committed] [--reconcile] [--dashboard-url <url>] [--json]",
|
|
91
91
|
" cockpit docs [list|tree|read <id|slug>|create --title <t>|update <id>] [--parent <id>|root|--clear-parent] [--query <text>] [--limit <n>] [--visibility org|private] [--file <path>|--body-stdin] [--allow-empty] [--dashboard-url <url>] [--json]",
|
|
92
92
|
" cockpit msg [channels|create <name>|dm <email>|read <channel>|send <channel>|thread <id> --channel <channel>] [--private] [--members a@x,b@y] [--description <text>] [--thread <id>] [--limit <n>] [--dashboard-url <url>] [--json]",
|
package/dist/commands/local.js
CHANGED
|
@@ -30,6 +30,7 @@ import { runNotes } from "./notes.js";
|
|
|
30
30
|
import { runServe } from "./serve.js";
|
|
31
31
|
import { runAutostart } from "./autostart-command.js";
|
|
32
32
|
import { runAgentRules } from "./agent-rules-command.js";
|
|
33
|
+
import { runMemoryLog } from "./memory-log.js";
|
|
33
34
|
import { runMemoryInstall } from "./memory-install.js";
|
|
34
35
|
import { runClean } from "./clean.js";
|
|
35
36
|
import { runDocs } from "./docs.js";
|
|
@@ -141,6 +142,8 @@ export async function runLocalCockpitCli(argv, io = defaultIo()) {
|
|
|
141
142
|
return await runAutostart(command, io);
|
|
142
143
|
case "agent-rules":
|
|
143
144
|
return await runAgentRules(command, io);
|
|
145
|
+
case "memory-log":
|
|
146
|
+
return await runMemoryLog(command, io);
|
|
144
147
|
case "memory":
|
|
145
148
|
return await runMemoryInstall(command, io);
|
|
146
149
|
case "clean":
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { appendExperience, drainExperiences, shipExperience, validateExperience } from "@bli-cockpit/telemetry-core/memory-experience";
|
|
3
|
+
import { readPipedText, writeLine } from "./cli-io.js";
|
|
4
|
+
import { callTower, openTower } from "./tower-command.js";
|
|
5
|
+
function sender(command, io) {
|
|
6
|
+
return async (entry) => {
|
|
7
|
+
const tower = await openTower("memory log", command, io);
|
|
8
|
+
const result = await callTower(tower, { path: "/api/memory/experience", method: "POST", body: entry, label: "memory experience", timeoutMs: 5000 });
|
|
9
|
+
return result.ok ? { ok: result.body?.ok === true, reason: "experience_not_acknowledged" } : result;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export async function runMemoryLog(command, io) {
|
|
13
|
+
const reason = command.reasonStdin ? (await readPipedText(io.stdin, { maxChars: 1002 })).trim() : command.reason;
|
|
14
|
+
validateExperience(command.store, command.verdict, reason);
|
|
15
|
+
const entry = await appendExperience({ store: command.store, verdict: command.verdict, reason }, {
|
|
16
|
+
homeDir: command.homeDir, agent: "cockpit", project: path.basename(process.cwd()),
|
|
17
|
+
});
|
|
18
|
+
const delivery = await shipExperience(entry, sender(command, io), command.homeDir);
|
|
19
|
+
const receipt = { ok: true, id: entry.id, local: true, ...delivery };
|
|
20
|
+
writeLine(io.stderr, `[memory experience] recorded ${JSON.stringify(receipt)}`);
|
|
21
|
+
writeLine(io.stdout, command.json ? JSON.stringify(receipt) : `Experience appended; shipped: ${delivery.shipped} (${delivery.reason}).`);
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
export async function runMemoryExperienceAfterSync(command, io) {
|
|
25
|
+
const result = await drainExperiences(sender(command, io), command.homeDir);
|
|
26
|
+
if (result.reason !== "empty")
|
|
27
|
+
writeLine(io.stderr, `[memory experience] sync ${JSON.stringify(result)}`);
|
|
28
|
+
}
|
package/dist/commands/ops.js
CHANGED
|
@@ -88,7 +88,7 @@ async function runOpsStatus(command, io, tower) {
|
|
|
88
88
|
// BLI-3762: a job that ran and wrote less than it owed is not healthy.
|
|
89
89
|
row.verdict === "degraded");
|
|
90
90
|
if (command.json) {
|
|
91
|
-
writeLine(io.stdout, JSON.stringify(memory ? { ...payload, memory: memory.section, hooks: memory.hooks } : payload));
|
|
91
|
+
writeLine(io.stdout, JSON.stringify(memory ? { ...payload, memory: memory.section, hooks: memory.hooks, experience: memory.experience } : payload));
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
94
|
const styled = colorEnabled(io);
|
|
@@ -111,6 +111,11 @@ async function runOpsStatus(command, io, tower) {
|
|
|
111
111
|
writeLine(io.stdout, line);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
+
if (memory?.experience) {
|
|
115
|
+
writeLine(io.stdout, `\nEXPERIENCE ${memory.experience.summary}`);
|
|
116
|
+
for (const line of memory.experience.lines)
|
|
117
|
+
writeLine(io.stdout, ` ${line}`);
|
|
118
|
+
}
|
|
114
119
|
if (memory && !memory.section) {
|
|
115
120
|
// Never a silent gap where a section was asked for: the reason the gauge
|
|
116
121
|
// could not be read is printed where the gauge would have been.
|
|
@@ -177,15 +182,15 @@ async function readMemoryUsage(command, io, tower) {
|
|
|
177
182
|
reason: result.reason,
|
|
178
183
|
http_status: result.httpStatus ?? null,
|
|
179
184
|
})}`);
|
|
180
|
-
return { section: null, hooks: null, reason: result.reason };
|
|
185
|
+
return { section: null, hooks: null, experience: null, reason: result.reason };
|
|
181
186
|
}
|
|
182
187
|
const body = asRecord(result.body);
|
|
183
188
|
// BLI-3788: the hook counts ride the same answer, and their absence is a
|
|
184
189
|
// fact about the SERVER's version rather than about this fleet — an older
|
|
185
190
|
// dashboard sends no `hooks` key, and printing nothing is right there.
|
|
186
191
|
if (!body.memory)
|
|
187
|
-
return { section: null, hooks: body.hooks ?? null, reason: "memory_section_absent" };
|
|
188
|
-
return { section: body.memory, hooks: body.hooks ?? null, reason: "ok" };
|
|
192
|
+
return { section: null, hooks: body.hooks ?? null, experience: body.experience ?? null, reason: "memory_section_absent" };
|
|
193
|
+
return { section: body.memory, hooks: body.hooks ?? null, experience: body.experience ?? null, reason: "ok" };
|
|
189
194
|
}
|
|
190
195
|
async function runOpsRecompile(command, io, tower) {
|
|
191
196
|
const person = command.person ?? "";
|
|
@@ -15,7 +15,7 @@ export async function runCockpitCli(argv, io) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if (command === "--version" || command === "-V" || command === "version") {
|
|
18
|
-
writeLine(io?.stdout ?? process.stdout, "0.2.
|
|
18
|
+
writeLine(io?.stdout ?? process.stdout, "0.2.87");
|
|
19
19
|
return 0;
|
|
20
20
|
}
|
|
21
21
|
|
package/dist/commands/sync.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { runMemoryExperienceAfterSync } from "./memory-log.js";
|
|
1
2
|
import { writeLine } from "./cli-io.js";
|
|
2
3
|
import { attributedSyncRunStatus, cursorStatusLine, displayTicketId, rawEvidenceSyncLine, shortSha, worktreeSyncRow, writeAgentSessionSummary, } from "./collection-report.js";
|
|
3
4
|
import { collectionRootConsentAliases } from "./collection-roots.js";
|
|
@@ -52,6 +53,7 @@ export async function runSync(command, io) {
|
|
|
52
53
|
// BLI-3580: BLI Memory's registration converges the same way — after
|
|
53
54
|
// collection, at most once a day, its own receipt either way.
|
|
54
55
|
await runMemoryInstallAfterSync(command, io, dashboardUrl);
|
|
56
|
+
await runMemoryExperienceAfterSync({ ...command, dashboardUrl }, io);
|
|
55
57
|
// BLI-3619: and the disk stops growing without bound — same daily cadence,
|
|
56
58
|
// same rule that a follow-up never blocks or fails collection.
|
|
57
59
|
await runStagingPruneAfterSync(command, io, dashboardUrl);
|
|
@@ -86,6 +88,7 @@ export async function runSync(command, io) {
|
|
|
86
88
|
// BLI-3580: BLI Memory's registration converges the same way — after
|
|
87
89
|
// collection, at most once a day, its own receipt either way.
|
|
88
90
|
await runMemoryInstallAfterSync(command, io, dashboardUrl);
|
|
91
|
+
await runMemoryExperienceAfterSync({ ...command, dashboardUrl }, io);
|
|
89
92
|
throw error;
|
|
90
93
|
}
|
|
91
94
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.87",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"test": "node dist/cli.js --help && node ../../scripts/assert-public-cli-routing.mjs && node ../../scripts/assert-public-cli-verb-help.mjs && node ../../scripts/assert-public-cli-runtime-files.mjs && node ../../scripts/assert-public-cli-no-fleet-posts.mjs && node ../../scripts/assert-public-package-pack.mjs --workspace=@bli-cockpit/cli"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@bli-cockpit/memory-mcp": "0.1.
|
|
31
|
-
"@bli-cockpit/mcp": "0.1.
|
|
32
|
-
"@bli-cockpit/telemetry-core": "0.1.
|
|
30
|
+
"@bli-cockpit/memory-mcp": "0.1.19",
|
|
31
|
+
"@bli-cockpit/mcp": "0.1.20",
|
|
32
|
+
"@bli-cockpit/telemetry-core": "0.1.36"
|
|
33
33
|
}
|
|
34
34
|
}
|