everything-dev 1.49.0 → 1.51.0

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 (145) hide show
  1. package/dist/app.cjs +66 -86
  2. package/dist/app.cjs.map +1 -1
  3. package/dist/app.mjs +66 -87
  4. package/dist/app.mjs.map +1 -1
  5. package/dist/cli/db-doctor.cjs +6 -23
  6. package/dist/cli/db-doctor.cjs.map +1 -1
  7. package/dist/cli/db-doctor.mjs +7 -24
  8. package/dist/cli/db-doctor.mjs.map +1 -1
  9. package/dist/cli/db-repair.cjs +25 -20
  10. package/dist/cli/db-repair.cjs.map +1 -1
  11. package/dist/cli/db-repair.mjs +25 -20
  12. package/dist/cli/db-repair.mjs.map +1 -1
  13. package/dist/cli/db-studio.cjs +4 -2
  14. package/dist/cli/db-studio.cjs.map +1 -1
  15. package/dist/cli/db-studio.mjs +5 -3
  16. package/dist/cli/db-studio.mjs.map +1 -1
  17. package/dist/cli/framework-version.cjs +45 -9
  18. package/dist/cli/framework-version.cjs.map +1 -1
  19. package/dist/cli/framework-version.mjs +45 -10
  20. package/dist/cli/framework-version.mjs.map +1 -1
  21. package/dist/cli/infra.cjs +89 -3
  22. package/dist/cli/infra.cjs.map +1 -1
  23. package/dist/cli/infra.mjs +83 -4
  24. package/dist/cli/infra.mjs.map +1 -1
  25. package/dist/cli/init.cjs +39 -15
  26. package/dist/cli/init.cjs.map +1 -1
  27. package/dist/cli/init.d.cts +8 -3
  28. package/dist/cli/init.d.cts.map +1 -1
  29. package/dist/cli/init.d.mts +8 -3
  30. package/dist/cli/init.d.mts.map +1 -1
  31. package/dist/cli/init.mjs +39 -16
  32. package/dist/cli/init.mjs.map +1 -1
  33. package/dist/cli/parse.cjs +4 -1
  34. package/dist/cli/parse.cjs.map +1 -1
  35. package/dist/cli/parse.mjs +4 -1
  36. package/dist/cli/parse.mjs.map +1 -1
  37. package/dist/cli/status.cjs +6 -2
  38. package/dist/cli/status.cjs.map +1 -1
  39. package/dist/cli/status.mjs +7 -3
  40. package/dist/cli/status.mjs.map +1 -1
  41. package/dist/cli/sync.cjs +9 -3
  42. package/dist/cli/sync.cjs.map +1 -1
  43. package/dist/cli/sync.mjs +9 -3
  44. package/dist/cli/sync.mjs.map +1 -1
  45. package/dist/cli/upgrade.cjs +59 -5
  46. package/dist/cli/upgrade.cjs.map +1 -1
  47. package/dist/cli/upgrade.mjs +59 -5
  48. package/dist/cli/upgrade.mjs.map +1 -1
  49. package/dist/cli.cjs +73 -9
  50. package/dist/cli.cjs.map +1 -1
  51. package/dist/cli.mjs +74 -10
  52. package/dist/cli.mjs.map +1 -1
  53. package/dist/config.cjs +13 -5
  54. package/dist/config.cjs.map +1 -1
  55. package/dist/config.d.cts.map +1 -1
  56. package/dist/config.d.mts.map +1 -1
  57. package/dist/config.mjs +13 -5
  58. package/dist/config.mjs.map +1 -1
  59. package/dist/contract.cjs +76 -4
  60. package/dist/contract.cjs.map +1 -1
  61. package/dist/contract.d.cts +148 -3
  62. package/dist/contract.d.cts.map +1 -1
  63. package/dist/contract.d.mts +148 -3
  64. package/dist/contract.d.mts.map +1 -1
  65. package/dist/contract.meta.cjs +17 -2
  66. package/dist/contract.meta.cjs.map +1 -1
  67. package/dist/contract.meta.d.cts +23 -2
  68. package/dist/contract.meta.d.mts +23 -2
  69. package/dist/contract.meta.mjs +17 -2
  70. package/dist/contract.meta.mjs.map +1 -1
  71. package/dist/contract.mjs +72 -5
  72. package/dist/contract.mjs.map +1 -1
  73. package/dist/db.cjs +32 -24
  74. package/dist/db.cjs.map +1 -1
  75. package/dist/db.d.cts +16 -9
  76. package/dist/db.d.cts.map +1 -1
  77. package/dist/db.d.mts +16 -9
  78. package/dist/db.d.mts.map +1 -1
  79. package/dist/db.mjs +32 -23
  80. package/dist/db.mjs.map +1 -1
  81. package/dist/dev-session.cjs +28 -0
  82. package/dist/dev-session.cjs.map +1 -1
  83. package/dist/dev-session.mjs +29 -1
  84. package/dist/dev-session.mjs.map +1 -1
  85. package/dist/index.cjs +5 -0
  86. package/dist/index.d.cts +2 -2
  87. package/dist/index.d.mts +2 -2
  88. package/dist/index.mjs +2 -2
  89. package/dist/infra/planner.cjs +344 -0
  90. package/dist/infra/planner.cjs.map +1 -0
  91. package/dist/infra/planner.mjs +343 -0
  92. package/dist/infra/planner.mjs.map +1 -0
  93. package/dist/infra/preflight.cjs +131 -0
  94. package/dist/infra/preflight.cjs.map +1 -0
  95. package/dist/infra/preflight.mjs +130 -0
  96. package/dist/infra/preflight.mjs.map +1 -0
  97. package/dist/infra/types.cjs +9 -0
  98. package/dist/infra/types.cjs.map +1 -0
  99. package/dist/infra/types.mjs +8 -0
  100. package/dist/infra/types.mjs.map +1 -0
  101. package/dist/near-cli.cjs +37 -0
  102. package/dist/near-cli.cjs.map +1 -1
  103. package/dist/near-cli.mjs +36 -1
  104. package/dist/near-cli.mjs.map +1 -1
  105. package/dist/orchestrator.cjs +10 -2
  106. package/dist/orchestrator.cjs.map +1 -1
  107. package/dist/orchestrator.mjs +10 -2
  108. package/dist/orchestrator.mjs.map +1 -1
  109. package/dist/plugin.cjs +161 -44
  110. package/dist/plugin.cjs.map +1 -1
  111. package/dist/plugin.d.cts +57 -1
  112. package/dist/plugin.d.cts.map +1 -1
  113. package/dist/plugin.d.mts +57 -1
  114. package/dist/plugin.d.mts.map +1 -1
  115. package/dist/plugin.mjs +165 -48
  116. package/dist/plugin.mjs.map +1 -1
  117. package/dist/process-registry.cjs +88 -0
  118. package/dist/process-registry.cjs.map +1 -0
  119. package/dist/process-registry.mjs +83 -0
  120. package/dist/process-registry.mjs.map +1 -0
  121. package/dist/publish.cjs +4 -0
  122. package/dist/publish.cjs.map +1 -1
  123. package/dist/publish.mjs +4 -0
  124. package/dist/publish.mjs.map +1 -1
  125. package/dist/service-descriptor.cjs +4 -0
  126. package/dist/service-descriptor.cjs.map +1 -1
  127. package/dist/service-descriptor.mjs +4 -1
  128. package/dist/service-descriptor.mjs.map +1 -1
  129. package/dist/ui/index.cjs +2 -1
  130. package/dist/ui/index.d.cts +2 -2
  131. package/dist/ui/index.d.mts +2 -2
  132. package/dist/ui/index.mjs +2 -2
  133. package/dist/ui/router.cjs +40 -0
  134. package/dist/ui/router.cjs.map +1 -1
  135. package/dist/ui/router.d.cts +6 -1
  136. package/dist/ui/router.d.cts.map +1 -1
  137. package/dist/ui/router.d.mts +6 -1
  138. package/dist/ui/router.d.mts.map +1 -1
  139. package/dist/ui/router.mjs +40 -1
  140. package/dist/ui/router.mjs.map +1 -1
  141. package/package.json +5 -2
  142. package/skills/api-and-auth/SKILL.md +38 -16
  143. package/skills/cli-reference/SKILL.md +5 -4
  144. package/skills/dev-workflow/SKILL.md +40 -11
  145. package/skills/plugin-development/SKILL.md +17 -6
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.mts","names":[],"sources":["../../src/ui/router.ts"],"mappings":";;;;iBAGgB,UAAA,CAAW,IAAA,EAAM,QAAA;AAAA,iBAcjB,UAAA,CAAW,IAAA,EAAM,QAAA;AAAA,iBAMjB,YAAA,CAAa,MAAA,EAAQ,UAAA;AAAA,iBASf,eAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,OAAA,CAAQ,QAAA"}
1
+ {"version":3,"file":"router.d.mts","names":[],"sources":["../../src/ui/router.ts"],"mappings":";;;;iBAGgB,UAAA,CAAW,IAAA,EAAM,QAAA;AAAA,iBAcjB,UAAA,CAAW,IAAA,EAAM,QAAA;AAAA,iBAMjB,YAAA,CAAa,MAAA,EAAQ,UAAA;AAAA,iBASf,eAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,OAAA,CAAQ,QAAA;AAAA,iBA0GlD,iBAAA,CACd,QAAA,EAAU,QAAA,EACV,QAAA;EACG,QAAA;EAAkB,QAAA;EAAkB,UAAA;AAAA"}
@@ -45,7 +45,46 @@ async function collectHeadData(router) {
45
45
  scripts: [...scriptMap.values()]
46
46
  };
