@rubytech/create-maxy 1.0.811 → 1.0.813

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 (31) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/neo4j/migrations/004-project-admin-agent.ts +89 -21
  3. package/payload/server/chunk-6UFBDVWR.js +10009 -0
  4. package/payload/server/chunk-D2JKNYRK.js +1027 -0
  5. package/payload/server/chunk-FMNXMQIL.js +2525 -0
  6. package/payload/server/chunk-KKC4IV6I.js +10050 -0
  7. package/payload/server/chunk-TQTMKIW6.js +2547 -0
  8. package/payload/server/chunk-WK6KSHPD.js +1027 -0
  9. package/payload/server/client-pool-KUFFECZC.js +31 -0
  10. package/payload/server/client-pool-VW3EE2YD.js +31 -0
  11. package/payload/server/maxy-edge.js +3 -3
  12. package/payload/server/neo4j-migrations-CALDCV6M.js +300 -0
  13. package/payload/server/neo4j-migrations-SU4TDFK2.js +300 -0
  14. package/payload/server/public/assets/{Checkbox-BruL6MSR.js → Checkbox-L-AVlzpu.js} +1 -1
  15. package/payload/server/public/assets/{admin-DEpiIhX6.js → admin-D_1VXUmN.js} +20 -20
  16. package/payload/server/public/assets/data-qc5_bVVg.js +1 -0
  17. package/payload/server/public/assets/graph-Dy65Y3T3.js +1 -0
  18. package/payload/server/public/assets/{jsx-runtime-foO6ZMix.css → jsx-runtime-B4OPP5PQ.css} +1 -1
  19. package/payload/server/public/assets/{page-B6RDeHJu.js → page-CGTUVIDm.js} +2 -2
  20. package/payload/server/public/assets/{page-CwUuxhGW.js → page-sZ6T4GwW.js} +1 -1
  21. package/payload/server/public/assets/{public-CfjzDdUe.js → public-BLPUQVy7.js} +1 -1
  22. package/payload/server/public/assets/{useAdminFetch-iYCQ9lT0.js → useAdminFetch-zpmdQvyy.js} +1 -1
  23. package/payload/server/public/assets/{useVoiceRecorder-D_8P7xJU.js → useVoiceRecorder-18dZkZGR.js} +1 -1
  24. package/payload/server/public/data.html +5 -5
  25. package/payload/server/public/graph.html +6 -6
  26. package/payload/server/public/index.html +8 -8
  27. package/payload/server/public/public.html +5 -5
  28. package/payload/server/server.js +65 -35
  29. package/payload/server/public/assets/data-zXzsrn3y.js +0 -1
  30. package/payload/server/public/assets/graph-Bc7QuO11.js +0 -1
  31. /package/payload/server/public/assets/{jsx-runtime-DJER3a7U.js → jsx-runtime-DOYWvSKw.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.811",
3
+ "version": "1.0.813",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -30,16 +30,20 @@
30
30
  * (see neo4j-store.ts:171). Idempotent: subsequent runs no-op because
31
31
  * the WHERE clause matches zero rows.
32
32
  *
33
- * Run via the platform/ui standalone runtime so it picks up the same
34
- * NEO4J_URI / accounts-directory resolution as the server:
33
+ * Boot-time entry point (Task 871): {@link applyAdminAgentBackfill}. The
34
+ * neo4j-migrations runner calls it from `applyBootMigrations` AFTER
35
+ * `pruneAlienAccounts` so we never project :Agent for an account that the
36
+ * preceding pass would prune.
37
+ *
38
+ * Manual standalone entry point (legacy, retained for ad-hoc operator
39
+ * runs):
35
40
  *
36
41
  * cd platform/ui && \
37
42
  * NEO4J_URI=bolt://… NEO4J_PASSWORD=… \
38
43
  * npx tsx ../neo4j/migrations/004-project-admin-agent.ts
39
44
  *
40
45
  * Output: structured `[admin-agent-graph-backfill]` lines per account + a
41
- * final totals line. Non-zero exit code on any per-account agent-projection
42
- * failure surfaces to the operator; subsequent accounts are still attempted.
46
+ * final totals line. Both entry points emit identical log lines.
43
47
  */
44
48
 
45
49
  import { existsSync, readdirSync } from "node:fs";
@@ -47,6 +51,24 @@ import { resolve } from "node:path";
47
51
  import { projectAgent, getSession } from "../../ui/app/lib/neo4j-store";
48
52
  import { ACCOUNTS_DIR } from "../../ui/app/lib/claude-agent/account";
49
53
 
54
+ /**
55
+ * Structural alias for the `Driver` instance the runner passes in. Same
56
+ * rationale as `004-prune-alien-accounts.ts`: this file lives outside
57
+ * `platform/ui/`, and depending on the workspace's dedupe state,
58
+ * `neo4j-driver` resolves to a different node_modules copy here than at
59
+ * the boot-loader site. Structural typing sidesteps the nominal-distinct-
60
+ * types-from-different-paths trap.
61
+ */
62
+ type Neo4jDriverLike = {
63
+ session(): {
64
+ run(
65
+ cypher: string,
66
+ params?: Record<string, unknown>,
67
+ ): Promise<{ records: Array<{ get(key: string): unknown }> }>;
68
+ close(): Promise<void>;
69
+ };
70
+ };
71
+
50
72
  interface PerAccountStats {
51
73
  accountId: string;
52
74
  projected: 0 | 1;
@@ -94,9 +116,10 @@ interface HandledByStats {
94
116
  * are written — surfaced through `candidates - edges`.
95
117
  */
96
118
  async function backfillAdminHandledBy(
119
+ driver: Neo4jDriverLike,
97
120
  accountId: string,
98
121
  ): Promise<HandledByStats> {
99
- const session = getSession();
122
+ const session = driver.session();
100
123
  try {
101
124
  const result = await session.run(
102
125
  `MATCH (c:AdminConversation {accountId: $accountId})
@@ -137,8 +160,11 @@ async function backfillAdminHandledBy(
137
160
  *
138
161
  * Idempotent: WHERE clause matches zero rows on re-run.
139
162
  */
140
- async function backfillChannel(accountId: string): Promise<number> {
141
- const session = getSession();
163
+ async function backfillChannel(
164
+ driver: Neo4jDriverLike,
165
+ accountId: string,
166
+ ): Promise<number> {
167
+ const session = driver.session();
142
168
  try {
143
169
  const result = await session.run(
144
170
  `MATCH (c:Conversation {accountId: $accountId})
@@ -158,17 +184,32 @@ async function backfillChannel(accountId: string): Promise<number> {
158
184
  }
159
185
  }
160
186
 
161
- async function main(): Promise<void> {
187
+ /**
188
+ * Boot-time entry point (Task 871). Idempotent across every pass; safe to
189
+ * run on every server boot. Throws on fatal failure; per-account failures
190
+ * are logged and counted but do not abort the run (subsequent accounts
191
+ * still get processed). The neo4j-migrations runner wraps this in its own
192
+ * try/catch so a throw here is logged as `[migration] failed
193
+ * admin-agent-graph-backfill error="…"` and boot continues.
194
+ *
195
+ * Refusal posture: if `<platformRoot>/../data/accounts` does not exist,
196
+ * logs and returns silently — nothing to do (matches pruneAlienAccounts).
197
+ */
198
+ export async function applyAdminAgentBackfill(
199
+ driver: Neo4jDriverLike,
200
+ platformRoot: string,
201
+ ): Promise<void> {
202
+ const accountsDir = resolve(platformRoot, "..", "data", "accounts");
162
203
  const start = Date.now();
163
204
 
164
- if (!existsSync(ACCOUNTS_DIR)) {
205
+ if (!existsSync(accountsDir)) {
165
206
  console.error(
166
- `[admin-agent-graph-backfill] ACCOUNTS_DIR missing at ${ACCOUNTS_DIR} — nothing to do`,
207
+ `[admin-agent-graph-backfill] accounts-dir missing at ${accountsDir} — nothing to do`,
167
208
  );
168
- process.exit(0);
209
+ return;
169
210
  }
170
211
 
171
- const accountEntries = readdirSync(ACCOUNTS_DIR, { withFileTypes: true })
212
+ const accountEntries = readdirSync(accountsDir, { withFileTypes: true })
172
213
  .filter((e) => e.isDirectory());
173
214
 
174
215
  console.error(
@@ -183,7 +224,7 @@ async function main(): Promise<void> {
183
224
  const perAccount: PerAccountStats[] = [];
184
225
 
185
226
  for (const entry of accountEntries) {
186
- const accountDir = resolve(ACCOUNTS_DIR, entry.name);
227
+ const accountDir = resolve(accountsDir, entry.name);
187
228
  const accountId = entry.name;
188
229
  const accountStart = Date.now();
189
230
 
@@ -198,7 +239,7 @@ async function main(): Promise<void> {
198
239
  let channelBackfilled = 0;
199
240
 
200
241
  try {
201
- handledByStats = await backfillAdminHandledBy(accountId);
242
+ handledByStats = await backfillAdminHandledBy(driver, accountId);
202
243
  totalHandledByCandidates += handledByStats.candidates;
203
244
  totalHandledByEdges += handledByStats.edges;
204
245
  } catch (err) {
@@ -209,7 +250,7 @@ async function main(): Promise<void> {
209
250
  }
210
251
 
211
252
  try {
212
- channelBackfilled = await backfillChannel(accountId);
253
+ channelBackfilled = await backfillChannel(driver, accountId);
213
254
  totalChannelBackfilled += channelBackfilled;
214
255
  } catch (err) {
215
256
  const msg = err instanceof Error ? err.message : String(err);
@@ -236,12 +277,39 @@ async function main(): Promise<void> {
236
277
  console.error(
237
278
  `[admin-agent-graph-backfill] done totals: projected=${totalProjected} failed=${totalFailed} handled-by-candidates=${totalHandledByCandidates} handled-by-edges=${totalHandledByEdges} channel-backfilled=${totalChannelBackfilled} ms=${ms}`,
238
279
  );
280
+ }
239
281
 
240
- process.exit(totalFailed > 0 ? 1 : 0);
282
+ /**
283
+ * Standalone entry point — retained for manual `npx tsx` runs (Task 871
284
+ * preserved this so an operator can re-run the backfill ad-hoc without a
285
+ * full server boot). Wraps `applyAdminAgentBackfill` with a structural
286
+ * driver-shape that delegates to the neo4j-store singleton's getSession,
287
+ * so the env-var resolution (NEO4J_URI / NEO4J_PASSWORD / config file)
288
+ * matches the boot path exactly.
289
+ */
290
+ async function main(): Promise<void> {
291
+ if (!existsSync(ACCOUNTS_DIR)) {
292
+ console.error(
293
+ `[admin-agent-graph-backfill] ACCOUNTS_DIR missing at ${ACCOUNTS_DIR} — nothing to do`,
294
+ );
295
+ process.exit(0);
296
+ }
297
+ const driverShim: Neo4jDriverLike = { session: () => getSession() };
298
+ const platformRoot = resolve(ACCOUNTS_DIR, "..", "..", "platform");
299
+ try {
300
+ await applyAdminAgentBackfill(driverShim, platformRoot);
301
+ process.exit(0);
302
+ } catch (err) {
303
+ const msg = err instanceof Error ? err.message : String(err);
304
+ console.error(`[admin-agent-graph-backfill] fatal error="${msg}"`);
305
+ process.exit(2);
306
+ }
241
307
  }
242
308
 
243
- main().catch((err) => {
244
- const msg = err instanceof Error ? err.message : String(err);
245
- console.error(`[admin-agent-graph-backfill] fatal error="${msg}"`);
246
- process.exit(2);
247
- });
309
+ if (process.argv[1]?.endsWith("004-project-admin-agent.ts")) {
310
+ main().catch((err) => {
311
+ const msg = err instanceof Error ? err.message : String(err);
312
+ console.error(`[admin-agent-graph-backfill] fatal error="${msg}"`);
313
+ process.exit(2);
314
+ });
315
+ }