@rubytech/create-sitedesk-code 0.1.524 → 0.1.526
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/__tests__/samba-provision.test.js +46 -1
- package/dist/__tests__/websockify-bind-wiring.test.js +47 -0
- package/dist/index.js +39 -1
- package/dist/samba-provision.js +37 -0
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +8 -7
- package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +26 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
- package/payload/platform/plugins/memory/PLUGIN.md +10 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +5 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js +141 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +6 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts +45 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js +122 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js +26 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js +201 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +89 -33
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +2 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +6 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js +148 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +83 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +90 -5
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +173 -2
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +73 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +194 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +25 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +81 -8
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js +39 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +9 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/scripts/__tests__/check-canonical-tool-names.test.sh +162 -0
- package/payload/platform/scripts/__tests__/check-no-task-id-leaks.test.sh +53 -0
- package/payload/platform/scripts/__tests__/task-id-citation.test.sh +72 -0
- package/payload/platform/scripts/check-canonical-tool-names.mjs +36 -4
- package/payload/platform/scripts/check-no-task-id-leaks.mjs +80 -62
- package/payload/platform/scripts/lib/canonical-tool-names.mjs +130 -26
- package/payload/platform/scripts/lib/task-id-citation.mjs +67 -0
- package/payload/platform/scripts/vnc.sh +45 -1
- package/payload/server/{chunk-VUXKXOJU.js → chunk-7MGR5M6G.js} +4 -2
- package/payload/server/{manager-4TJK3YOY.js → manager-6XOWHREK.js} +1 -1
- package/payload/server/server.js +10 -4
- package/payload/platform/.docs/search-surface-contract.md +0 -58
- package/payload/platform/docs/superpowers/plans/2026-06-02-task-610-follower-202-retry.md +0 -372
- package/payload/platform/docs/superpowers/plans/2026-06-04-public-agent-knowledge-delivery.md +0 -230
- package/payload/platform/docs/superpowers/plans/2026-06-23-account-filesystem-schema.md +0 -544
- package/payload/platform/docs/superpowers/plans/2026-07-11-task-1557-operator-on-behalf-preference-attribution.md +0 -542
- package/payload/platform/docs/superpowers/plans/2026-07-13-account-schema-ontology-projection.md +0 -547
- package/payload/platform/docs/superpowers/plans/2026-07-14-graph-top-level-labels-ontology-single-source.md +0 -458
- package/payload/platform/docs/superpowers/plans/2026-07-17-task-1736-retire-mcp-stderr-tee.md +0 -397
- package/payload/platform/docs/superpowers/plans/2026-07-18-graph-native-ledger.md +0 -807
- package/payload/platform/docs/superpowers/plans/2026-07-18-ledger-write-path-fix.md +0 -109
- package/payload/platform/docs/superpowers/plans/2026-07-20-storage-pages-create.md +0 -82
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1704-data-portal-standing-audit.md +0 -673
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1789-reseat-channel-row-fork.md +0 -1244
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1818-loop-gate-app-routes.md +0 -462
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1819-top-level-label-allowlist.md +0 -321
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1829-platform-ui-typecheck.md +0 -830
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1831-data-portal-class-derived-allowlist.md +0 -2177
- package/payload/platform/docs/superpowers/plans/2026-07-21-graph-caption-resolver.md +0 -124
- package/payload/platform/docs/superpowers/plans/2026-07-21-task-1877-bash-schema-enforcement.md +0 -107
- package/payload/platform/docs/superpowers/plans/2026-07-21-task-1887-reconcile-allowed-top-level.md +0 -205
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1899-reconcile-report-only.md +0 -748
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1910-two-way-portal-exchange.md +0 -1716
- package/payload/platform/docs/superpowers/plans/2026-07-23-task-1930-adherence-enforcement.md +0 -422
- package/payload/platform/docs/superpowers/plans/2026-07-24-task-1942-subaccount-switcher-brand-head.md +0 -327
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1974-uploads-intake-inbox.md +0 -235
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1976-intra-folder-hygiene.md +0 -215
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-1902-account-owned-entry-declarations.md +0 -555
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-1926-portal-push-concurrency-guard.md +0 -482
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-2023-sidebar-sessions-async-reads.md +0 -394
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2016-disabled-agent-routing.md +0 -624
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2028-declared-file-write-deny.md +0 -303
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2052-account-machinery-write-fence.md +0 -250
- package/payload/platform/docs/superpowers/plans/2026-07-28-task-2097-email-signature-set.md +0 -65
- package/payload/platform/docs/superpowers/specs/2026-06-02-task-610-follower-202-retry-design.md +0 -116
- package/payload/platform/docs/superpowers/specs/2026-06-23-account-filesystem-schema-design.md +0 -170
- package/payload/platform/docs/superpowers/specs/2026-07-11-task-1557-operator-on-behalf-preference-attribution-design.md +0 -90
- package/payload/platform/docs/superpowers/specs/2026-07-13-account-schema-ontology-projection-design.md +0 -178
- package/payload/platform/docs/superpowers/specs/2026-07-14-graph-top-level-labels-ontology-single-source-design.md +0 -119
- package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md +0 -128
- package/payload/platform/docs/superpowers/specs/2026-07-18-graph-native-ledger-design.md +0 -241
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1704-data-portal-standing-audit-design.md +0 -177
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1789-reseat-channel-row-fork-design.md +0 -201
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1818-loop-gate-app-routes-design.md +0 -217
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1819-top-level-label-allowlist-design.md +0 -80
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1820-cpu-triage-admin-tools-design.md +0 -97
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1829-platform-ui-typecheck-design.md +0 -163
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1831-data-portal-class-derived-allowlist-design.md +0 -163
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1899-reconcile-report-only-design.md +0 -121
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1910-two-way-portal-exchange-design.md +0 -103
- package/payload/platform/docs/superpowers/specs/2026-07-23-task-1930-adherence-enforcement-design.md +0 -81
- package/payload/platform/docs/superpowers/specs/2026-07-24-task-1942-subaccount-switcher-brand-head-design.md +0 -35
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1902-account-owned-entry-declarations-design.md +0 -232
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1926-portal-push-concurrency-guard-design.md +0 -200
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-2014-ui-suite-nondeterminism-design.md +0 -169
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2016-disabled-agent-routing-design.md +0 -139
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2028-declared-file-write-deny-design.md +0 -127
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2052-account-machinery-write-fence-design.md +0 -150
- package/payload/platform/docs/superpowers/specs/2026-07-28-task-2097-email-signature-set-design.md +0 -155
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-ingest.d.ts","sourceRoot":"","sources":["../../src/lib/log-ingest.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,sBAAsB,GACtB,wBAAwB,GACxB,mBAAmB,GACnB,2BAA2B,GAC3B,sBAAsB,GACtB,wBAAwB,GACxB,wBAAwB,GACxB,cAAc,GACd,oBAAoB,CAAC;AAEzB,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;AAEnD,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAW3D;AAED,kFAAkF;AAClF,wBAAsB,cAAc,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkClE;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,qBAAqB,GAC7C,OAAO,CAAC,CAAC,CAAC,CA8BZ;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"log-ingest.d.ts","sourceRoot":"","sources":["../../src/lib/log-ingest.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,sBAAsB,GACtB,wBAAwB,GACxB,mBAAmB,GACnB,2BAA2B,GAC3B,sBAAsB,GACtB,wBAAwB,GACxB,wBAAwB,GACxB,cAAc,GACd,iBAAiB,GACjB,oBAAoB,CAAC;AAEzB,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;AAEnD,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAW3D;AAED,kFAAkF;AAClF,wBAAsB,cAAc,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkClE;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,qBAAqB,GAC7C,OAAO,CAAC,CAAC,CAAC,CA8BZ;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAuC7D;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAO5F"}
|
|
@@ -134,6 +134,12 @@ export function classifyReason(err) {
|
|
|
134
134
|
return "schema-unknown-label";
|
|
135
135
|
if (/Schema\.org/i.test(msg) && /property/i.test(msg))
|
|
136
136
|
return "schema-property-naming";
|
|
137
|
+
// A refusal to change a property's Neo4j type. Matched before the gate rule
|
|
138
|
+
// below, which its "Update blocked" prefix would otherwise claim: a label or
|
|
139
|
+
// property denylist refusal and a temporal type refusal are different causes,
|
|
140
|
+
// and an operator grepping the reason must be able to tell them apart.
|
|
141
|
+
if (/^Update blocked \(type-preserving\)/i.test(msg))
|
|
142
|
+
return "type-preserving";
|
|
137
143
|
// graph-write-gate "Write blocked" / "Update blocked" — checkGraphWriteGate
|
|
138
144
|
if (/^(Write|Update) blocked/i.test(msg))
|
|
139
145
|
return "gate-blocked";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-ingest.js","sourceRoot":"","sources":["../../src/lib/log-ingest.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,0EAA0E;AAC1E,6CAA6C;AAC7C,wEAAwE;AACxE,4CAA4C;AAC5C,EAAE;AACF,uBAAuB;AACvB,gHAAgH;AAChH,uBAAuB;AACvB,oIAAoI;AACpI,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAC5E,sEAAsE;AACtE,gBAAgB;AAEhB,MAAM,GAAG,GAAG,YAAY,CAAC;AACzB,MAAM,aAAa,GAAG,WAAW,CAAC;AAClC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAC9C,MAAM,UAAU,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"log-ingest.js","sourceRoot":"","sources":["../../src/lib/log-ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** `valueType()` reports nullability, e.g. `ZONED DATETIME NOT NULL`. A value
|
|
2
|
+
* read off a node is always NOT NULL, so the suffix carries no information. */
|
|
3
|
+
export declare function normaliseValueType(raw: string): string;
|
|
4
|
+
/** The constructor for a `valueType()` reading, or null when the type is not
|
|
5
|
+
* temporal and the value can ride in the `n += $props` bag unchanged. */
|
|
6
|
+
export declare function temporalConstructorFor(rawValueType: string): string | null;
|
|
7
|
+
/** A value the caller must vet with Neo4j's own temporal parser before the
|
|
8
|
+
* write runs. Vetting up front is what makes the rejection all-or-nothing. */
|
|
9
|
+
export interface TemporalProbe {
|
|
10
|
+
key: string;
|
|
11
|
+
constructorName: string;
|
|
12
|
+
paramName: string;
|
|
13
|
+
value: unknown;
|
|
14
|
+
/** Normalised `valueType()` reading, for the rejection message. */
|
|
15
|
+
existingType: string;
|
|
16
|
+
}
|
|
17
|
+
export interface CompiledUpdate {
|
|
18
|
+
/** The SET clause body, without the leading `SET`. */
|
|
19
|
+
setClause: string;
|
|
20
|
+
/** Query params. Always carries `props`; temporal values are `tp0`, `tp1`, … */
|
|
21
|
+
params: Record<string, unknown>;
|
|
22
|
+
probes: TemporalProbe[];
|
|
23
|
+
}
|
|
24
|
+
/** The single rejection message for every type-preserving refusal — raised here
|
|
25
|
+
* for a value this module can already see is wrong, and by the caller when
|
|
26
|
+
* Neo4j's parser rejects a probe. `Update blocked` is what `classifyReason`
|
|
27
|
+
* maps to `reason=gate-blocked`, so the refusal always reaches the log. */
|
|
28
|
+
export declare function typePreserveRejection(key: string, existingType: string, value: unknown): Error;
|
|
29
|
+
export interface CompileArgs {
|
|
30
|
+
/** Node alias the SET clause addresses. */
|
|
31
|
+
alias: string;
|
|
32
|
+
/** `valueType()` per property key, for the keys the node already holds. A key
|
|
33
|
+
* absent from this map is new on the node and has no type to preserve. */
|
|
34
|
+
existingTypes: Record<string, string>;
|
|
35
|
+
props: Record<string, unknown>;
|
|
36
|
+
/** The write-time stamp. Its key is removed from `props` first, so a
|
|
37
|
+
* caller-supplied value can never reach the node or a probe — matching the
|
|
38
|
+
* pre-existing behaviour where the explicit stamp overwrote it. */
|
|
39
|
+
now: {
|
|
40
|
+
key: string;
|
|
41
|
+
isoValue: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export declare function compileTypePreservingSet(args: CompileArgs): CompiledUpdate;
|
|
45
|
+
//# sourceMappingURL=temporal-type-preserve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal-type-preserve.d.ts","sourceRoot":"","sources":["../../src/lib/temporal-type-preserve.ts"],"names":[],"mappings":"AA2CA;gFACgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;0EAC0E;AAC1E,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1E;AAED;+EAC+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED;;;4EAG4E;AAC5E,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,CAM9F;AAOD,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd;+EAC2E;IAC3E,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;;wEAEoE;IACpE,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAgE1E"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Task 2148 — type-preserving SET compiler for memory-update.
|
|
3
|
+
//
|
|
4
|
+
// `SET n += $props` writes every value verbatim. An agent updating a :Meeting
|
|
5
|
+
// with `startsAt: "2026-07-29T13:30:00Z"` therefore replaced a ZONED DATETIME
|
|
6
|
+
// with a STRING, and a `STRING`-to-`DATETIME` comparison in Neo4j is NULL, not
|
|
7
|
+
// false: every calendar reader dropped the row with no error and no log line.
|
|
8
|
+
//
|
|
9
|
+
// This module decides, per key, whether the value can ride in the `n += $props`
|
|
10
|
+
// bag or has to be rebuilt with the temporal constructor matching the type the
|
|
11
|
+
// node already holds. It is pure — the caller owns the session — and it never
|
|
12
|
+
// guesses at Neo4j's temporal grammar: values bound for a constructor come back
|
|
13
|
+
// as `probes`, which the caller vets with Neo4j's own parser before any write.
|
|
14
|
+
//
|
|
15
|
+
// existing valueType(n.startsAt) emitted SET fragment
|
|
16
|
+
// ──────────────────────────────── ─────────────────────────────────
|
|
17
|
+
// STRING / INTEGER / absent (stays in `n += $props`)
|
|
18
|
+
// ZONED DATETIME n.`startsAt` = datetime($tp0)
|
|
19
|
+
// DATE n.`startsAt` = date($tp0)
|
|
20
|
+
//
|
|
21
|
+
// The `updatedAt` stamp follows the same rule rather than being forced to one
|
|
22
|
+
// type: `memory-write` stamps it as an ISO string (memory-write.ts:223) and the
|
|
23
|
+
// graph tooltip reads it with `typeof props.updatedAt === 'string'`
|
|
24
|
+
// (platform/ui/app/graph/display-helpers.ts:286), so an unconditional
|
|
25
|
+
// `datetime()` would be the very retype this module exists to prevent.
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
/** Neo4j temporal types, as `valueType()` names them, and the Cypher
|
|
28
|
+
* constructor that rebuilds a value of that type. */
|
|
29
|
+
const TEMPORAL_CONSTRUCTORS = {
|
|
30
|
+
DATE: "date",
|
|
31
|
+
"ZONED DATETIME": "datetime",
|
|
32
|
+
"LOCAL DATETIME": "localdatetime",
|
|
33
|
+
"ZONED TIME": "time",
|
|
34
|
+
"LOCAL TIME": "localtime",
|
|
35
|
+
DURATION: "duration",
|
|
36
|
+
};
|
|
37
|
+
/** The five constructors with a zero-argument "now" form. `duration` has none,
|
|
38
|
+
* which is why a DURATION-typed `updatedAt` is a rejection rather than a
|
|
39
|
+
* silent retype. */
|
|
40
|
+
const NOW_CAPABLE = new Set(["date", "datetime", "localdatetime", "time", "localtime"]);
|
|
41
|
+
/** `valueType()` reports nullability, e.g. `ZONED DATETIME NOT NULL`. A value
|
|
42
|
+
* read off a node is always NOT NULL, so the suffix carries no information. */
|
|
43
|
+
export function normaliseValueType(raw) {
|
|
44
|
+
return raw.trim().replace(/\s+NOT\s+NULL$/i, "").trim();
|
|
45
|
+
}
|
|
46
|
+
/** The constructor for a `valueType()` reading, or null when the type is not
|
|
47
|
+
* temporal and the value can ride in the `n += $props` bag unchanged. */
|
|
48
|
+
export function temporalConstructorFor(rawValueType) {
|
|
49
|
+
return TEMPORAL_CONSTRUCTORS[normaliseValueType(rawValueType)] ?? null;
|
|
50
|
+
}
|
|
51
|
+
/** The single rejection message for every type-preserving refusal — raised here
|
|
52
|
+
* for a value this module can already see is wrong, and by the caller when
|
|
53
|
+
* Neo4j's parser rejects a probe. `Update blocked` is what `classifyReason`
|
|
54
|
+
* maps to `reason=gate-blocked`, so the refusal always reaches the log. */
|
|
55
|
+
export function typePreserveRejection(key, existingType, value) {
|
|
56
|
+
return new Error(`Update blocked (type-preserving): ${key} holds ${existingType} and ` +
|
|
57
|
+
`"${String(value)}" is not a valid ${existingType}. ` +
|
|
58
|
+
`The whole update was rejected — no property was changed.`);
|
|
59
|
+
}
|
|
60
|
+
/** Backticks are the only character that can break out of `n.\`key\``. */
|
|
61
|
+
function quoteKey(key) {
|
|
62
|
+
return "`" + key.replace(/`/g, "``") + "`";
|
|
63
|
+
}
|
|
64
|
+
export function compileTypePreservingSet(args) {
|
|
65
|
+
const { alias, existingTypes, props, now } = args;
|
|
66
|
+
const scalarProps = {};
|
|
67
|
+
const assignments = [];
|
|
68
|
+
const probes = [];
|
|
69
|
+
const params = {};
|
|
70
|
+
let paramIndex = 0;
|
|
71
|
+
for (const [key, value] of Object.entries(props)) {
|
|
72
|
+
if (key === now.key)
|
|
73
|
+
continue;
|
|
74
|
+
const rawType = existingTypes[key];
|
|
75
|
+
const constructorName = rawType ? temporalConstructorFor(rawType) : null;
|
|
76
|
+
if (!constructorName) {
|
|
77
|
+
scalarProps[key] = value;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// `null` removes the property. Removal changes no type, so it is not this
|
|
81
|
+
// module's business — it rides in the props bag exactly as it always did.
|
|
82
|
+
// Refusing it would take away the only way to clear a temporal property.
|
|
83
|
+
if (value === null) {
|
|
84
|
+
scalarProps[key] = value;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const existingType = normaliseValueType(rawType);
|
|
88
|
+
// Only a non-empty string can reach a temporal constructor. Anything else
|
|
89
|
+
// is refused here rather than probed: Neo4j would reject it too, and this
|
|
90
|
+
// way the message names the key without a round trip.
|
|
91
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
92
|
+
throw typePreserveRejection(key, existingType, value);
|
|
93
|
+
}
|
|
94
|
+
const paramName = `tp${paramIndex++}`;
|
|
95
|
+
params[paramName] = value;
|
|
96
|
+
assignments.push(`${alias}.${quoteKey(key)} = ${constructorName}(\$${paramName})`);
|
|
97
|
+
probes.push({ key, constructorName, paramName, value, existingType });
|
|
98
|
+
}
|
|
99
|
+
// The stamp is emitted last so it wins over anything in `props`, exactly as
|
|
100
|
+
// the trailing `n.updatedAt = $updatedAt` did before.
|
|
101
|
+
const nowRawType = existingTypes[now.key];
|
|
102
|
+
const nowConstructor = nowRawType ? temporalConstructorFor(nowRawType) : null;
|
|
103
|
+
if (nowConstructor) {
|
|
104
|
+
const nowType = normaliseValueType(nowRawType);
|
|
105
|
+
if (!NOW_CAPABLE.has(nowConstructor)) {
|
|
106
|
+
throw typePreserveRejection(now.key, nowType, now.isoValue);
|
|
107
|
+
}
|
|
108
|
+
assignments.push(`${alias}.${quoteKey(now.key)} = ${nowConstructor}()`);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const paramName = `tp${paramIndex++}`;
|
|
112
|
+
params[paramName] = now.isoValue;
|
|
113
|
+
assignments.push(`${alias}.${quoteKey(now.key)} = \$${paramName}`);
|
|
114
|
+
}
|
|
115
|
+
params.props = scalarProps;
|
|
116
|
+
return {
|
|
117
|
+
setClause: [`${alias} += \$props`, ...assignments].join(", "),
|
|
118
|
+
params,
|
|
119
|
+
probes,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=temporal-type-preserve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal-type-preserve.js","sourceRoot":"","sources":["../../src/lib/temporal-type-preserve.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js
CHANGED
|
@@ -55,6 +55,32 @@ describe("memory-update-by-name — happy path", () => {
|
|
|
55
55
|
expect(params).toEqual({ accountId: ACCOUNT_ID, name: "BioSymm Technologies Ltd" });
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
|
+
describe("memory-update-by-name — Task 2148 type preservation is inherited", () => {
|
|
59
|
+
// This tool owns the lookup and nothing else: the write, the gates and the
|
|
60
|
+
// type-preserving SET all live in memoryUpdate, which it delegates to. So the
|
|
61
|
+
// guard here is that the properties bag arrives verbatim — if it ever grew its
|
|
62
|
+
// own write path, a :Meeting reachable by name would be a second route to the
|
|
63
|
+
// string retype that made Adam Mackay's golf afternoon publish as open time.
|
|
64
|
+
it("hands a temporal property straight to memoryUpdate without rewriting it", async () => {
|
|
65
|
+
mockSession.run.mockResolvedValueOnce({ records: [record("4:meeting:17")] });
|
|
66
|
+
memoryUpdateMock.mockResolvedValueOnce({ nodeId: "4:meeting:17", labels: ["Meeting"], updated: true });
|
|
67
|
+
await memoryUpdateByName({
|
|
68
|
+
label: "Meeting",
|
|
69
|
+
name: "Golf",
|
|
70
|
+
accountId: ACCOUNT_ID,
|
|
71
|
+
properties: { startsAt: "2026-07-29T13:30:00Z", endsAt: "2026-07-29T17:30:00Z" },
|
|
72
|
+
createdBy: CREATED_BY,
|
|
73
|
+
});
|
|
74
|
+
expect(memoryUpdateMock).toHaveBeenCalledWith({
|
|
75
|
+
nodeId: "4:meeting:17",
|
|
76
|
+
properties: { startsAt: "2026-07-29T13:30:00Z", endsAt: "2026-07-29T17:30:00Z" },
|
|
77
|
+
accountId: ACCOUNT_ID,
|
|
78
|
+
createdBy: CREATED_BY,
|
|
79
|
+
});
|
|
80
|
+
// The lookup is the only statement this tool runs itself.
|
|
81
|
+
expect(mockSession.run).toHaveBeenCalledTimes(1);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
58
84
|
describe("memory-update-by-name — reject paths", () => {
|
|
59
85
|
it("throws 'not found' on zero matches with the lookup tuple in the message", async () => {
|
|
60
86
|
mockSession.run.mockResolvedValueOnce({ records: [] });
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-update-by-name.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-by-name.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"memory-update-by-name.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-by-name.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-update-type-preserve.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-type-preserve.test.ts"],"names":[],"mappings":""}
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Task 2148 — memory-update must not be able to change a property's Neo4j
|
|
2
|
+
// type. Before this, `SET n += $props` wrote an ISO string straight over a
|
|
3
|
+
// :Meeting's ZONED DATETIME `startsAt`, and every `m.startsAt < datetime(...)`
|
|
4
|
+
// comparison against the result was NULL rather than false — the booking page
|
|
5
|
+
// offered a busy afternoon as open time for two days with no error logged.
|
|
6
|
+
//
|
|
7
|
+
// The suite asserts the Cypher the tool builds, which is the surface the fix
|
|
8
|
+
// lives on: neither plugin has a live-Neo4j harness, so a `valueType()` read is
|
|
9
|
+
// not available to a unit test. Every temporal value is vetted by Neo4j's own
|
|
10
|
+
// parser through a probe query BEFORE the update runs, so a rejection can never
|
|
11
|
+
// leave a partially-applied node.
|
|
12
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
13
|
+
const mockSession = {
|
|
14
|
+
run: vi.fn(),
|
|
15
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
16
|
+
};
|
|
17
|
+
vi.mock("../../lib/neo4j.js", () => ({
|
|
18
|
+
getSession: () => mockSession,
|
|
19
|
+
}));
|
|
20
|
+
vi.mock("../../lib/embeddings.js", () => ({
|
|
21
|
+
embed: vi.fn().mockResolvedValue([0.1, 0.2]),
|
|
22
|
+
}));
|
|
23
|
+
vi.mock("../memory-write.js", () => ({
|
|
24
|
+
buildTextRepresentation: () => "text",
|
|
25
|
+
}));
|
|
26
|
+
vi.mock("../../lib/graph-write-gate.js", () => ({
|
|
27
|
+
checkGraphWriteGate: vi.fn().mockResolvedValue({ ok: true }),
|
|
28
|
+
checkLabelWriteGate: vi.fn().mockReturnValue({ ok: true }),
|
|
29
|
+
checkPropertyWriteGate: vi.fn().mockReturnValue({ ok: true }),
|
|
30
|
+
}));
|
|
31
|
+
import { memoryUpdate } from "../memory-update.js";
|
|
32
|
+
const ACCOUNT_ID = "dddb9148-7ba4-4de7-a0da-6eadc5743eda";
|
|
33
|
+
const NODE_ID = "4:meeting:17";
|
|
34
|
+
const CREATED_BY = { agent: undefined, session: undefined, tool: "memory-update" };
|
|
35
|
+
/** The pre-read row: labels, name, sliceToken, and the `valueType()` of each
|
|
36
|
+
* incoming key the node already holds. */
|
|
37
|
+
function preRead(labels, propTypes) {
|
|
38
|
+
return {
|
|
39
|
+
records: [
|
|
40
|
+
{
|
|
41
|
+
get: (k) => k === "nodeLabels" ? labels : k === "propTypes" ? propTypes : null,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function updateRow() {
|
|
47
|
+
return {
|
|
48
|
+
records: [
|
|
49
|
+
{
|
|
50
|
+
get: (k) => k === "nodeId" ? NODE_ID : k === "nodeLabels" ? ["Meeting"] : {},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Every `session.run` call's Cypher, in order. */
|
|
56
|
+
function cyphers() {
|
|
57
|
+
return mockSession.run.mock.calls.map((c) => c[0]);
|
|
58
|
+
}
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
mockSession.run.mockReset();
|
|
61
|
+
mockSession.close.mockClear();
|
|
62
|
+
});
|
|
63
|
+
describe("memory-update — reads the existing property types", () => {
|
|
64
|
+
it("asks Neo4j for valueType() of every incoming key plus updatedAt", async () => {
|
|
65
|
+
mockSession.run
|
|
66
|
+
.mockResolvedValueOnce(preRead(["Meeting"], []))
|
|
67
|
+
.mockResolvedValueOnce(updateRow())
|
|
68
|
+
.mockResolvedValueOnce({ records: [] });
|
|
69
|
+
await memoryUpdate({
|
|
70
|
+
nodeId: NODE_ID,
|
|
71
|
+
properties: { title: "Golf" },
|
|
72
|
+
accountId: ACCOUNT_ID,
|
|
73
|
+
createdBy: CREATED_BY,
|
|
74
|
+
});
|
|
75
|
+
const [cypher, params] = mockSession.run.mock.calls[0];
|
|
76
|
+
expect(cypher).toContain("valueType(n[k])");
|
|
77
|
+
expect(params.propKeys).toEqual(["title", "updatedAt"]);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe("memory-update — a temporal property keeps its type", () => {
|
|
81
|
+
it("rebuilds a ZONED DATETIME key with datetime() instead of the props bag", async () => {
|
|
82
|
+
mockSession.run
|
|
83
|
+
.mockResolvedValueOnce(preRead(["Meeting"], [
|
|
84
|
+
["startsAt", "ZONED DATETIME NOT NULL"],
|
|
85
|
+
["title", "STRING NOT NULL"],
|
|
86
|
+
["updatedAt", "ZONED DATETIME NOT NULL"],
|
|
87
|
+
]))
|
|
88
|
+
// the probe
|
|
89
|
+
.mockResolvedValueOnce({ records: [{ get: () => null }] })
|
|
90
|
+
.mockResolvedValueOnce(updateRow())
|
|
91
|
+
.mockResolvedValueOnce({ records: [] });
|
|
92
|
+
await memoryUpdate({
|
|
93
|
+
nodeId: NODE_ID,
|
|
94
|
+
properties: { startsAt: "2026-07-29T13:30:00Z", title: "Golf" },
|
|
95
|
+
accountId: ACCOUNT_ID,
|
|
96
|
+
createdBy: CREATED_BY,
|
|
97
|
+
});
|
|
98
|
+
// The probe runs before the write, so a bad value can never half-apply.
|
|
99
|
+
expect(cyphers()[1]).toBe("RETURN datetime($tp0) AS probe");
|
|
100
|
+
const [updateCypher, updateParams] = mockSession.run.mock.calls[2];
|
|
101
|
+
expect(updateCypher).toContain("SET n += $props, n.`startsAt` = datetime($tp0), n.`updatedAt` = datetime()");
|
|
102
|
+
expect(updateCypher).not.toContain("n.updatedAt = $updatedAt");
|
|
103
|
+
expect(updateParams.props).toEqual({ title: "Golf" });
|
|
104
|
+
expect(updateParams.tp0).toBe("2026-07-29T13:30:00Z");
|
|
105
|
+
});
|
|
106
|
+
it("leaves a node with no temporal keys on the plain props bag and an ISO stamp", async () => {
|
|
107
|
+
mockSession.run
|
|
108
|
+
.mockResolvedValueOnce(preRead(["Organization"], [["name", "STRING NOT NULL"], ["updatedAt", "STRING NOT NULL"]]))
|
|
109
|
+
.mockResolvedValueOnce(updateRow())
|
|
110
|
+
.mockResolvedValueOnce({ records: [] });
|
|
111
|
+
await memoryUpdate({
|
|
112
|
+
nodeId: NODE_ID,
|
|
113
|
+
properties: { name: "Acme" },
|
|
114
|
+
accountId: ACCOUNT_ID,
|
|
115
|
+
createdBy: CREATED_BY,
|
|
116
|
+
});
|
|
117
|
+
// No probe: the second call is the update itself.
|
|
118
|
+
expect(cyphers()).toHaveLength(3);
|
|
119
|
+
const [updateCypher, updateParams] = mockSession.run.mock.calls[1];
|
|
120
|
+
expect(updateCypher).toContain("SET n += $props, n.`updatedAt` = $tp0");
|
|
121
|
+
expect(typeof updateParams.tp0).toBe("string");
|
|
122
|
+
expect(Number.isNaN(Date.parse(updateParams.tp0))).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("memory-update — the updatedAt stamp keeps the node's own type", () => {
|
|
126
|
+
it("writes a string stamp on a node whose updatedAt is a string", async () => {
|
|
127
|
+
mockSession.run
|
|
128
|
+
.mockResolvedValueOnce(preRead(["Organization"], [["updatedAt", "STRING NOT NULL"]]))
|
|
129
|
+
.mockResolvedValueOnce(updateRow())
|
|
130
|
+
.mockResolvedValueOnce({ records: [] });
|
|
131
|
+
await memoryUpdate({
|
|
132
|
+
nodeId: NODE_ID,
|
|
133
|
+
properties: { name: "Acme" },
|
|
134
|
+
accountId: ACCOUNT_ID,
|
|
135
|
+
createdBy: CREATED_BY,
|
|
136
|
+
});
|
|
137
|
+
expect(mockSession.run.mock.calls[1][0]).toContain("n.`updatedAt` = $tp0");
|
|
138
|
+
});
|
|
139
|
+
it("writes datetime() on a node whose updatedAt is a ZONED DATETIME", async () => {
|
|
140
|
+
mockSession.run
|
|
141
|
+
.mockResolvedValueOnce(preRead(["Meeting"], [["updatedAt", "ZONED DATETIME NOT NULL"]]))
|
|
142
|
+
.mockResolvedValueOnce(updateRow())
|
|
143
|
+
.mockResolvedValueOnce({ records: [] });
|
|
144
|
+
await memoryUpdate({
|
|
145
|
+
nodeId: NODE_ID,
|
|
146
|
+
properties: { title: "Golf" },
|
|
147
|
+
accountId: ACCOUNT_ID,
|
|
148
|
+
createdBy: CREATED_BY,
|
|
149
|
+
});
|
|
150
|
+
expect(mockSession.run.mock.calls[1][0]).toContain("n.`updatedAt` = datetime()");
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
describe("memory-update — rejection is whole-update", () => {
|
|
154
|
+
it("refuses a non-string value for a temporal key without running any write", async () => {
|
|
155
|
+
mockSession.run.mockResolvedValueOnce(preRead(["Meeting"], [["startsAt", "ZONED DATETIME NOT NULL"]]));
|
|
156
|
+
await expect(memoryUpdate({
|
|
157
|
+
nodeId: NODE_ID,
|
|
158
|
+
properties: { startsAt: 1754000000000, title: "Golf" },
|
|
159
|
+
accountId: ACCOUNT_ID,
|
|
160
|
+
createdBy: CREATED_BY,
|
|
161
|
+
})).rejects.toThrow(/Update blocked \(type-preserving\): startsAt holds ZONED DATETIME/);
|
|
162
|
+
// Only the pre-read ran — `title` would have succeeded and did not.
|
|
163
|
+
expect(mockSession.run).toHaveBeenCalledTimes(1);
|
|
164
|
+
});
|
|
165
|
+
it("lets a transient driver failure through instead of blaming the value", async () => {
|
|
166
|
+
// A disconnect is not a verdict on the timestamp. Reporting it as
|
|
167
|
+
// "not a valid ZONED DATETIME" would send the agent to reword a value that
|
|
168
|
+
// was correct, and no rewording could ever succeed.
|
|
169
|
+
const transient = Object.assign(new Error("Connection was closed by server"), {
|
|
170
|
+
code: "Neo.TransientError.General.DatabaseUnavailable",
|
|
171
|
+
});
|
|
172
|
+
mockSession.run
|
|
173
|
+
.mockResolvedValueOnce(preRead(["Meeting"], [["startsAt", "ZONED DATETIME NOT NULL"]]))
|
|
174
|
+
.mockRejectedValueOnce(transient);
|
|
175
|
+
await expect(memoryUpdate({
|
|
176
|
+
nodeId: NODE_ID,
|
|
177
|
+
properties: { startsAt: "2026-07-29T13:30:00Z" },
|
|
178
|
+
accountId: ACCOUNT_ID,
|
|
179
|
+
createdBy: CREATED_BY,
|
|
180
|
+
})).rejects.toThrow(/Connection was closed by server/);
|
|
181
|
+
expect(mockSession.run).toHaveBeenCalledTimes(2);
|
|
182
|
+
});
|
|
183
|
+
it("turns a Neo4j parser refusal into the type-preserving message, before any write", async () => {
|
|
184
|
+
const clientError = Object.assign(new Error("Text cannot be parsed to a DateTime"), {
|
|
185
|
+
code: "Neo.ClientError.Statement.ArgumentError",
|
|
186
|
+
});
|
|
187
|
+
mockSession.run
|
|
188
|
+
.mockResolvedValueOnce(preRead(["Meeting"], [["startsAt", "ZONED DATETIME NOT NULL"]]))
|
|
189
|
+
.mockRejectedValueOnce(clientError);
|
|
190
|
+
await expect(memoryUpdate({
|
|
191
|
+
nodeId: NODE_ID,
|
|
192
|
+
properties: { startsAt: "next tuesday", title: "Golf" },
|
|
193
|
+
accountId: ACCOUNT_ID,
|
|
194
|
+
createdBy: CREATED_BY,
|
|
195
|
+
})).rejects.toThrow(/Update blocked \(type-preserving\): startsAt holds ZONED DATETIME and "next tuesday" is not a valid ZONED DATETIME/);
|
|
196
|
+
// Pre-read + probe only. The update never ran.
|
|
197
|
+
expect(mockSession.run).toHaveBeenCalledTimes(2);
|
|
198
|
+
expect(cyphers()[1]).toBe("RETURN datetime($tp0) AS probe");
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
//# sourceMappingURL=memory-update-type-preserve.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-update-type-preserve.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-type-preserve.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-update.d.ts","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-update.d.ts","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAE9E,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AA0DD,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAO9E"}
|