@rubytech/create-maxy-code 0.1.442 → 0.1.443

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 (37) hide show
  1. package/dist/__tests__/converge-client-admins.test.js +50 -0
  2. package/dist/converge-client-admins.js +67 -0
  3. package/dist/index.js +8 -0
  4. package/package.json +1 -1
  5. package/payload/platform/docs/superpowers/plans/2026-07-13-account-schema-ontology-projection.md +547 -0
  6. package/payload/platform/docs/superpowers/plans/2026-07-14-graph-top-level-labels-ontology-single-source.md +458 -0
  7. package/payload/platform/docs/superpowers/specs/2026-07-13-account-schema-ontology-projection-design.md +178 -0
  8. package/payload/platform/docs/superpowers/specs/2026-07-14-graph-top-level-labels-ontology-single-source-design.md +119 -0
  9. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  10. package/payload/platform/plugins/admin/PLUGIN.md +7 -1
  11. package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh +19 -2
  12. package/payload/platform/plugins/admin/mcp/dist/index.js +126 -1
  13. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  14. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts +30 -0
  15. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts.map +1 -1
  16. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js +78 -0
  17. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js.map +1 -1
  18. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
  19. package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
  20. package/payload/platform/plugins/memory/PLUGIN.md +2 -0
  21. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/resolve-active-vertical.test.js +12 -0
  22. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/resolve-active-vertical.test.js.map +1 -1
  23. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-active-vertical.d.ts +9 -1
  24. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-active-vertical.d.ts.map +1 -1
  25. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-active-vertical.js +19 -2
  26. package/payload/platform/plugins/memory/mcp/dist/lib/resolve-active-vertical.js.map +1 -1
  27. package/payload/platform/plugins/memory/references/schema-estate-agent.md +8 -3
  28. package/payload/platform/scripts/__tests__/account-schema-owned-dirs.test.sh +58 -0
  29. package/payload/platform/scripts/__tests__/provision-role-stamp.test.sh +6 -0
  30. package/payload/platform/scripts/lib/account-schema-owned-dirs.py +143 -10
  31. package/payload/platform/scripts/lib/provision-account-dir.sh +5 -0
  32. package/payload/platform/scripts/name-glsmith-owner.sh +239 -0
  33. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
  35. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  36. package/payload/server/server.js +341 -169
  37. package/payload/platform/plugins/memory/references/schema-trades.md +0 -34