47
47
  }
48
+ function escapeHtml(s) {
49
+ return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
50
+ }
51
+ function serializeMeta(meta) {
52
+ if (!meta) return "";
53
+ if ("charSet" in meta) return `<meta charset="${escapeHtml(String(meta.charSet))}">`;
54
+ if ("title" in meta) return `<title>${escapeHtml(String(meta.title))}</title>`;
55
+ return `<meta ${Object.entries(meta).filter(([, v]) => v != null).map(([k, v]) => `${k}="${escapeHtml(String(v))}"`).join(" ")}>`;
56
+ }
57
+ function serializeLink(link) {
58
+ if (!link) return "";
59
+ return `<link ${Object.entries(link).filter(([, v]) => v != null).map(([k, v]) => `${k}="${escapeHtml(String(v))}"`).join(" ")}>`;
60
+ }
61
+ function serializeScript(script, cspNonce) {
62
+ if (!script) return "";
63
+ if ("src" in script && script.src) {
64
+ const attrs = [`src="${escapeHtml(script.src)}"`];
65
+ if (script.integrity) attrs.push(`integrity="${escapeHtml(script.integrity)}"`);
66
+ if (script.crossOrigin) attrs.push(`crossorigin="${escapeHtml(script.crossOrigin)}"`);
67
+ if (script.type) attrs.push(`type="${escapeHtml(script.type)}"`);
68
+ if (cspNonce) attrs.push(`nonce="${cspNonce}"`);
69
+ return `<script ${attrs.join(" ")}><\/script>`;
70
+ }
71
+ if ("children" in script) {
72
+ const attrs = [];
73
+ if (script.type) attrs.push(`type="${escapeHtml(script.type)}"`);
74
+ if (cspNonce) attrs.push(`nonce="${cspNonce}"`);
75
+ const content = typeof script.children === "string" ? script.children : JSON.stringify(script.children);
76
+ return `<script${attrs.length ? ` ${attrs.join(" ")}` : ""}>${content}<\/script>`;
77
+ }
78
+ return "";
79
+ }
80
+ function serializeHeadData(headData, cspNonce) {
81
+ return {
82
+ metaHtml: headData.meta.filter(Boolean).map((m) => serializeMeta(m)).join("\n"),
83
+ linkHtml: headData.links.filter(Boolean).map((l) => serializeLink(l)).join("\n"),
84
+ scriptHtml: headData.scripts.filter(Boolean).map((s) => serializeScript(s, cspNonce)).join("\n")
85
+ };
86
+ }
48
87
 
