@bli-cockpit/cli 0.2.200 → 0.2.201

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.
@@ -35,6 +35,7 @@ import { parseMemoryRulesArgs } from "./memory-rules.js";
35
35
  import { optionalNonEmpty, optionalUrl, parseNamedArgs, workRootFlagValue, } from "./local-arg-values.js";
36
36
  export const MEMORY_STORE_ACTIONS = new Set([
37
37
  "rules",
38
+ "knowledge",
38
39
  "search",
39
40
  "save",
40
41
  "update",
@@ -88,8 +89,8 @@ const VALUE_FLAGS = [
88
89
  "--source",
89
90
  ];
90
91
  export function parseMemoryStoreArgs(action, args) {
91
- if (action === "rules")
92
- return parseMemoryRulesArgs(args);
92
+ if (action === "rules" || action === "knowledge")
93
+ return parseMemoryRulesArgs(args, action);
93
94
  const values = parseNamedArgs(args, { allowedFlags: ALLOWED_FLAGS, valueFlags: VALUE_FLAGS });
94
95
  const rest = values.positionals.slice(1);
95
96
  const containers = values.flagValues.get("--container") ?? [];
@@ -1,15 +1,15 @@
1
1
  import { askAgentDoor, emitAgentDoor, failAgentDoor } from "./agent-door.js";
2
2
  import { writeLine } from "./cli-io.js";
3
3
  import { optionalNonEmpty, optionalUrl, parseNamedArgs } from "./local-arg-values.js";
4
- export function parseMemoryRulesArgs(args) {
5
- const values = parseNamedArgs(args, { allowedFlags: ["--person", "--project", "--limit", "--json", "--home", "--dashboard-url"],
4
+ export function parseMemoryRulesArgs(args, action = "rules") {
5
+ const values = parseNamedArgs(args, { allowedFlags: ["--person", "--project", "--limit", "--json", "--by-project", "--home", "--dashboard-url"],
6
6
  valueFlags: ["--person", "--project", "--limit", "--home", "--dashboard-url"] });
7
7
  if (values.positionals.slice(1).length)
8
- throw new Error("memory rules takes no positionals; use --person and --project.");
8
+ throw new Error(`memory ${action} takes no positionals; use --person and --project.`);
9
9
  const raw = values.flags.get("--limit");
10
10
  if (raw !== undefined && (!/^\d+$/.test(raw) || Number(raw) < 1 || Number(raw) > 1000))
11
11
  throw new Error("--limit must be between 1 and 1000.");
12
- return { kind: "memory-store", action: "rules", containerTags: [],
12
+ return { kind: "memory-store", action, byProject: values.booleans.has("--by-project"), containerTags: [],
13
13
  person: optionalNonEmpty(values.flags.get("--person")), project: optionalNonEmpty(values.flags.get("--project")),
14
14
  limit: raw === undefined ? undefined : Number(raw), json: values.booleans.has("--json"),
15
15
  homeDir: optionalNonEmpty(values.flags.get("--home")), dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")) };
@@ -22,21 +22,32 @@ export async function runMemoryRules(command, door) {
22
22
  params.set("project", command.project);
23
23
  if (command.limit !== undefined)
24
24
  params.set("limit", String(command.limit));
25
- const answer = await askAgentDoor(door, { path: `/api/memory/rules${params.size ? `?${params}` : ""}`,
26
- method: "GET", label: "memory rules", timeoutMs: 60_000 });
25
+ const answer = await askAgentDoor(door, { path: `/api/memory/${command.action}${params.size ? `?${params}` : ""}`,
26
+ method: "GET", label: `memory ${command.action}`, timeoutMs: 60_000 });
27
27
  if (!answer.ok)
28
28
  return failAgentDoor(door, "[memory cli]", answer.reason, answer.detail);
29
29
  const body = answer.body;
30
- writeLine(door.io.stderr, `[memory cli] rules ${JSON.stringify({ reason: body.capped ? "capped" : "exhausted", returned: body.returned, groups: body.groups.length })}`);
30
+ writeLine(door.io.stderr, `[memory cli] ${command.action} ${JSON.stringify({ reason: body.capped ? "capped" : "exhausted", returned: body.returned, groups: body.projectGroups?.length ?? body.groups?.length ?? 0 })}`);
31
31
  if (door.json)
32
32
  return emitAgentDoor(door, answer.body);
33
- for (const group of body.groups) {
34
- writeLine(door.io.stdout, group.owner);
35
- for (const rule of group.rules)
36
- writeLine(door.io.stdout, ` [${rule.created_at.slice(0, 10)}] ${rule.project ? `[${rule.project}] ` : ""}${rule.text}${group.owner === "unattributed" ? ` (space: ${rule.container})` : ""}`);
33
+ if (command.byProject || command.action === "knowledge") {
34
+ for (const group of body.projectGroups ?? []) {
35
+ writeLine(door.io.stdout, `${group.project} (${group.count}) : ${group.headline.split("\n")[0]}`);
36
+ for (const topic of group.topics) {
37
+ writeLine(door.io.stdout, ` ${topic.title}`);
38
+ for (const memory of topic.memories)
39
+ writeLine(door.io.stdout, ` ${memory.text}${memory.repetition > 1 ? ` (said ${memory.repetition} times)` : ""}${memory.importance !== null ? ` [importance ${memory.importance}/100]` : ""}`);
40
+ }
41
+ }
37
42
  }
43
+ else
44
+ for (const group of body.groups) {
45
+ writeLine(door.io.stdout, group.owner);
46
+ for (const rule of group.rules)
47
+ writeLine(door.io.stdout, ` [${rule.created_at.slice(0, 10)}] ${rule.project ? `[${rule.project}] ` : ""}${rule.text}${group.owner === "unattributed" ? ` (space: ${rule.container})` : ""}`);
48
+ }
38
49
  if (!body.returned)
39
- writeLine(door.io.stdout, "No ground rules matched.");
50
+ writeLine(door.io.stdout, `No ${command.action === "knowledge" ? "project knowledge" : "ground rules"} matched.`);
40
51
  if (body.capped)
41
52
  writeLine(door.io.stdout, "Result capped. Narrow by person or project, or increase --limit (max 1000).");
42
53
  return 0;
@@ -65,6 +65,7 @@ const FORGET_MAX_CHARS = 10_000;
65
65
  export async function runMemoryStore(command, io) {
66
66
  const door = await openAgentDoor("memory", command, io);
67
67
  switch (command.action) {
68
+ case "knowledge":
68
69
  case "rules":
69
70
  return runMemoryRules(command, door);
70
71
  case "search":
@@ -26,7 +26,7 @@ export function runMemoryVerbList(io, json) {
26
26
  ok: true,
27
27
  noun: "memory",
28
28
  machine_verbs: ["install", "status"],
29
- store_verbs: ["search", "save", "update", "forget", "private", "public", "profile", "consolidation", "requeue"],
29
+ store_verbs: ["rules", "knowledge", "search", "save", "update", "forget", "private", "public", "profile", "consolidation", "requeue"],
30
30
  log_verbs: ["log"],
31
31
  }));
32
32
  return 0;
@@ -44,7 +44,8 @@ export function runMemoryVerbList(io, json) {
44
44
  " you can forget or update only your own memories (a super admin, any)",
45
45
  " cockpit memory private <id> [--json] only you and super admins can read this memory",
46
46
  " cockpit memory public <id> [--json] every member can read it again (how every memory starts)",
47
- " cockpit memory rules [--person <name>] [--project <name>] [--limit <n>] [--json]",
47
+ " cockpit memory rules [--person <name>] [--project <name-or-slug>] [--by-project] [--limit <n>] [--json]",
48
+ " cockpit memory knowledge [--person <name>] [--project <name-or-slug>] [--by-project] [--limit <n>] [--json]",
48
49
  " cockpit memory profile [--container <tag>] [--json]",
49
50
  " the compiled one-page briefing every session opens with; a read, never a compile",
50
51
  " cockpit memory consolidation [--container <tag>] [--json]",
@@ -21,7 +21,7 @@ export async function runCockpitCli(argv, io) {
21
21
  }
22
22
 
23
23
  if (command === "--version" || command === "-V" || command === "version") {
24
- writeLine(io?.stdout ?? process.stdout, "0.2.200");
24
+ writeLine(io?.stdout ?? process.stdout, "0.2.201");
25
25
  return 0;
26
26
  }
27
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/cli",
3
- "version": "0.2.200",
3
+ "version": "0.2.201",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@bli-cockpit/memory-mcp": "0.1.60",
31
- "@bli-cockpit/mcp": "0.1.112",
31
+ "@bli-cockpit/mcp": "0.1.113",
32
32
  "@bli-cockpit/telemetry-core": "0.1.69"
33
33
  },
34
34
  "repository": {