@rubytech/create-maxy 1.0.768 → 1.0.770

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/index.js CHANGED
@@ -1541,25 +1541,23 @@ function setupVncViewer() {
1541
1541
  }
1542
1542
  function setupAccount() {
1543
1543
  log("10", TOTAL, "Setting up...");
1544
+ // Tasks 787 + 788 — both seed-neo4j.sh and embed-backfill.sh hard-exit
1545
+ // without NEO4J_URI. The installer owns the brand-correct URI and password,
1546
+ // so we derive them once and pass to both call sites. Missing password file
1547
+ // is a hard error: ensureNeo4jPassword() ran upstream and would have thrown
1548
+ // already if it couldn't reach the brand's Neo4j.
1549
+ const passwordFile = join(INSTALL_DIR, "platform/config/.neo4j-password");
1550
+ if (!existsSync(passwordFile)) {
1551
+ throw new Error(`Neo4j password file missing at ${passwordFile} — required by setup step.`);
1552
+ }
1553
+ const password = readFileSync(passwordFile, "utf-8").trim();
1554
+ const neo4jUri = `bolt://localhost:${NEO4J_PORT}`;
1555
+ const neo4jEnv = { ...process.env, NEO4J_URI: neo4jUri, NEO4J_PASSWORD: password };
1544
1556
  const seedScript = join(INSTALL_DIR, "platform/scripts/seed-neo4j.sh");
1545
1557
  if (existsSync(seedScript)) {
1546
- // Task 787 — explicit env to seed. The script no longer falls back to
1547
- // bolt://localhost:7687, so the installer is responsible for naming the
1548
- // brand-correct URI and providing the password. Missing password file is
1549
- // a hard error: ensureNeo4jPassword() ran upstream and would have thrown
1550
- // already if it couldn't reach the brand's Neo4j.
1551
- const passwordFile = join(INSTALL_DIR, "platform/config/.neo4j-password");
1552
- if (!existsSync(passwordFile)) {
1553
- throw new Error(`Neo4j password file missing at ${passwordFile} — required by seed step.`);
1554
- }
1555
- const password = readFileSync(passwordFile, "utf-8").trim();
1556
- const neo4jUri = `bolt://localhost:${NEO4J_PORT}`;
1557
1558
  console.log(` [neo4j] passing NEO4J_URI=${neo4jUri} to seed`);
1558
1559
  logFile(` [neo4j] passing NEO4J_URI=${neo4jUri} to seed`);
1559
- shell("bash", [seedScript], {
1560
- cwd: INSTALL_DIR,
1561
- env: { ...process.env, NEO4J_URI: neo4jUri, NEO4J_PASSWORD: password },
1562
- });
1560
+ shell("bash", [seedScript], { cwd: INSTALL_DIR, env: neo4jEnv });
1563
1561
  }
1564
1562
  // Task 748 — universal embedding coverage backfill. Run after seed so the
1565
1563
  // entity_search index is in place and any pre-Task-748 nodes (e.g. the
@@ -1581,6 +1579,7 @@ function setupAccount() {
1581
1579
  stdio: "inherit",
1582
1580
  timeout: 30 * 60_000,
1583
1581
  cwd: INSTALL_DIR,
1582
+ env: neo4jEnv,
1584
1583
  });
1585
1584
  const dur = ((Date.now() - start) / 1000).toFixed(1);
1586
1585
  if (result.status !== 0 || result.signal) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.768",
3
+ "version": "1.0.770",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -5471,8 +5471,11 @@ app3.post("/", async (c) => {
5471
5471
  } else {
5472
5472
  message = body.message ?? "";
5473
5473
  }
5474
- if (!message || !session_key) {
5475
- return c.json({ error: "message and session_key required" }, 400);
5474
+ if (!session_key) {
5475
+ return c.json({ error: "session_key required" }, 400);
5476
+ }
5477
+ if (!message) {
5478
+ return c.json({ error: "message required" }, 400);
5476
5479
  }
5477
5480
  if (!validateSession(session_key, "public")) {
5478
5481
  return c.json({ error: "Invalid or expired session" }, 401);
@@ -8156,10 +8159,10 @@ app11.post("/", requireAdminSession, async (c) => {
8156
8159
  }
8157
8160
  message = formData.get("message") ?? "";
8158
8161
  userTimestamp = formData.get("timestamp") || void 0;
8159
- if (!message) {
8160
- return chatReject(400, "message and session_key required", session_key);
8161
- }
8162
8162
  const files = formData.getAll("attachments");
8163
+ if (!message && files.length === 0) {
8164
+ return chatReject(400, "message required", session_key);
8165
+ }
8163
8166
  if (files.length > MAX_FILES_PER_MESSAGE) {
8164
8167
  return chatReject(422, `Maximum ${MAX_FILES_PER_MESSAGE} files per message.`, session_key);
8165
8168
  }
@@ -8199,6 +8202,10 @@ app11.post("/", requireAdminSession, async (c) => {
8199
8202
  return chatReject(422, err instanceof Error ? err.message : "File storage failed", session_key);
8200
8203
  }
8201
8204
  }
8205
+ if (!message && storedAttachments.length > 0) {
8206
+ const names = storedAttachments.map((a) => a.filename.replace(/[\[\]\r\n]/g, "_")).join(", ");
8207
+ message = `[attachments: ${names}]`;
8208
+ }
8202
8209
  } else {
8203
8210
  let body;
8204
8211
  try {
@@ -8211,7 +8218,7 @@ app11.post("/", requireAdminSession, async (c) => {
8211
8218
  topicChangeAction = body.topicChangeAction;
8212
8219
  heldMessage = body.heldMessage;
8213
8220
  if (!message) {
8214
- return chatReject(400, "message and session_key required", session_key);
8221
+ return chatReject(400, "message required", session_key);
8215
8222
  }
8216
8223
  }
8217
8224
  try {