49
88
  //#endregion
50
- export { collectHeadData, getLinkKey, getMetaKey, getScriptKey };
89
+ export { collectHeadData, getLinkKey, getMetaKey, getScriptKey, serializeHeadData };
51
90
  //# sourceMappingURL=router.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.mjs","names":[],"sources":["../../src/ui/router.ts"],"sourcesContent":["import type { AnyRouter } from \"@tanstack/react-router\";\nimport type { HeadData, HeadLink, HeadMeta, HeadScript } from \"./types\";\n\nexport function getMetaKey(meta: HeadMeta): string {\n if (!meta) return \"null\";\n if (\"title\" in meta) return \"title\";\n if (\"charSet\" in meta) return \"charSet\";\n if (\"name\" in meta) return `name:${(meta as { name: string }).name}`;\n if (\"property\" in meta) {\n return `property:${(meta as { property: string }).property}`;\n }\n if (\"httpEquiv\" in meta) {\n return `httpEquiv:${(meta as { httpEquiv: string }).httpEquiv}`;\n }\n return JSON.stringify(meta);\n}\n\nexport function getLinkKey(link: HeadLink): string {\n const rel = (link as { rel?: string }).rel ?? \"\";\n const href = (link as { href?: string }).href ?? \"\";\n return `${rel}:${href}`;\n}\n\nexport function getScriptKey(script: HeadScript): string {\n if (!script) return \"null\";\n if (\"src\" in script && script.src) return `src:${script.src}`;\n if (\"children\" in script && script.children) {\n return `children:${typeof script.children === \"string\" ? script.children : JSON.stringify(script.children)}`;\n }\n return JSON.stringify(script);\n}\n\nexport async function collectHeadData(router: AnyRouter): Promise<HeadData> {\n await router.load();\n\n const metaMap = new Map<string, HeadMeta>();\n const linkMap = new Map<string, HeadLink>();\n const scriptMap = new Map<string, HeadScript>();\n\n for (const match of router.state.matches) {\n const route =\n (\n router as AnyRouter & {\n routesById?: Record<string, { options?: { head?: (...args: unknown[]) => unknown } }>;\n }\n ).routesById?.[(match as { routeId: string }).routeId] ??\n (match as { route?: { options?: { head?: (...args: unknown[]) => unknown } } }).route;\n const headFn = route?.options?.head;\n if (!headFn) continue;\n\n try {\n const headResult = (await headFn({\n loaderData: match.loaderData,\n matches: router.state.matches,\n match,\n params: match.params,\n })) as {\n meta?: HeadMeta[];\n links?: HeadLink[];\n scripts?: HeadScript[];\n };\n\n if (headResult?.meta) {\n for (const meta of headResult.meta) {\n metaMap.set(getMetaKey(meta), meta);\n }\n }\n if (headResult?.links) {\n for (const link of headResult.links) {\n linkMap.set(getLinkKey(link), link);\n }\n }\n if (headResult?.scripts) {\n for (const script of headResult.scripts) {\n scriptMap.set(getScriptKey(script), script);\n }\n }\n } catch (error) {\n console.warn(`[collectHeadData] head() failed for ${match.routeId}:`, error);\n }\n }\n\n return {\n meta: [...metaMap.values()],\n links: [...linkMap.values()],\n scripts: [...scriptMap.values()],\n };\n}\n"],"mappings":";AAGA,SAAgB,WAAW,MAAwB;AACjD,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,WAAW,KAAM,QAAO;AAC5B,KAAI,aAAa,KAAM,QAAO;AAC9B,KAAI,UAAU,KAAM,QAAO,QAAS,KAA0B;AAC9D,KAAI,cAAc,KAChB,QAAO,YAAa,KAA8B;AAEpD,KAAI,eAAe,KACjB,QAAO,aAAc,KAA+B;AAEtD,QAAO,KAAK,UAAU,KAAK;;AAG7B,SAAgB,WAAW,MAAwB;AAGjD,QAAO,GAFM,KAA0B,OAAO,GAEhC,GADA,KAA2B,QAAQ;;AAInD,SAAgB,aAAa,QAA4B;AACvD,KAAI,CAAC,OAAQ,QAAO;AACpB,KAAI,SAAS,UAAU,OAAO,IAAK,QAAO,OAAO,OAAO;AACxD,KAAI,cAAc,UAAU,OAAO,SACjC,QAAO,YAAY,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW,KAAK,UAAU,OAAO,SAAS;AAE5G,QAAO,KAAK,UAAU,OAAO;;AAG/B,eAAsB,gBAAgB,QAAsC;AAC1E,OAAM,OAAO,MAAM;CAEnB,MAAM,0BAAU,IAAI,KAAuB;CAC3C,MAAM,0BAAU,IAAI,KAAuB;CAC3C,MAAM,4BAAY,IAAI,KAAyB;AAE/C,MAAK,MAAM,SAAS,OAAO,MAAM,SAAS;EAQxC,MAAM,UALF,OAGA,aAAc,MAA8B,YAC7C,MAA+E,QAC5D,SAAS;AAC/B,MAAI,CAAC,OAAQ;AAEb,MAAI;GACF,MAAM,aAAc,MAAM,OAAO;IAC/B,YAAY,MAAM;IAClB,SAAS,OAAO,MAAM;IACtB;IACA,QAAQ,MAAM;IACf,CAAC;AAMF,OAAI,YAAY,KACd,MAAK,MAAM,QAAQ,WAAW,KAC5B,SAAQ,IAAI,WAAW,KAAK,EAAE,KAAK;AAGvC,OAAI,YAAY,MACd,MAAK,MAAM,QAAQ,WAAW,MAC5B,SAAQ,IAAI,WAAW,KAAK,EAAE,KAAK;AAGvC,OAAI,YAAY,QACd,MAAK,MAAM,UAAU,WAAW,QAC9B,WAAU,IAAI,aAAa,OAAO,EAAE,OAAO;WAGxC,OAAO;AACd,WAAQ,KAAK,uCAAuC,MAAM,QAAQ,IAAI,MAAM;;;AAIhF,QAAO;EACL,MAAM,CAAC,GAAG,QAAQ,QAAQ,CAAC;EAC3B,OAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC;EAC5B,SAAS,CAAC,GAAG,UAAU,QAAQ,CAAC;EACjC"}
