@rubytech/create-realagent 1.0.816 → 1.0.818

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-search/src/__tests__/fulltext-coverage.test.ts +1 -1
  3. package/payload/platform/lib/graph-write/dist/index.d.ts +5 -0
  4. package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
  5. package/payload/platform/lib/graph-write/dist/index.js +14 -0
  6. package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
  7. package/payload/platform/lib/graph-write/src/index.ts +25 -0
  8. package/payload/platform/neo4j/edge-annotations.json +0 -8
  9. package/payload/platform/neo4j/migrations/004-prune-alien-accounts.ts +3 -4
  10. package/payload/platform/neo4j/migrations/005-removed-review-feature.ts +102 -0
  11. package/payload/platform/neo4j/schema.cypher +1 -22
  12. package/payload/platform/plugins/admin/PLUGIN.md +1 -8
  13. package/payload/platform/plugins/admin/mcp/dist/index.js +6 -44
  14. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  15. package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +2 -2
  16. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts.map +1 -1
  17. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +2 -3
  18. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
  19. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js +1 -1
  20. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js.map +1 -1
  21. package/payload/platform/plugins/docs/references/cloudflare.md +1 -3
  22. package/payload/platform/plugins/docs/references/memory-guide.md +1 -1
  23. package/payload/platform/plugins/docs/references/troubleshooting.md +8 -12
  24. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js +1 -1
  25. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js.map +1 -1
  26. package/payload/platform/scripts/logs-read.sh +8 -38
  27. package/payload/server/chunk-AJLGI7Y3.js +10067 -0
  28. package/payload/server/chunk-ON3LBL2Y.js +1114 -0
  29. package/payload/server/chunk-P3HTEK33.js +10074 -0
  30. package/payload/server/chunk-PXQA2MA3.js +2518 -0
  31. package/payload/server/client-pool-GBY5I2KQ.js +31 -0
  32. package/payload/server/maxy-edge.js +3 -3
  33. package/payload/server/neo4j-migrations-STCKDWAL.js +364 -0
  34. package/payload/server/public/assets/{admin-Cxtmv0wo.js → admin-CdVYoqKD.js} +20 -20
  35. package/payload/server/public/assets/{graph-C4-jEPDE.js → graph-DeH6ulGh.js} +1 -1
  36. package/payload/server/public/assets/{page-zuI00fuC.js → page-WIAWD2Oi.js} +1 -1
  37. package/payload/server/public/graph.html +2 -2
  38. package/payload/server/public/index.html +2 -2
  39. package/payload/server/server.js +326 -2236
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent",
3
- "version": "1.0.816",
3
+ "version": "1.0.818",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent": "./dist/index.js"
@@ -61,7 +61,7 @@ const EXCLUDED_FROM_INDEX = new Set(["Trashed", "GraphPreference"]);
61
61
  * writer means extending this list AND the schema's `ON EACH [...]` clause.
62
62
  * Discovered via codebase sweep during Task 748 across `memory-write`,
63
63
  * `memory-archive-write`, `memory-ingest`, `email-store`, `neo4j-store`,
64
- * `workflow-create`, `tool-call-writer`, `review-detector/writer`.
64
+ * `workflow-create`, `tool-call-writer`.
65
65
  */
66
66
  const CANONICAL_TEXT_PROPERTIES = [
67
67
  // Generic
@@ -14,6 +14,11 @@ export * from "./audit.js";
14
14
  * hourly [graph-health] signal):
15
15
  * - zero relationships → `[graph-write] reject reason=zero-relationships`
16
16
  * - unresolved target id → `[graph-write] reject reason=unresolved-target`
17
+ * - removed-feature write → `[graph-write] reject reason=removed-feature`
18
+ * (Task 884 — `:ReviewAlert` and `:Event {actionTool:"review-digest-compose"}`
19
+ * are deleted features; the gate catches doctrine-compliant writers
20
+ * re-introducing them. The vitest tombstone grep is the primary fence
21
+ * for raw `session.run("MERGE …")` callers that bypass this primitive.)
17
22
  *