@@ -0,0 +1,50 @@
1
+ // Task 1623 — acceptance for the installer convergence that drops the vestigial
2
+ // admins[] key from existing client account.json. Filesystem fixtures under a
3
+ // tmp dir; no installer side effects. Runs under `node --test dist/__tests__/*`.
4
+ import test from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from "node:fs";
7
+ import { tmpdir } from "node:os";
8
+ import { join } from "node:path";
9
+ import { removeClientAdminsKey } from "../converge-client-admins.js";
10
+ function makeRoot() {
11
+ return mkdtempSync(join(tmpdir(), "conv-1623-"));
12
+ }
13
+ function acct(root, id, cfg) {
14
+ mkdirSync(join(root, id), { recursive: true });
15
+ writeFileSync(join(root, id, "account.json"), JSON.stringify(cfg, null, 2));
16
+ }
17
+ function hasAdmins(root, id) {
18
+ return "admins" in JSON.parse(readFileSync(join(root, id, "account.json"), "utf-8"));
19
+ }
20
+ test("removes admins from a client, keeps it on the house, is idempotent", () => {
21
+ const root = makeRoot();
22
+ try {
23
+ acct(root, "c1", { accountId: "c1", role: "client", admins: [] });
24
+ acct(root, "h1", { accountId: "h1", role: "house", admins: [{ userId: "u1", role: "owner" }] });
25
+ acct(root, "c2", { accountId: "c2", role: "client" }); // already stripped
26
+ const first = removeClientAdminsKey(root);
27
+ assert.equal(first.find((r) => r.accountId === "c1")?.action, "removed");
28
+ assert.equal(first.find((r) => r.accountId === "h1")?.action, "house-kept");
29
+ assert.equal(first.find((r) => r.accountId === "c2")?.action, "absent");
30
+ assert.equal(hasAdmins(root, "c1"), false);
31
+ assert.equal(hasAdmins(root, "h1"), true);
32
+ const second = removeClientAdminsKey(root);
33
+ assert.equal(second.find((r) => r.accountId === "c1")?.action, "absent");
34
+ }
35
+ finally {
36
+ rmSync(root, { recursive: true, force: true });
37
+ }
38
+ });
39
+ test("unreadable account.json is reported, not thrown", () => {
40
+ const root = makeRoot();
41
+ try {
42
+ mkdirSync(join(root, "bad"), { recursive: true });
43
+ writeFileSync(join(root, "bad", "account.json"), "{ not json");
44
+ const res = removeClientAdminsKey(root);
45
+ assert.equal(res.find((r) => r.accountId === "bad")?.action, "unreadable");
46
+ }
47
+ finally {
48
+ rmSync(root, { recursive: true, force: true });
49
+ }
50
+ });
@@ -0,0 +1,67 @@
1
+ // Task 1623 — installer convergence. A client sub-account never carries admins[]
2
+ // (Task 999 retired the seats, Task 1596 the inbound read). This removes the
3
+ // vestigial key from every existing role:'client' account.json on each install,
4
+ // reaching all installs and brands without a per-box script. The house keeps its
5
+ // admins[] (the real install-wide access surface). Atomic temp-write + rename,
6
+ // idempotent, one auditable line per file; contents are never echoed.
7
+ import { existsSync, readdirSync, readFileSync, writeFileSync, renameSync, statSync, rmSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ export function removeClientAdminsKey(accountsDir) {
10
+ const out = [];
11
+ let entries = [];
12
+ try {
13
+ entries = readdirSync(accountsDir);
14
+ }
15
+ catch {
16
+ return out;
17
+ }
18
+ for (const entry of entries) {
19
+ if (entry.startsWith("."))
20
+ continue;
21
+ const dir = join(accountsDir, entry);
22
+ try {
23
+ if (!statSync(dir).isDirectory())
24
+ continue;
25
+ }
26
+ catch {
27
+ continue;
28
+ }
29
+ const cfgPath = join(dir, "account.json");
30
+ if (!existsSync(cfgPath))
31
+ continue;
32
+ let cfg;
33
+ try {
34
+ cfg = JSON.parse(readFileSync(cfgPath, "utf-8"));
35
+ }
36
+ catch {
37
+ out.push({ accountId: entry, action: "unreadable" });
38
+ continue;
39
+ }
40
+ if (cfg.role === "house") {
41
+ out.push({ accountId: entry, action: "house-kept" });
42
+ continue;
43
+ }
44
+ if (cfg.role !== "client" || !("admins" in cfg)) {
45
+ out.push({ accountId: entry, action: "absent" });
46
+ continue;
47
+ }
48
+ delete cfg.admins;
49
+ const tmp = `${cfgPath}.1623.tmp`;
50
+ try {
51
+ writeFileSync(tmp, JSON.stringify(cfg, null, 2) + "\n");
52
+ renameSync(tmp, cfgPath);
53
+ out.push({ accountId: entry, action: "removed" });
54
+ }
55
+ catch {
56
+ // A write/rename failure (full disk, permissions, file changed under us):
57
+ // remove any half-written temp so no .1623.tmp is orphaned, and label it
58
+ // write-failed (the file was readable — "unreadable" would misdescribe it).
59
+ try {
60
+ rmSync(tmp, { force: true });
61
+ }
62
+ catch { /* best-effort cleanup */ }
63
+ out.push({ accountId: entry, action: "write-failed" });
64
+ }
65
+ }
66
+ return out;
67
+ }
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { buildHeartbeatCronBlock, mergeHeartbeatBlock } from "./cron-registratio
10
10
  import { validateTierFlag, validateEntitlementBase64, applyTierToAccountConfig, entitlementPath } from "./tier-flag.js";
11
11
  import { parseOsRelease, isUbuntuLike as isUbuntuLikePure, parseAptCacheCandidate, decideAptResolution, } from "./apt-resolve.js";
12
12
  import { findPeerBrandOnDefaultNeo4jPort } from "./peer-brand-detect.js";
13
+ import { removeClientAdminsKey } from "./converge-client-admins.js";
13
14
  import { resolveNeo4jPidfileScrub } from "./neo4j-pidfile-scrub.js";
14
15
  import { runInitLogging } from "./init-logging.js";
15
16
  import { requireSupportedPlatform, detectPlatform } from "./platform-detect.js";
@@ -2574,6 +2575,13 @@ function deployPayload() {
2574
2575
  // installer is its own npm package and doesn't bundle the platform lib.
2575
2576
  // Mirrors checkAdminAuthInvariant() in platform/lib/admins-write/src/index.ts;
2576
2577
  // future divergence between the two should be caught by the test suite.
2578
+ // Task 1623 — converge existing client account.json to drop the vestigial
2579
+ // admins[] key before the invariant check reads them. House untouched.
2580
+ for (const r of removeClientAdminsKey(join(INSTALL_DIR, "data", "accounts"))) {
2581
+ if (r.action === "removed" || r.action === "unreadable" || r.action === "write-failed") {
2582
+ console.log(` [converge-1623] account=${r.accountId.slice(0, 8)} admins=${r.action}`);
2583
+ }
2584
+ }
2577
2585
  runInstallInvariantCheck(persistentUsersFile, join(INSTALL_DIR, "data", "accounts"));
2578
2586
  // The version marker is NOT written here. It is stamped at the very end of a
2579
2587
  // fully-successful install (after plugin registration and every throwing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy-code",
3
- "version": "0.1.442",
3
+ "version": "0.1.443",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy-code": "./dist/index.js"