@rubytech/create-maxy-code 0.1.230 → 0.1.232

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 (49) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/neo4j/schema.cypher +20 -0
  3. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +39 -1
  4. package/payload/platform/plugins/docs/references/graph.md +12 -0
  5. package/payload/platform/plugins/docs/references/memory-guide.md +26 -0
  6. package/payload/platform/plugins/docs/superpowers/plans/2026-06-01-memory-edge.md +589 -0
  7. package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
  8. package/payload/platform/plugins/memory/PLUGIN.md +7 -1
  9. package/payload/platform/plugins/memory/mcp/dist/index.js +41 -0
  10. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  11. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js +72 -26
  12. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js.map +1 -1
  13. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edge.test.d.ts +2 -0
  14. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edge.test.d.ts.map +1 -0
  15. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edge.test.js +164 -0
  16. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-edge.test.js.map +1 -0
  17. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-timeline-learned-at.test.d.ts +2 -0
  18. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-timeline-learned-at.test.d.ts.map +1 -0
  19. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-timeline-learned-at.test.js +30 -0
  20. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-timeline-learned-at.test.js.map +1 -0
  21. package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts +17 -1
  22. package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts.map +1 -1
  23. package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js +33 -13
  24. package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js.map +1 -1
  25. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edge.d.ts +21 -0
  26. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edge.d.ts.map +1 -0
  27. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edge.js +51 -0
  28. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edge.js.map +1 -0
  29. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  30. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +1 -0
  31. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  32. package/payload/platform/plugins/memory/skills/challenge/SKILL.md +52 -0
  33. package/payload/platform/plugins/memory/skills/connect/SKILL.md +56 -0
  34. package/payload/platform/plugins/memory/skills/emerge/SKILL.md +87 -0
  35. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  36. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  37. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  39. package/payload/platform/services/claude-session-manager/dist/http-server.js +26 -4
  40. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  41. package/payload/platform/templates/specialists/agents/archive-ingest-operator.md +1 -1
  42. package/payload/platform/templates/specialists/agents/database-operator.md +1 -1
  43. package/payload/platform/templates/specialists/agents/librarian.md +1 -1
  44. package/payload/server/{chunk-EXIPYITB.js → chunk-63M3ILJ6.js} +1 -0
  45. package/payload/server/maxy-edge.js +1 -1
  46. package/payload/server/public/assets/admin-DfeXRW1m.js +1 -0
  47. package/payload/server/public/index.html +1 -1
  48. package/payload/server/server.js +1 -1
  49. package/payload/server/public/assets/admin-BKawc0eQ.js +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy-code",