18
23
  * The `createdBy.agent` field is advisory, not authoritative — it is sourced
19
24
  * from the MCP server's AGENT_SLUG env var, which is set by the trusted
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4EAA4E;IAC5E,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,eAAe,CAAC,CA8G1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4EAA4E;IAC5E,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,eAAe,CAAC,CAkI1B"}
@@ -40,6 +40,20 @@ async function writeNodeWithEdges(params) {
40
40
  const { session, labels, props, relationships, createdBy } = params;
41
41
  const agentLabel = createdBy.agent ?? createdBy.source ?? "unknown";
42
42
  const labelCsv = labels.join(",");
43
+ // Task 884: review-detector / review-digest feature is removed entirely.
44
+ // Reject any re-introduction via the doctrine surface. The actionTool check
45
+ // is property-keyed (not label-keyed) so a future scheduled-Event writer
46
+ // re-introducing the daily digest by tool name is caught here even though
47
+ // `:Event` is otherwise a valid label. Fires before the zero-relationships
48
+ // check because the dead-feature rejection is structurally more fundamental.
49
+ const reviewDigestActionTool = typeof props.actionTool === "string" && props.actionTool === "review-digest-compose";
50
+ if (labels.includes("ReviewAlert") || reviewDigestActionTool) {
51
+ const actionToolField = reviewDigestActionTool
52
+ ? "review-digest-compose"
53
+ : "n/a";
54
+ process.stderr.write(`[graph-write] reject reason=removed-feature labels=${labelCsv} actionTool=${actionToolField} agent=${agentLabel}\n`);
55
+ throw new Error("Write doctrine violated: review-detector feature removed (Task 884) — `:ReviewAlert` and `:Event {actionTool:'review-digest-compose'}` writes are not allowed.");
56
+ }
43
57
  if (!relationships || relationships.length < 1) {
44
58
  process.stderr.write(`[graph-write] reject reason=zero-relationships labels=${labelCsv} agent=${agentLabel}\n`);
45
59
  throw new Error("Write doctrine violated: a node must be created with at least one relationship. See .docs/neo4j.md (Write doctrine).");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,11 @@ export * from "./audit.js";
18
18
  * hourly [graph-health] signal):
19
19
  * - zero relationships → `[graph-write] reject reason=zero-relationships`
20
20
  * - unresolved target id → `[graph-write] reject reason=unresolved-target`
21
+ * - removed-feature write → `[graph-write] reject reason=removed-feature`
22
+ * (Task 884 — `:ReviewAlert` and `:Event {actionTool:"review-digest-compose"}`
23
+ * are deleted features; the gate catches doctrine-compliant writers
24
+ * re-introducing them. The vitest tombstone grep is the primary fence
25
+ * for raw `session.run("MERGE …")` callers that bypass this primitive.)
21
26
  *
22
27
  * The `createdBy.agent` field is advisory, not authoritative — it is sourced
23
28
  * from the MCP server's AGENT_SLUG env var, which is set by the trusted
@@ -88,6 +93,26 @@ export async function writeNodeWithEdges(
88
93
  const agentLabel = createdBy.agent ?? createdBy.source ?? "unknown";
89
94
  const labelCsv = labels.join(",");
90
95
 
96
+ // Task 884: review-detector / review-digest feature is removed entirely.
97
+ // Reject any re-introduction via the doctrine surface. The actionTool check
98
+ // is property-keyed (not label-keyed) so a future scheduled-Event writer
99
+ // re-introducing the daily digest by tool name is caught here even though
100
+ // `:Event` is otherwise a valid label. Fires before the zero-relationships
101
+ // check because the dead-feature rejection is structurally more fundamental.
102
+ const reviewDigestActionTool =
103
+ typeof props.actionTool === "string" && props.actionTool === "review-digest-compose";
104
+ if (labels.includes("ReviewAlert") || reviewDigestActionTool) {
105
+ const actionToolField = reviewDigestActionTool
106
+ ? "review-digest-compose"
107
+ : "n/a";
108
+ process.stderr.write(
109
+ `[graph-write] reject reason=removed-feature labels=${labelCsv} actionTool=${actionToolField} agent=${agentLabel}\n`
110
+ );
111
+ throw new Error(
112
+ "Write doctrine violated: review-detector feature removed (Task 884) — `:ReviewAlert` and `:Event {actionTool:'review-digest-compose'}` writes are not allowed."
113
+ );
114
+ }
115
+
91
116
  if (!relationships || relationships.length < 1) {
92
117
  process.stderr.write(
93
118
  `[graph-write] reject reason=zero-relationships labels=${labelCsv} agent=${agentLabel}\n`
@@ -96,14 +96,6 @@
96
96
  "direction": "(Email)-[:RECEIVED_BY]->(Person)",
97
97
  "note": "Email recipient."
98
98
  },
99
- "RAISED_BY": {
100
- "direction": "(ReviewAlert)-[:RAISED_BY]->(*)",
101
- "note": "Alert provenance."
102
- },
103
- "AFFECTS": {
104
- "direction": "(ReviewAlert)-[:AFFECTS]->(*)",
105
- "note": "Alert impact surface."
106
- },
107
99
  "BLOCKS": {
108
100
  "direction": "(Task)-[:BLOCKS]->(Task)",
109
101
  "note": "Task dependency."
@@ -5,10 +5,9 @@
5
5
  * `${DATA_ROOT}/accounts/<uuid>/account.json`. Idempotent — silent when
6
6
  * the graph is already clean.
7
7
  *
8
- * Why a backstop, not a writer fix: the leaked nodes were written by the
9
- * `review-digest-compose` writer, which has since been removed in favour
10
- * of a coming gbrain rewrite. With no live writer to fix, this is the
11
- * surface that catches future writer drift before the next gbrain ships.
8
+ * Why a backstop, not a writer fix: the leaked nodes were written by a
9
+ * since-removed writer. With no live writer to fix, this is the surface
10
+ * that catches future writer drift.
12
11
  *
13
12
  * Hard guard: refuses to run when the on-disk account set is empty
14
13
  * (corrupt-install scenario). Refusing to wipe the graph is louder than
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Migration 005 — Remove review-detector / review-digest feature artefacts (Task 884).
3
+ *
4
+ * The review-detector subsystem was wired into boot, MERGEd a daily `:Event`
5
+ * with `actionTool="review-digest-compose"` on every start, and aggregated
6
+ * `:ReviewAlert` nodes via rule matches. The feature is deleted entirely;
7
+ * this migration is the boot-sweep that removes the residue from existing
8
+ * installs. Idempotent — once the graph is clean, both queries DETACH DELETE
9
+ * zero rows and the log line records `events=0 alerts=0`.
10
+ *
11
+ * Filesystem artefacts (`review.log`, `review-rules.json`, `review-state.json`,
12
+ * `review-pending-alerts.jsonl`) are also removed best-effort — ENOENT is the
13
+ * idempotent no-op; any other errno is logged and ignored so a sticky permission
14
+ * problem does not block boot.
15
+ *
16
+ * Same structural-type pattern as 004-prune-alien-accounts.ts: the runner sits
17
+ * outside `platform/ui/` so depending on the workspace dedupe state the
18
+ * `neo4j-driver` import resolves to a different node_modules copy, and TS
19
+ * treats two same-shape types from different paths as nominally distinct.
20
+ */
21
+
22
+ import { resolve } from "node:path";
23
+ import { unlinkSync } from "node:fs";
24
+ import { homedir } from "node:os";
25
+ import { basename, dirname } from "node:path";
26
+
27
+ type Neo4jDriverLike = {
28
+ session(): {
29
+ run(
30
+ cypher: string,
31
+ params?: Record<string, unknown>,
32
+ ): Promise<{ records: Array<{ get(key: string): unknown }> }>;
33
+ close(): Promise<void>;
34
+ };
35
+ };
36
+
37
+ export async function removeReviewFeature(
38
+ driver: Neo4jDriverLike,
39
+ platformRoot: string,
40
+ ): Promise<void> {
41
+ const session = driver.session();
42
+ let eventsDeleted = 0;
43
+ let alertsDeleted = 0;
44
+
45
+ try {
46
+ const eventResult = await session.run(
47
+ `MATCH (e:Event)
48
+ WHERE e.actionTool = "review-digest-compose"
49
+ OR e.eventId STARTS WITH "review-digest-"
50
+ DETACH DELETE e
51
+ RETURN count(e) AS deleted`,
52
+ );
53
+ eventsDeleted = toNumber(eventResult.records[0]?.get("deleted"));
54
+
55
+ const alertResult = await session.run(
56
+ `MATCH (a:ReviewAlert)
57
+ DETACH DELETE a
58
+ RETURN count(a) AS deleted`,
59
+ );
60
+ alertsDeleted = toNumber(alertResult.records[0]?.get("deleted"));
61
+ } finally {
62
+ await session.close();
63
+ }
64
+
65
+ // Best-effort filesystem cleanup. The configDir convention is
66
+ // `~/.<installDirName>` where installDir = dirname(platformRoot)
67
+ // (e.g. `~/maxy/platform` → `~/.maxy`).
68
+ const installDirName = basename(dirname(platformRoot));
69
+ const configDir = resolve(homedir(), `.${installDirName}`);
70
+ const artefacts = [
71
+ resolve(configDir, "logs", "review.log"),
72
+ resolve(configDir, "review-rules.json"),
73
+ resolve(configDir, "review-state.json"),
74
+ resolve(configDir, "review-pending-alerts.jsonl"),
75
+ ];
76
+ for (const path of artefacts) {
77
+ try {
78
+ unlinkSync(path);
79
+ } catch (err) {
80
+ const code = (err as NodeJS.ErrnoException).code;
81
+ if (code === "ENOENT") continue;
82
+ console.error(
83
+ `[migration] removed-review-feature unlink-skip path=${path} reason=${code ?? "unknown"}`,
84
+ );
85
+ }
86
+ }
87
+
88
+ console.error(
89
+ `[migration] removed-review-feature events=${eventsDeleted} alerts=${alertsDeleted}`,
90
+ );
91
+ }
92
+
93
+ function toNumber(v: unknown): number {
94
+ if (typeof v === "number") return v;
95
+ if (
96
+ v &&
97
+ typeof (v as { toNumber?: () => number }).toNumber === "function"
98
+ ) {
99
+ return (v as { toNumber: () => number }).toNumber();
100
+ }
101
+ return 0;
102
+ }
@@ -284,7 +284,6 @@ OPTIONS {
284
284
  // - Workflows: Workflow, WorkflowStep, WorkflowRun, StepResult
285
285
  // - Onboarding: OnboardingState
286
286
  // - Email: Email, EmailAccount
287
- // - Review signals: ReviewAlert
288
287
  // - CV/career sublabels: Position, Credential
289
288
  // - Public agents: Agent (Task 837 — projection of file-based public agents)
290
289
  //
@@ -314,7 +313,7 @@ FOR (n:LocalBusiness|Service|PriceSpecification|OpeningHoursSpecification|Organi
314
313
  |Conversation|AdminConversation|PublicConversation|Message|UserMessage|AssistantMessage|ToolCall
315
314
  |Task|Project|Event
316
315
  |Workflow|WorkflowStep|WorkflowRun|StepResult
317
- |OnboardingState|Email|EmailAccount|ReviewAlert
316
+ |OnboardingState|Email|EmailAccount
318
317
  |Position|Credential|Agent)
319
318
  ON EACH [n.name, n.firstName, n.lastName, n.givenName, n.familyName,
320
319
  n.title, n.currentTitle, n.summary, n.body, n.content, n.text, n.description, n.headline, n.abstract,
@@ -832,26 +831,6 @@ FOR (au:AdminUser) REQUIRE au.userId IS UNIQUE;
832
831
  CREATE INDEX graph_preference_account_user IF NOT EXISTS
833
832
  FOR (p:GraphPreference) ON (p.accountId, p.userId);
834
833
 
835
- // ----------------------------------------------------------
836
- // ReviewAlert — review-detector rule-match aggregation
837
- //
838
- // One alert per (accountId, ruleId); subsequent rule matches bump
839
- // lastMatchAt and cumulativeMatchCount via ON MATCH. Written by
840
- // platform/ui/app/lib/review-detector/writer.ts, read by the admin
841
- // chat's alert-surfacing tools. Listed in FILTER_EXCLUDED_LABELS
842
- // (graph-labels.ts, Task 626) so it never surfaces as a /graph filter
843
- // row, but registered in GRAPH_LABEL_COLOURS so neighbourhood-mode
844
- // drilldown / search hits can still render it.
845
- //
846
- // Composite MERGE key (accountId, ruleId) — no UNIQUE constraint for
847
- // the same reason as GraphPreference: the composite MERGE is
848
- // idempotent and a composite constraint would add schema surface
849
- // for no behavioural gain.
850
- // ----------------------------------------------------------
851
-
852
- CREATE INDEX review_alert_account_rule IF NOT EXISTS
853
- FOR (a:ReviewAlert) ON (a.accountId, a.ruleId);
854
-
855
834
  // ----------------------------------------------------------
856
835
  // ToolCall — durable audit trail for agent tool invocations
857
836
  //
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: admin
3
- description: "Platform administration plugin. Provides system-status, brand-settings, account-manage, account-update, admin-add, admin-remove, admin-list, admin-update-pin, agent-list, agent-config-read, logs-read, plugin-read, render-component, session-reset, session-resume, file-attach, wifi, review-cadence tools (review-rules-list, review-rules-suppress, review-rules-unsuppress, review-rules-add, review-rules-remove, review-alerts-recent), adherence-read (attention-weighted adherence ledger), and action-approval tools (action-pending, action-approve, action-reject, action-edit) for managing the Maxy platform."
3
+ description: "Platform administration plugin. Provides system-status, brand-settings, account-manage, account-update, admin-add, admin-remove, admin-list, admin-update-pin, agent-list, agent-config-read, logs-read, plugin-read, render-component, session-reset, session-resume, file-attach, wifi, adherence-read (attention-weighted adherence ledger), and action-approval tools (action-pending, action-approve, action-reject, action-edit) for managing the Maxy platform."
4
4
  tools:
5
5
  - system-status
6
6
  - brand-settings
@@ -18,12 +18,6 @@ tools:
18
18
  - session-reset
19
19
  - session-resume
20
20
  - file-attach
21
- - review-rules-list
22
- - review-rules-suppress
23
- - review-rules-unsuppress
24
- - review-rules-add
25
- - review-rules-remove
26
- - review-alerts-recent
27
21
  - adherence-read
28
22
  - action-pending
29
23
  - action-approve
@@ -40,7 +34,6 @@ hidden:
40
34
  - onboarding-step9-mode
41
35
  - qr-generate
42
36
  - wifi
43
- - review-digest-compose
44
37
  always: true
45
38
  embed: false
46
39
  ---
@@ -17,7 +17,6 @@ import { homedir, hostname as osHostname } from "node:os";
17
17
  import QRCode from "qrcode";
18
18
  import { getSession, closeDriver } from "./lib/neo4j.js";
19
19
  import { getOnboardingState, completeOnboardingStep } from "./lib/onboarding.js";
20
- import { registerReviewTools } from "./lib/review-tools.js";
21
20
  const server = new McpServer({
22
21
  name: "admin",
23
22
  version: "0.1.0",
@@ -1179,8 +1178,8 @@ server.tool("agent-list", "List all public (non-admin) agents with their full co
1179
1178
  };
1180
1179
  }
1181
1180
  });
1182
- server.tool("logs-read", "Read recent logs. Task 532: the stream logs (type=agent-stream/error/session/public) are now per-conversation — pass `conversationId` to retrieve a single conversation's log from first [spawn] to final [process-exit]. type=agent-stream: per-conversation tool-use/tool-result archive (every `[tool-use]` and `[tool-result]` pair with full input + output JSON, plus raw Claude stream-json, agent events, and MCP server stderr via tee). USE THIS when investigating what an agent ACTUALLY did with its tools — server.log only carries `[persist] tool-call persisted` markers, not bodies. (`type=system` is a backwards-compatible alias for the same archive.) type=session: SSE events sent to client. type=error: Claude subprocess stderr (raw — NODE_DEBUG HTTP/NET/UNDICI traces land in agent-stream via the stream tee, not here). type=heartbeat: platform event dispatcher (check-due-events cron). type=public: public agent diagnostic log. type=server: platform server log. type=mcp: MCP server stderr (per-plugin raw). type=vnc: VNC browser viewer lifecycle. type=review: log-review detector decisions. sessionKey: grep legacy sessionKey-tagged lines across all logs (useful for pre-Task-532 artefacts). When conversationId is provided, reads the single per-conversation file for the requested type (or dumps all type files for that conversationId if type is omitted).", {
1183
- type: z.enum(["agent-stream", "system", "session", "error", "heartbeat", "public", "server", "mcp", "vnc", "review"]).optional(),
1181
+ server.tool("logs-read", "Read recent logs. Task 532: the stream logs (type=agent-stream/error/session/public) are now per-conversation — pass `conversationId` to retrieve a single conversation's log from first [spawn] to final [process-exit]. type=agent-stream: per-conversation tool-use/tool-result archive (every `[tool-use]` and `[tool-result]` pair with full input + output JSON, plus raw Claude stream-json, agent events, and MCP server stderr via tee). USE THIS when investigating what an agent ACTUALLY did with its tools — server.log only carries `[persist] tool-call persisted` markers, not bodies. (`type=system` is a backwards-compatible alias for the same archive.) type=session: SSE events sent to client. type=error: Claude subprocess stderr (raw — NODE_DEBUG HTTP/NET/UNDICI traces land in agent-stream via the stream tee, not here). type=heartbeat: platform event dispatcher (check-due-events cron). type=public: public agent diagnostic log. type=server: platform server log. type=mcp: MCP server stderr (per-plugin raw). type=vnc: VNC browser viewer lifecycle. sessionKey: grep legacy sessionKey-tagged lines across all logs (useful for pre-Task-532 artefacts). When conversationId is provided, reads the single per-conversation file for the requested type (or dumps all type files for that conversationId if type is omitted).", {
1182
+ type: z.enum(["agent-stream", "system", "session", "error", "heartbeat", "public", "server", "mcp", "vnc"]).optional(),
1184
1183
  lines: z.number().optional(),
1185
1184
  sessionKey: z.string().optional(),
1186
1185
  conversationId: z.string().optional(),
@@ -1223,7 +1222,7 @@ server.tool("logs-read", "Read recent logs. Task 532: the stream logs (type=agen
1223
1222
  const prefix = prefixMap[resolvedType];
1224
1223
  if (!prefix) {
1225
1224
  return {
1226
- content: [{ type: "text", text: `type=${resolvedType} is not per-conversation. Valid per-conversation types: agent-stream, error, session, public. For platform-scoped types (server, vnc, review, heartbeat, mcp) omit conversationId.` }],
1225
+ content: [{ type: "text", text: `type=${resolvedType} is not per-conversation. Valid per-conversation types: agent-stream, error, session, public. For platform-scoped types (server, vnc, heartbeat, mcp) omit conversationId.` }],
1227
1226
  isError: true,
1228
1227
  };
1229
1228
  }
@@ -1276,11 +1275,11 @@ server.tool("logs-read", "Read recent logs. Task 532: the stream logs (type=agen
1276
1275
  };
1277
1276
  // When a type is explicitly provided, search only that type's files.
1278
1277
  // When type is omitted, search all prefix-based log types (excludes heartbeat — no session context).
1279
- // server, vnc, and review are single-file (configDir-scoped), so they have no prefix search;
1278
+ // server and vnc are single-file (configDir-scoped), so they have no prefix search;
1280
1279
  // their matches are produced by dedicated blocks below.
1281
- const searchPrefixes = type && type !== "heartbeat" && type !== "server" && type !== "vnc" && type !== "review" && prefixes[type]
1280
+ const searchPrefixes = type && type !== "heartbeat" && type !== "server" && type !== "vnc" && prefixes[type]
1282
1281
  ? { [type]: prefixes[type] }
1283
- : (type === "server" || type === "vnc" || type === "review") ? {} : prefixes;
1282
+ : (type === "server" || type === "vnc") ? {} : prefixes;
1284
1283
  const allFiles = readdirSync(LOG_DIR).filter(f => f.endsWith(".log"));
1285
1284
  const sections = [];
1286
1285
  // Search account-scoped prefix-based log files
@@ -1341,25 +1340,6 @@ server.tool("logs-read", "Read recent logs. Task 532: the stream logs (type=agen
1341
1340
  }
1342
1341
  }
1343
1342
  }
1344
- // Search review.log (platform-scoped, in configDir) — the
1345
- // proactive log-review detector's self-log (Task 385).
1346
- const includeReview = !type || type === "review";
1347
- if (includeReview) {
1348
- const reviewLog = resolve(CONFIG_DIR, "logs", "review.log");
1349
- if (existsSync(reviewLog)) {
1350
- try {
1351
- const result = execFileSync("grep", ["-F", sessionKey, reviewLog], { timeout: 5000 }).toString().trim();
1352
- if (result) {
1353
- sections.push(`## review.log (review)\n${result}`);
1354
- }
1355
- }
1356
- catch (grepErr) {
1357
- const exitCode = grepErr.status;
1358
- if (exitCode !== 1)
1359
- throw grepErr;
1360
- }
1361
- }
1362
- }
1363
1343
  if (sections.length === 0) {
1364
1344
  return { content: [{ type: "text", text: `No log lines found for session key "${sessionKey}".` }] };
1365
1345
  }
@@ -1401,20 +1381,6 @@ server.tool("logs-read", "Read recent logs. Task 532: the stream logs (type=agen
1401
1381
  }).toString();
1402
1382
  return { content: [{ type: "text", text: `# vnc-boot.log\n\n${result}` }] };
1403
1383
  }
1404
- // Review log is a single platform-scoped file written by the in-process
1405
- // review detector (Task 385). Every scan cycle, rule match, suppression,
1406
- // rate-limit decision, admin-tool rule mutation, and watchdog event is
1407
- // here. Use this to answer "did the detector see X?" questions.
1408
- if (resolvedType === "review") {
1409
- const reviewLogFile = resolve(CONFIG_DIR, "logs", "review.log");
1410
- if (!existsSync(reviewLogFile)) {
1411
- return { content: [{ type: "text", text: `No review log found at ${reviewLogFile} (detector may not have started yet)` }] };
1412
- }
1413
- const result = execFileSync("tail", ["-n", String(lines), reviewLogFile], {
1414
- timeout: 5000,
1415
- }).toString();
1416
- return { content: [{ type: "text", text: `# review.log\n\n${result}` }] };
1417
- }
1418
1384
  // Task 850 — agent-stream and the legacy system alias both map to
1419
1385
  // claude-agent-stream-. The fall-through default also covers them.
1420
1386
  const prefix = resolvedType === "error" ? "claude-agent-stderr-"
@@ -3229,10 +3195,6 @@ server.tool("adherence-read", "Read the attention-weighted adherence ledger for
3229
3195
  };
3230
3196
  }
3231
3197
  });
3232
- // Review cadence tools (Task 385) — list, suppress, add, remove, etc.
3233
- // Registered as the final tool bundle because they depend on CONFIG_DIR
3234
- // and ACCOUNT_ID being resolved above.
3235
- registerReviewTools(server, { configDir: CONFIG_DIR, accountId: ACCOUNT_ID });
3236
3198
  // Cleanup on exit (SIGTERM for systemd service stops on Pi)
3237
3199
  const cleanup = async () => {
3238
3200
  await closeDriver();