1
+ {"version":3,"file":"router.mjs","names":[],"sources":["../../src/ui/router.ts"],"sourcesContent":["import type { AnyRouter } from \"@tanstack/react-router\";\nimport type { HeadData, HeadLink, HeadMeta, HeadScript } from \"./types\";\n\nexport function getMetaKey(meta: HeadMeta): string {\n if (!meta) return \"null\";\n if (\"title\" in meta) return \"title\";\n if (\"charSet\" in meta) return \"charSet\";\n if (\"name\" in meta) return `name:${(meta as { name: string }).name}`;\n if (\"property\" in meta) {\n return `property:${(meta as { property: string }).property}`;\n }\n if (\"httpEquiv\" in meta) {\n return `httpEquiv:${(meta as { httpEquiv: string }).httpEquiv}`;\n }\n return JSON.stringify(meta);\n}\n\nexport function getLinkKey(link: HeadLink): string {\n const rel = (link as { rel?: string }).rel ?? \"\";\n const href = (link as { href?: string }).href ?? \"\";\n return `${rel}:${href}`;\n}\n\nexport function getScriptKey(script: HeadScript): string {\n if (!script) return \"null\";\n if (\"src\" in script && script.src) return `src:${script.src}`;\n if (\"children\" in script && script.children) {\n return `children:${typeof script.children === \"string\" ? script.children : JSON.stringify(script.children)}`;\n }\n return JSON.stringify(script);\n}\n\nexport async function collectHeadData(router: AnyRouter): Promise<HeadData> {\n await router.load();\n\n const metaMap = new Map<string, HeadMeta>();\n const linkMap = new Map<string, HeadLink>();\n const scriptMap = new Map<string, HeadScript>();\n\n for (const match of router.state.matches) {\n const route =\n (\n router as AnyRouter & {\n routesById?: Record<string, { options?: { head?: (...args: unknown[]) => unknown } }>;\n }\n ).routesById?.[(match as { routeId: string }).routeId] ??\n (match as { route?: { options?: { head?: (...args: unknown[]) => unknown } } }).route;\n const headFn = route?.options?.head;\n if (!headFn) continue;\n\n try {\n const headResult = (await headFn({\n loaderData: match.loaderData,\n matches: router.state.matches,\n match,\n params: match.params,\n })) as {\n meta?: HeadMeta[];\n links?: HeadLink[];\n scripts?: HeadScript[];\n };\n\n if (headResult?.meta) {\n for (const meta of headResult.meta) {\n metaMap.set(getMetaKey(meta), meta);\n }\n }\n if (headResult?.links) {\n for (const link of headResult.links) {\n linkMap.set(getLinkKey(link), link);\n }\n }\n if (headResult?.scripts) {\n for (const script of headResult.scripts) {\n scriptMap.set(getScriptKey(script), script);\n }\n }\n } catch (error) {\n console.warn(`[collectHeadData] head() failed for ${match.routeId}:`, error);\n }\n }\n\n return {\n meta: [...metaMap.values()],\n links: [...linkMap.values()],\n scripts: [...scriptMap.values()],\n };\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\nfunction serializeMeta(meta: HeadMeta): string {\n if (!meta) return \"\";\n if (\"charSet\" in meta) return `<meta charset=\"${escapeHtml(String(meta.charSet))}\">`;\n if (\"title\" in meta) return `<title>${escapeHtml(String(meta.title))}</title>`;\n const attrs = Object.entries(meta as Record<string, unknown>)\n .filter(([, v]) => v != null)\n .map(([k, v]) => `${k}=\"${escapeHtml(String(v))}\"`)\n .join(\" \");\n return `<meta ${attrs}>`;\n}\n\nfunction serializeLink(link: HeadLink): string {\n if (!link) return \"\";\n const attrs = Object.entries(link as Record<string, unknown>)\n .filter(([, v]) => v != null)\n .map(([k, v]) => `${k}=\"${escapeHtml(String(v))}\"`)\n .join(\" \");\n return `<link ${attrs}>`;\n}\n\nfunction serializeScript(script: HeadScript, cspNonce?: string): string {\n if (!script) return \"\";\n if (\"src\" in script && script.src) {\n const attrs: string[] = [`src=\"${escapeHtml(script.src)}\"`];\n if (script.integrity) attrs.push(`integrity=\"${escapeHtml(script.integrity)}\"`);\n if (script.crossOrigin) attrs.push(`crossorigin=\"${escapeHtml(script.crossOrigin)}\"`);\n if (script.type) attrs.push(`type=\"${escapeHtml(script.type)}\"`);\n if (cspNonce) attrs.push(`nonce=\"${cspNonce}\"`);\n return `<script ${attrs.join(\" \")}></script>`;\n }\n if (\"children\" in script) {\n const attrs: string[] = [];\n if (script.type) attrs.push(`type=\"${escapeHtml(script.type)}\"`);\n if (cspNonce) attrs.push(`nonce=\"${cspNonce}\"`);\n const content =\n typeof script.children === \"string\" ? script.children : JSON.stringify(script.children);\n return `<script${attrs.length ? ` ${attrs.join(\" \")}` : \"\"}>${content}</script>`;\n }\n return \"\";\n}\n\nexport function serializeHeadData(\n headData: HeadData,\n cspNonce?: string,\n): { metaHtml: string; linkHtml: string; scriptHtml: string } {\n return {\n metaHtml: headData.meta\n .filter(Boolean)\n .map((m) => serializeMeta(m))\n .join(\"\\n\"),\n linkHtml: headData.links\n .filter(Boolean)\n .map((l) => serializeLink(l))\n .join(\"\\n\"),\n scriptHtml: headData.scripts\n .filter(Boolean)\n .map((s) => serializeScript(s, cspNonce))\n .join(\"\\n\"),\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "everything-dev",
3
- "version": "1.49.0",
3
+ "version": "1.51.0",
4
4
  "type": "module",
5
+ "engines": {
6
+ "node": ">=20.11"
7
+ },
5
8
  "publishConfig": {
6
9
  "access": "public"
7
10
  },
@@ -137,7 +140,7 @@
137
140
  "dotenv": "^17.3.1",
138
141
  "effect": "^3.21.0",
139
142
  "execa": "^9.5.2",
140
- "every-plugin": "^2.9.1",
143
+ "every-plugin": "^2.9.2",
141
144
  "glob": "^13.0.6",
142
145
  "gradient-string": "^3.0.0",
143
146
  "ink": "^6.8.0",
@@ -17,17 +17,22 @@ export default createPlugin.withPlugins<PluginsClient>()({
17
17
  secrets: z.object({ /* typed env vars, defaults for dev */ }),
18
18
  context: z.object({ /* per-request context injected by host */ }),
19
19
  contract,
20
- initialize: (config, plugins) => Effect.promise(async () => {
21
- return { db, upvoteService, publisher, auth, plugins };
22
- }),
23
- shutdown: (services) => Effect.promise(async () => { /* cleanup */ }),
24
- createRouter: (services, builder) => ({
20
+ initialize: (config, plugins, tools) =>
21
+ Effect.gen(function* () {
22
+ const registry = yield* tools.buildService(
23
+ RegistryTag,
24
+ RegistryLive.pipe(Layer.provide(DatabaseLive(config.secrets.API_DATABASE_URL))),
25
+ );
26
+ return { registry, publisher, auth: plugins.auth, plugins };
27
+ }),
28
+ shutdown: (deps) => Effect.promise(async () => { /* cleanup */ }),
29
+ createRouter: (deps, builder) => ({
25
30
  ping: builder.ping.handler(async () => ({ status: "ok", timestamp })),
26
31
  }),
27
32
  });
28
33
  ```
29
34
 
30
- Fields: `variables` (public config), `secrets` (private env), `context` (per-request host context), `contract` (oRPC router), `initialize` (startup, returns services), `createRouter` (maps procedures to handlers), `shutdown` (cleanup). `plugins` in `initialize` gives typed factories for all other plugins.
35
+ Fields: `variables` (public config), `secrets` (private env), `context` (per-request host context), `contract` (oRPC router), `initialize` (startup, returns services; third arg `tools` for scoped resources), `createRouter` (maps procedures to handlers), `shutdown` (cleanup). `plugins` in `initialize` gives typed factories for all other plugins. Use `tools.buildService(tag, layer)` for DB-backed services, caches, and other scoped resources.
31
36
 
32
37
  ## oRPC Contract Design
33
38
 
@@ -193,10 +198,11 @@ export function buildPluginContext(c) {
193
198
  The API plugin receives `auth` in `initialize`:
194
199
 
195
200
  ```ts
196
- initialize: (config, plugins) => Effect.promise(async () => {
197
- const { auth, ...restPlugins } = plugins;
198
- return { auth, plugins: restPlugins, ... };
199
- })
201
+ initialize: (config, plugins, _tools) =>
202
+ Effect.gen(function* () {
203
+ const { auth, ...restPlugins } = plugins;
204
+ return { auth, plugins: restPlugins, ... };
205
+ })
200
206
  ```
201
207
 
202
208
  Use `getAuthClient()` for in-process calls:
@@ -279,11 +285,12 @@ const baseApi = await loadPluginEntry(runtime, apiEntry, integrityRegistry, plug
279
285
  The API plugin receives `plugins` in `initialize`:
280
286
 
281
287
  ```ts
282
- initialize: (config, plugins) => Effect.promise(async () => {
283
- const authClient = plugins.auth({ reqHeaders: someHeaders });
284
- const session = await authClient.getSession();
285
- return { auth: plugins.auth, plugins, ... };
286
- })
288
+ initialize: (config, plugins, _tools) =>
289
+ Effect.gen(function* () {
290
+ const authClient = plugins.auth({ reqHeaders: someHeaders });
291
+ const session = await authClient.getSession();
292
+ return { auth: plugins.auth, plugins, ... };
293
+ })
287
294
  ```
288
295
 
289
296
  ### API-Owned Registry Pattern
@@ -309,7 +316,22 @@ import { runEffect } from "@/lib/context";
309
316
  const result = await runEffect(services.myService.doSomething(input));
310
317
  ```
311
318
 
312
- Best practices: Keep service interfaces Effect-native, bridge to async only at the handler boundary via `runEffect()`. Use `Context.Tag` for DI between services. Initialize long-lived resources in `initialize` and return them as services.
319
+ Best practices: Keep service interfaces Effect-native, bridge to async only at the handler boundary via `runEffect()`. Use `Context.Tag` for DI between services.
320
+
321
+ **Scoped resources** — For DB pools, caches, publishers, or any resource that must live for the plugin's lifetime, build them inside `initialize` using `tools.buildService(tag, layer)`. This binds the resource to the plugin lifecycle scope — it persists until plugin shutdown and is automatically released.
322
+
323
+ ```ts
324
+ initialize: (config, plugins, tools) =>
325
+ Effect.gen(function* () {
326
+ const repo = yield* tools.buildService(
327
+ MyRepoTag,
328
+ MyRepoLive.pipe(Layer.provide(DatabaseLive(config.secrets.MY_DATABASE_URL))),
329
+ );
330
+ return { repo, plugins };
331
+ }),
332
+ ```
333
+
334
+ Do **not** use `Effect.provide(Tag, Layer.scoped(...))` inside `initialize` for long-lived resources — it creates a transient scope that closes immediately. `tools.buildService(...)` uses the plugin's lifecycle scope instead.
313
335
 
314
336
  ### SSR Proxy Client
315
337
 
@@ -155,15 +155,16 @@ bos deploy --service my-railway # override Railway service name
155
155
 
156
156
  → [`publish-sync`](.) skill and [`super-app`](.) for tenant-aware deploy considerations.
157
157
 
158
- ### `bos key publish`
158
+ ### `bos key generate`
159
159
 
160
160
  Generate a publish access key (NEAR function-call key) scoped to the FastKV registry contract.
161
+ If existing publish keys are found on the account, you will be prompted to remove them.
161
162
 
162
- **Flags:** `--allowance <amount>` (default: `0.25NEAR`)
163
+ **Flags:** `--allowance <amount>` (default: `1NEAR`)
163
164
 
164
165
  ```bash
165
- bos key publish # generate key with default allowance
166
- bos key publish --allowance 1NEAR # custom allowance
166
+ bos key generate # generate key with default allowance
167
+ bos key generate --allowance 2NEAR # custom allowance
167
168
  ```
168
169
 
169
170
  Outputs the public key, private key, and registry contract address. The generated key can only call the set and get methods on the BOS registry contract — it cannot transfer funds or call other contracts.
@@ -2,7 +2,7 @@
2
2
  name: dev-workflow
3
3
  description: Development workflow for everything-dev projects using bos dev, bos start, and the Module Federation runtime. Use when starting dev servers, debugging hot reload, or understanding the service-descriptor architecture.
4
4
  metadata:
5
- sources: "packages/everything-dev/src/service-descriptor.ts,packages/everything-dev/src/orchestrator.ts,packages/everything-dev/src/dev-logs.ts,packages/everything-dev/src/dev-session.ts"
5
+ sources: "packages/everything-dev/src/service-descriptor.ts,packages/everything-dev/src/orchestrator.ts,packages/everything-dev/src/dev-logs.ts,packages/everything-dev/src/dev-session.ts,packages/everything-dev/src/process-registry.ts,packages/everything-dev/src/app.ts"
6
6
  ---
7
7
 
8
8
  # everything-dev Development Workflow
@@ -17,12 +17,29 @@ bos dev
17
17
  bos dev --api remote # UI only
18
18
  bos dev --ui remote # API only
19
19
  bos dev # Full local (rarely needed)
20
+
21
+ # Pin individual service ports (unset flags are picked automatically and persisted)
22
+ bos dev --port 3100 --api-port 3101 --ui-port 3103 --auth-port 3102 --plugin-port-start 3110
20
23
  ```
21
24
 
25
+ ### Port persistence
26
+
27
+ `bos dev` writes the resolved host/api/ui/auth/plugin-port-start values to `.bos/infra-state.json`
28
+ under a `devPorts` key. Subsequent runs reuse the same ports unless you pass an explicit flag
29
+ (or delete the file). This keeps CORS, browser bookmarks, and wallet-allowlisted origins stable
30
+ across restarts.
31
+
32
+ ### Port budgets (forward-compat for `--workspaces`)
33
+
34
+ `prepareDevelopmentRuntimeConfig` accepts an optional `portBudget: { min, max }`. When set,
35
+ `pickAvailablePort` skips candidates outside the budget and throws `RangeError` if no free port
36
+ is found inside it. The standalone `bos dev` path does not pass a budget today; a future
37
+ `bos dev --workspaces` orchestrator will slice disjoint budgets per child project.
38
+
22
39
  ## Port Assignments
23
40
 
24
- | Service | Port | URL |
25
- |---------|------|-----|
41
+ | Service | Default | URL |
42
+ |---------|---------|-----|
26
43
  | host | 3000 | http://localhost:3000 |
27
44
  | api | 3001 | http://localhost:3001 |
28
45
  | auth | 3002 | http://localhost:3002 |
@@ -118,13 +135,16 @@ lsof -i :3003 # Check what is using port 3003
118
135
 
119
136
  Kill the conflicting process and retry, or stop the existing `bos dev` session first.
120
137
 
121
- ### Stale PID file
138
+ ### Stale PID registry
122
139
 
123
- If `bos kill` doesn't run cleanly (e.g., terminal was closed), stale PIDs in `.bos/pids.json` can block restart:
140
+ If `bos kill` doesn't run cleanly (e.g., terminal was closed), stale entries can linger in the
141
+ global registry at `~/.cache/everything-dev/pids.json`. `bos ps` and `bos kill` always prune
142
+ ESRCH (dead) PIDs on read, so stale entries don't block restart — but you can wipe the file
143
+ manually if you want a clean slate:
124
144
 
125
145
  ```bash
126
- rm .bos/pids.json # Clear stale PID tracking
127
- bos dev # Start fresh
146
+ rm ~/.cache/everything-dev/pids.json # Clear global registry
147
+ bos dev # Start fresh
128
148
  ```
129
149
 
130
150
  ### API not responding
@@ -157,9 +177,18 @@ bos start --account foo.near --domain bar.com # Load specific config
157
177
  ## Process Management
158
178
 
159
179
  ```bash
160
- bos ps # Show PID, name, port, started time
161
- bos kill # Graceful SIGTERM → SIGKILL
162
- bos kill --force # Immediate SIGKILL
180
+ bos ps # List tracked development processes (cwd's entries, with role/ports)
181
+ bos kill # SIGTERM processes owned by cwd
182
+ bos kill --all # SIGTERM across all config directories
183
+ bos kill --signal SIGKILL # Force kill (cwd)
184
+ bos kill --config-dir /path # Target a specific project
163
185
  ```
164
186
 
165
- Process tracking uses `.bos/pids.json`.
187
+ The registry lives at `~/.cache/everything-dev/pids.json`, keyed by `pid`. Each entry stores
188
+ `configDir`, `role` (`standalone` today; `workspace-parent`/`workspace-child` reserved for the
189
+ planned `bos dev --workspaces` orchestrator), `ports`, optional `budget`, `startedAt`, and
190
+ `description`. `bos dev` registers on startup and unregisters on graceful shutdown; the
191
+ `BOS_WORKSPACE_CHILD=1` env var suppresses standalone registration so a future parent
192
+ orchestrator owns registry entries.
193
+
194
+ Process tracking uses `~/.cache/everything-dev/pids.json` (global, atomic writes).
@@ -159,20 +159,23 @@ export default createPlugin.withPlugins<PluginsClient>()({
159
159
 
160
160
  contract,
161
161
 
162
- initialize: (config) =>
162
+ initialize: (config, _plugins, tools) =>
163
163
  Effect.gen(function* () {
164
164
  const service = new TemplateService(config.variables.baseUrl, config.secrets.apiKey, config.variables.timeout);
165
165
  yield* service.ping(); // health check on startup
166
166
 
167
167
  const publisher = new MemoryPublisher({ resumeRetentionSeconds: 120 });
168
168
 
169
+ // For scoped resources (DB pools, caches, repositories):
170
+ // const repo = yield* tools.buildService(MyRepoTag, MyRepoLive.pipe(...))
171
+
169
172
  return { service, publisher };
170
173
  }),
171
174
 
172
175
  shutdown: () => Effect.void,
173
176
 
174
- createRouter: (context, builder) => {
175
- const { service, publisher } = context;
177
+ createRouter: (deps, builder) => {
178
+ const { service, publisher } = deps;
176
179
  const requireAuth = builder.middleware(async ({ context, next }) => {
177
180
  if (!context.userId) throw new ORPCError("UNAUTHORIZED", { message: "User ID required" });
178
181
  return next({ context: { ...context, userId: context.userId } });
@@ -236,7 +239,8 @@ Good practice:
236
239
  **`variables`** — Public config exposed in `bos.config.json` (typed, with defaults).
237
240
  **`secrets`** — Private values from `process.env` (typed, dev defaults).
238
241
  **`context`** — Per-request context injected by the host. See "Request Context Reference" below for all available fields.
239
- **`initialize`** — Effect-based startup. Create services, publishers, DB connections. Return value is passed as `context` to `createRouter`.
242
+ **`initialize`** — Effect-based startup. Create services, publishers, DB connections. Receives an optional third argument `tools` for building scoped resources. Return value is passed as `deps` to `createRouter`.
243
+ **`tools`** — Framework-provided third argument in `initialize(config, plugins, tools)`. Use `tools.buildService(tag, layer)` to build scoped resources (DB pools, caches, repositories) that live for the plugin's lifetime.
240
244
  **`createRouter`** — Maps contract procedures to handlers. Receives the value returned by `initialize` plus a pre-configured `builder`.
241
245
 
242
246
  ## Request Context Reference
@@ -418,7 +422,10 @@ export function DatabaseLive(url: string) {
418
422
  1. Create `drizzle.config.ts` in your plugin directory
419
423
  2. Run `drizzle-kit generate` to produce SQL migration files
420
424
  3. Store migrations in `src/db/migrations/`
421
- 4. Use the custom `migrate()` function during `initialize`:
425
+ 4. Use the custom `migrate()` function during `initialize`. Pass an explicit
426
+ `storage` resolved from the workspace so the journal slug is reliable
427
+ under rspack/Module Federation bundling (the no-arg fallback reads
428
+ `npm_package_name`, which is unreliable in bundled remotes):
422
429
 
423
430
  ```ts
424
431
  initialize: (config) =>
@@ -427,8 +434,12 @@ initialize: (config) =>
427
434
  // Or load and apply migrations directly:
428
435
  const { loadMigrations } = yield* Effect.promise(() => import("./db/load-migrations"));
429
436
  const { migrate } = yield* Effect.promise(() => import("./db/migrator"));
437
+ const { getMigrationSlug, getMigrationStorage } = yield* Effect.promise(
438
+ () => import("everything-dev/db"),
439
+ );
440
+ const storage = getMigrationStorage(getMigrationSlug(import.meta.dirname));
430
441
  const migrations = yield* loadMigrations();
431
- yield* migrate(driver.db, migrations);
442
+ yield* migrate(driver.db, migrations, storage);
432
443
 
433
444
  return { db: driver.db, ... };
434
445
  }),