unoverse 0.1.149 → 0.1.150
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/README.md +5 -3
- package/bin/unoverse.mjs +31 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,9 +27,11 @@ unoverse stop
|
|
|
27
27
|
|
|
28
28
|
## Build with Claude
|
|
29
29
|
|
|
30
|
-
Creating a universe also installs
|
|
30
|
+
Creating a universe also installs the Claude Code authoring skills (`.claude/skills/`)
|
|
31
31
|
and registers the `canvas` MCP (`.mcp.json`). Open the folder in Claude Code and ask for
|
|
32
32
|
what you want: components, templates, custom nodes, agent skills, or whole workflows
|
|
33
|
-
built live on your Canvas. `unoverse update` keeps the CLI and the
|
|
33
|
+
built live on your Canvas. `unoverse update` keeps the CLI and the skills current, and
|
|
34
|
+
any agent can install the same skills straight from the docs site:
|
|
35
|
+
`npx skills add docs.unoverse.ai`.
|
|
34
36
|
|
|
35
|
-
Documentation: https://
|
|
37
|
+
Documentation: https://docs.unoverse.ai
|
package/bin/unoverse.mjs
CHANGED
|
@@ -154,6 +154,37 @@ switch (cmd) {
|
|
|
154
154
|
// new cache key, so every studio release installs clean and fully resolved, and
|
|
155
155
|
// relaunching the same version stays instant from cache. Offline (npm view
|
|
156
156
|
// fails), fall back to the cached latest — stale beats broken with no network.
|
|
157
|
+
// RECLAIM THE PORT FROM A STALE STUDIO. A studio left over from an earlier session
|
|
158
|
+
// keeps :4108, so the new launch either fails to bind or — worse — the browser
|
|
159
|
+
// quietly keeps talking to last week's build. If the listener IS a studio, it is
|
|
160
|
+
// ours to replace: kill it and wait for the port. Anything else on the port is
|
|
161
|
+
// NOT ours: name it and stop, never kill a stranger's process.
|
|
162
|
+
const STUDIO_PORT = 4108;
|
|
163
|
+
const lsof = spawnSync("lsof", ["-nP", `-iTCP:${STUDIO_PORT}`, "-sTCP:LISTEN", "-Fpc"], { encoding: "utf8" });
|
|
164
|
+
const holder = lsof.status === 0 ? (lsof.stdout.match(/^p(\d+)$/m) || [])[1] : undefined;
|
|
165
|
+
if (holder) {
|
|
166
|
+
const cmd = spawnSync("ps", ["-p", holder, "-o", "command="], { encoding: "utf8" }).stdout?.trim() ?? "";
|
|
167
|
+
if (/unoverse-studio|@unoverse-platform\/studio/.test(cmd)) {
|
|
168
|
+
try {
|
|
169
|
+
process.kill(Number(holder));
|
|
170
|
+
} catch {
|
|
171
|
+
/* already gone */
|
|
172
|
+
}
|
|
173
|
+
// Wait (up to ~5s) for the socket to actually free — kill returns before close.
|
|
174
|
+
for (let i = 0; i < 25; i++) {
|
|
175
|
+
const still = spawnSync("lsof", ["-nP", `-iTCP:${STUDIO_PORT}`, "-sTCP:LISTEN"], { encoding: "utf8" });
|
|
176
|
+
if (!still.stdout?.trim()) break;
|
|
177
|
+
spawnSync("sleep", ["0.2"]);
|
|
178
|
+
}
|
|
179
|
+
console.log(` Reclaimed :${STUDIO_PORT} from a previous studio (pid ${holder})`);
|
|
180
|
+
} else {
|
|
181
|
+
console.error(
|
|
182
|
+
` :${STUDIO_PORT} is held by something that is not a studio (pid ${holder}: ${cmd || "unknown"}).\n` +
|
|
183
|
+
` Stop that process first — unoverse won't kill what it didn't start.`,
|
|
184
|
+
);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
157
188
|
const view = spawnSync("npm", ["view", "@unoverse-platform/studio", "version"], { encoding: "utf8" });
|
|
158
189
|
const exact = view.status === 0 ? view.stdout.trim() : "";
|
|
159
190
|
const spec = exact ? `@unoverse-platform/studio@${exact}` : "@unoverse-platform/studio@latest";
|
package/package.json
CHANGED