3
- "version": "0.1.230",
3
+ "version": "0.1.232",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy-code": "./dist/index.js"
@@ -1566,6 +1566,13 @@ OPTIONS {
1566
1566
  // mentioned | met | quoted | attended | transacted
1567
1567
  // Extractor refuses on ambiguity rather than collapsing to "other".
1568
1568
  //
1569
+ // `learnedAt` — datetime(), transaction-time: when this event was ingested.
1570
+ // Distinct from `occurredAt` (valid-time: when the fact was true in the world).
1571
+ // Enables bi-temporal queries: "events ingested on date X about something that
1572
+ // happened in 1990". Backfilled from `createdAt` on pre-existing nodes; nodes
1573
+ // without `createdAt` fall back to `datetime()` (safe approximation).
1574
+ // Task 597.
1575
+ //
1569
1576
  // `compiledTruth` source:
1570
1577
  // compiledTruthSource = "rewriter" (default) — compiled-truth-rewriter
1571
1578
  // library wrote it.
@@ -1596,6 +1603,9 @@ FOR (t:TimelineEvent) ON (t.occurredAt);
1596
1603
  CREATE INDEX timeline_event_kind IF NOT EXISTS
1597
1604
  FOR (t:TimelineEvent) ON (t.kind);
1598
1605
 
1606
+ CREATE INDEX timeline_event_learned_at IF NOT EXISTS
1607
+ FOR (t:TimelineEvent) ON (t.learnedAt);
1608
+
1599
1609
  CREATE VECTOR INDEX timeline_event_embedding IF NOT EXISTS
1600
1610
  FOR (t:TimelineEvent) ON (t.embedding)
1601
1611
  OPTIONS {
@@ -1605,6 +1615,16 @@ OPTIONS {
1605
1615
  }
1606
1616
  };
1607
1617
 
1618
+ // Task 597 migration — backfill learnedAt on :TimelineEvent nodes written
1619
+ // before transaction-time was tracked. Uses createdAt as the best available
1620
+ // proxy; nodes without createdAt get datetime() (safe: they predate the field).
1621
+ // CALL IN TRANSACTIONS avoids a single large write lock on installs with many nodes.
1622
+ CALL {
1623
+ MATCH (t:TimelineEvent) WHERE t.learnedAt IS NULL
1624
+ WITH t LIMIT 500
1625
+ SET t.learnedAt = coalesce(t.createdAt, datetime())
1626
+ } IN TRANSACTIONS OF 500 ROWS;
1627
+
1608
1628
  // `compiledTruthUpdatedAt` indices for stale-detection scans
1609
1629
  // (e.g. "find :Person with truth older than 7 days that has new events").
1610
1630
  CREATE INDEX person_compiled_truth_updated_at IF NOT EXISTS
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: platform-architecture
3
3
  description: Use when grounding any documented-surface claim about what Maxy ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
4
- content-hash: sha256:7ccf57afeb67e23745bc86265d7a65790fd4fc6cba0a659a8fb6ee3f69027e6d
4
+ content-hash: sha256:40fe99e94ab4ff0540965423bb0c7aa6016d438a5503f06aa3ab6608773c694e
5
5
  brand: maxy-code
6
6
  product-name: Maxy
7
7
  ---
@@ -1489,6 +1489,16 @@ Ask naturally:
1489
1489
  - "What did I last discuss about the Acme proposal?"
1490
1490
  - "Who have I met from the fintech conference?"
1491
1491
 
1492
+ ## Thinking tools
1493
+
1494
+ Three slash commands that apply analysis to what's already in your graph:
1495
+
1496
+ **`/challenge <claim>`** — stress-tests an assertion. Maxy searches your graph for nodes that contradict or qualify the claim — nodes that assert the opposite, name exceptions, or add significant caveats — and presents the strongest counter-case it finds. If nothing in your graph challenges the claim, it says so rather than inventing one. Results cite node IDs and relevance scores so you can inspect the sources directly.
1497
+
1498
+ **`/connect <topic-A> <topic-B>`** — finds the bridge. Maxy searches both topics, collects their immediate graph neighborhoods, and looks for nodes they share. If a direct bridge exists it names it in one sentence. If not, it surfaces the closest approach — the two nodes that are semantically nearest across the two sides — and proposes the connection you could draw.
1499
+
1500
+ **`/emerge`** — names the unnamed clusters. Maxy retrieves your KnowledgeDocument and Section nodes that are not yet connected to a Concept node, groups them by shared theme, and proposes a Concept name for each cluster. You approve or skip each proposal one at a time; nothing is written without your confirmation. Clusters of fewer than three nodes are listed at the end as "too small to cluster."
1501
+
1492
1502
  ## Listing and counting
1493
1503
 
1494
1504
  Maxy answers relational questions — "list all my people", "how many tasks do I have", "find the person with email X", "show me the 20 most recently created nodes" — via direct read-only Cypher against your Neo4j. This is faster and more precise than semantic search when the question is "the exact set where", not "things similar to".
@@ -1507,6 +1517,22 @@ The page reads only your own brand's Neo4j — a Maxy device and a Real Agent de
1507
1517
 
1508
1518
  **Typo-proof cypher.** When Maxy runs direct Cypher to answer a relational question, the query is checked against your Neo4j's live label and relationship-type taxonomy before it executes. Cypher that references an unknown name (an edge or label that does not exist in your graph) is rejected for writes and flagged with a warnings header for reads, so Maxy never silently acts on a query that targeted the wrong set of nodes. You should not see this — it runs invisibly — but it is the safety net that stops a fabricated edge name from producing "empty" results that are really just unreachable. Before acting on a bulk operation Maxy surfaces the result count and a sample; if it ever describes a cypher rejection, that means its first attempt was malformed and it corrected itself.
1509
1519
 
1520
+ ## Bi-temporal timeline events
1521
+
1522
+ Every factual statement Maxy extracts from your conversations is stored as a `:TimelineEvent` node. Each event carries two separate timestamps:
1523
+
1524
+ - **`occurredAt`** (valid-time) — when the fact was true in the world. Set from the text itself; can reference a date in the past ("Alice joined in 1990" stores `occurredAt = 1990-01-01`).
1525
+ - **`learnedAt`** (transaction-time) — when the system ingested this event. Always the wall-clock time of the write; never back-dated.
1526
+
1527
+ This distinction lets you ask two qualitatively different questions:
1528
+
1529
+ - *"What happened to Alice in 1990?"* — query by `occurredAt`.
1530
+ - *"What did Maxy learn about Alice last Tuesday?"* — query by `learnedAt`.
1531
+
1532
+ `memory-compiled-truth-history` returns both fields for every timeline event on an entity under the `timelineEvents` array, alongside the compiled-truth revision history in the `revisions` array.
1533
+
1534
+ **Backfill:** Timeline events written before this feature was added have `learnedAt` set to their `createdAt` value by the schema migration. Events without `createdAt` (very old nodes) receive the migration run time as an approximation.
1535
+
1510
1536
  ## Write doctrine
1511
1537
 
1512
1538
  Every new node in Maxy's graph is created with at least one connection to an existing node. A contact connects to the conversation or organisation it came from; a task connects to the session that raised it or the entities it will affect; a session summary connects to the conversation it summarises. A node with no connection is noise — it cannot be attributed, traversed, or explained — so the graph refuses to create one. If Maxy ever tries to record something without a link, the write is rejected and Maxy asks you to clarify where it belongs.
@@ -2572,6 +2598,18 @@ switch them off. Flipping it off again also drops them from any already-
2572
2598
  expanded neighbourhood so a click near a `ToolCall` does not re-introduce
2573
2599
  it.
2574
2600
 
2601
+ ## Direct edge management
2602
+
2603
+ `memory-edge` creates or deletes a typed directed edge between two nodes that already exist in the graph. Both nodes must belong to the same account — mismatched or foreign nodes are rejected with a structured error before any mutation runs.
2604
+
2605
+ **Create:** MERGE is idempotent. First call returns `{created: true}`; a repeated call with the same endpoints and type returns `{created: false}`. Properties supplied on the call are stamped onto the relationship on CREATE only; a subsequent idempotent hit does not overwrite them.
2606
+
2607
+ **Delete:** If the edge is present it is deleted and `{deleted: true}` is returned. If absent, the call is a no-op and returns `{deleted: false}`.
2608
+
2609
+ `relationshipType` is uppercase-coerced. Types that start with an underscore (e.g. `_SOFT_DELETE`) are reserved for platform internals and are rejected.
2610
+
2611
+ Typical flow: call `memory-search` for each endpoint to retrieve their `elementId` values, then call `memory-edge action=create relationshipType=RELATES_TO fromId=<id> toId=<id>`. The new edge appears when you hop-expand either endpoint on the `/graph` canvas.
2612
+
2575
2613
  ---
2576
2614
  # Neo4j Edge Types
2577
2615
  Source: https://docs.getmaxy.com/neo4j.md
@@ -147,3 +147,15 @@ the 90% domain-navigation path stays clean without having to remember to
147
147
  switch them off. Flipping it off again also drops them from any already-
148
148
  expanded neighbourhood so a click near a `ToolCall` does not re-introduce
149
149
  it.
150
+
151
+ ## Direct edge management
152
+
153
+ `memory-edge` creates or deletes a typed directed edge between two nodes that already exist in the graph. Both nodes must belong to the same account — mismatched or foreign nodes are rejected with a structured error before any mutation runs.
154
+
155
+ **Create:** MERGE is idempotent. First call returns `{created: true}`; a repeated call with the same endpoints and type returns `{created: false}`. Properties supplied on the call are stamped onto the relationship on CREATE only; a subsequent idempotent hit does not overwrite them.
156
+
157
+ **Delete:** If the edge is present it is deleted and `{deleted: true}` is returned. If absent, the call is a no-op and returns `{deleted: false}`.
158
+
159
+ `relationshipType` is uppercase-coerced. Types that start with an underscore (e.g. `_SOFT_DELETE`) are reserved for platform internals and are rejected.
160
+
161
+ Typical flow: call `memory-search` for each endpoint to retrieve their `elementId` values, then call `memory-edge action=create relationshipType=RELATES_TO fromId=<id> toId=<id>`. The new edge appears when you hop-expand either endpoint on the `/graph` canvas.
@@ -90,6 +90,16 @@ Ask naturally:
90
90
  - "What did I last discuss about the Acme proposal?"
91
91
  - "Who have I met from the fintech conference?"
92
92
 
93
+ ## Thinking tools
94
+
95
+ Three slash commands that apply analysis to what's already in your graph:
96
+
97
+ **`/challenge <claim>`** — stress-tests an assertion. {{productName}} searches your graph for nodes that contradict or qualify the claim — nodes that assert the opposite, name exceptions, or add significant caveats — and presents the strongest counter-case it finds. If nothing in your graph challenges the claim, it says so rather than inventing one. Results cite node IDs and relevance scores so you can inspect the sources directly.
98
+
99
+ **`/connect <topic-A> <topic-B>`** — finds the bridge. {{productName}} searches both topics, collects their immediate graph neighborhoods, and looks for nodes they share. If a direct bridge exists it names it in one sentence. If not, it surfaces the closest approach — the two nodes that are semantically nearest across the two sides — and proposes the connection you could draw.
100
+
101
+ **`/emerge`** — names the unnamed clusters. {{productName}} retrieves your KnowledgeDocument and Section nodes that are not yet connected to a Concept node, groups them by shared theme, and proposes a Concept name for each cluster. You approve or skip each proposal one at a time; nothing is written without your confirmation. Clusters of fewer than three nodes are listed at the end as "too small to cluster."
102
+
93
103
  ## Listing and counting
94
104
 
95
105
  {{productName}} answers relational questions — "list all my people", "how many tasks do I have", "find the person with email X", "show me the 20 most recently created nodes" — via direct read-only Cypher against your Neo4j. This is faster and more precise than semantic search when the question is "the exact set where", not "things similar to".
@@ -108,6 +118,22 @@ The page reads only your own brand's Neo4j — a Maxy device and a Real Agent de
108
118
 
109
119
  **Typo-proof cypher.** When {{productName}} runs direct Cypher to answer a relational question, the query is checked against your Neo4j's live label and relationship-type taxonomy before it executes. Cypher that references an unknown name (an edge or label that does not exist in your graph) is rejected for writes and flagged with a warnings header for reads, so {{productName}} never silently acts on a query that targeted the wrong set of nodes. You should not see this — it runs invisibly — but it is the safety net that stops a fabricated edge name from producing "empty" results that are really just unreachable. Before acting on a bulk operation {{productName}} surfaces the result count and a sample; if it ever describes a cypher rejection, that means its first attempt was malformed and it corrected itself.
110
120
 
121
+ ## Bi-temporal timeline events
122
+
123
+ Every factual statement {{productName}} extracts from your conversations is stored as a `:TimelineEvent` node. Each event carries two separate timestamps:
124
+
125
+ - **`occurredAt`** (valid-time) — when the fact was true in the world. Set from the text itself; can reference a date in the past ("Alice joined in 1990" stores `occurredAt = 1990-01-01`).
126
+ - **`learnedAt`** (transaction-time) — when the system ingested this event. Always the wall-clock time of the write; never back-dated.
127
+
128
+ This distinction lets you ask two qualitatively different questions:
129
+
130
+ - *"What happened to Alice in 1990?"* — query by `occurredAt`.
131
+ - *"What did {{productName}} learn about Alice last Tuesday?"* — query by `learnedAt`.
132
+
133
+ `memory-compiled-truth-history` returns both fields for every timeline event on an entity under the `timelineEvents` array, alongside the compiled-truth revision history in the `revisions` array.
134
+
135
+ **Backfill:** Timeline events written before this feature was added have `learnedAt` set to their `createdAt` value by the schema migration. Events without `createdAt` (very old nodes) receive the migration run time as an approximation.
136
+
111
137
  ## Write doctrine
112
138
 
113
139
  Every new node in {{productName}}'s graph is created with at least one connection to an existing node. A contact connects to the conversation or organisation it came from; a task connects to the session that raised it or the entities it will affect; a session summary connects to the conversation it summarises. A node with no connection is noise — it cannot be attributed, traversed, or explained — so the graph refuses to create one. If {{productName}} ever tries to record something without a link, the write is rejected and {{productName}} asks you to clarify where it belongs.