ponzu 1.71.0 → 1.71.2
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 +196 -95
- package/package.json +1 -1
- package/studio/assets/{index-CR9Oyb70.js → index-kF-bDYqZ.js} +17 -17
- package/studio/index.html +1 -1
package/dist/index.js
CHANGED
|
@@ -6978,7 +6978,7 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
6978
6978
|
// apps/cli/src/index.ts
|
|
6979
6979
|
import { existsSync as existsSync13 } from "fs";
|
|
6980
6980
|
import { networkInterfaces } from "os";
|
|
6981
|
-
import { dirname as
|
|
6981
|
+
import { dirname as dirname13, isAbsolute as isAbsolute4, join as join21, resolve as resolve5 } from "path";
|
|
6982
6982
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6983
6983
|
import { parseArgs } from "util";
|
|
6984
6984
|
|
|
@@ -33328,7 +33328,7 @@ When to watch: whenever the person might react to the work on the canvas. That's
|
|
|
33328
33328
|
|
|
33329
33329
|
Watching doesn't cut you off from chat. A message the person types reaches you as soon as the current wait returns, within a minute. To tell them something (here's the link, which option you'd pick), write it in chat, then keep watching.
|
|
33330
33330
|
|
|
33331
|
-
1. listen: wait_for_activity with the cursor from your last call. Start with types comment.created, comment.replied, comment.edited, file.changed. An edit replaces what the comment asks; work from the new text. If the wait says Ponzu restarted or lost track, it lists the open threads waiting on you instead: work through those, then carry on with the cursor it gives. The wait hears from every file you've worked in this session and names the file for any event outside the one you passed: pass that file when you act on it.
|
|
33331
|
+
1. listen: wait_for_activity with the cursor from your last call. Start with types comment.created, comment.replied, comment.edited, file.changed. An edit replaces what the comment asks; work from the new text. If the wait says Ponzu restarted or lost track, it lists the open threads waiting on you instead: work through those, then carry on with the cursor it gives. If it says Ponzu stopped and isn't back yet, nothing was checked: wait again with the cursor it gives, as Ponzu is most likely restarting into an update. The wait hears from every file you've worked in this session and names the file for any event outside the one you passed: pass that file when you act on it.
|
|
33332
33332
|
2. triage each comment:
|
|
33333
33333
|
- change ("make this bigger", "try blue"): do it.
|
|
33334
33334
|
- question ("why this font?"): reply with an answer, leave it open.
|
|
@@ -33422,6 +33422,7 @@ See it
|
|
|
33422
33422
|
|
|
33423
33423
|
What the person sees
|
|
33424
33424
|
- On their canvas, the load plays once when the artboard appears: when they open its page, and each time you edit it. Then a finite animation holds its end. Hovering or clicking the artboard doesn't replay it, so never tell them it will.
|
|
33425
|
+
- Their canvas plays what record shows. It holds motion still on purpose: while its window is in the background on battery, while they pan across a crowded page, for parts too small to see at their zoom, and for loops longer than 20 s on an artboard zoomed far out. If record shows the motion working and they say it doesn't play, tell the Ponzu team with send_feedback instead of reworking the design.
|
|
33425
33426
|
- A hint that fades out ends hidden, so the canvas shows nothing once it has played.
|
|
33426
33427
|
- When they need to watch the motion (an entrance to review, a hint that leaves), put a looping copy on an artboard beside the real one: animation-iteration-count: infinite, with a beat of about a second held at the end of the keyframes so each cycle reads as one play. Keep the real one finite, and say which is which in a note.
|
|
33427
33428
|
- If the motion answers something the person does, put it on :hover or :focus, so they can set it off themselves.
|
|
@@ -33541,7 +33542,7 @@ var listenTools = [
|
|
|
33541
33542
|
title: "Wait for activity",
|
|
33542
33543
|
group: "listen",
|
|
33543
33544
|
readOnly: true,
|
|
33544
|
-
description: "Watch the canvas. Call this instead of ending your turn whenever the person might react to your work there: after you put something up for review, or while you design together. Calling it again and again is the loop (get_guide('watch')). Long-polls for what people do in the canvas: new comments and replies, edits made in a text editor, other agents' changes, in this file and the others you've worked in this session, saying which file each is in. Returns immediately if anything happened after `since`; otherwise waits up to `timeout` seconds. Pass back the returned cursor next time so nothing is missed. If Ponzu restarted or lost track
|
|
33545
|
+
description: "Watch the canvas. Call this instead of ending your turn whenever the person might react to your work there: after you put something up for review, or while you design together. Calling it again and again is the loop (get_guide('watch')). Long-polls for what people do in the canvas: new comments and replies, edits made in a text editor, other agents' changes, in this file and the others you've worked in this session, saying which file each is in. Returns immediately if anything happened after `since`; otherwise waits up to `timeout` seconds. Pass back the returned cursor next time so nothing is missed. If Ponzu restarts during the wait, the wait carries on once it's back. If it restarted or lost track before you waited, it returns at once with the open threads waiting on you: handle those, then keep watching with the cursor it gives. The person's chat messages still reach you between waits.",
|
|
33545
33546
|
input: {
|
|
33546
33547
|
file: fileArg,
|
|
33547
33548
|
since: number2().int().min(0).optional().describe("Cursor from the last call. Omit to start from now."),
|
|
@@ -33570,7 +33571,7 @@ var listenTools = [
|
|
|
33570
33571
|
const waiting = waitingText(files, all);
|
|
33571
33572
|
return {
|
|
33572
33573
|
text: `${GAP_NOTE[gap]} ${waiting.text}
|
|
33573
|
-
|
|
33574
|
+
Keep watching: wait again with cursor=${next}.`,
|
|
33574
33575
|
data: { cursor: next, events: [], gap, waiting: waiting.ids },
|
|
33575
33576
|
metrics: { cursor: gap, events: 0, scope_files: files.length }
|
|
33576
33577
|
};
|
|
@@ -36772,6 +36773,7 @@ data:
|
|
|
36772
36773
|
|
|
36773
36774
|
// packages/mcp/src/index.ts
|
|
36774
36775
|
var FILES_META = "ponzu.design/files";
|
|
36776
|
+
var WAIT_META = "ponzu.design/wait";
|
|
36775
36777
|
function clientKind(name = "") {
|
|
36776
36778
|
const n = name.toLowerCase();
|
|
36777
36779
|
if (n.includes("claude"))
|
|
@@ -36840,7 +36842,7 @@ function createMcpServer(ws, opts = {}) {
|
|
|
36840
36842
|
destructiveHint: def.destructive ?? false,
|
|
36841
36843
|
openWorldHint: false
|
|
36842
36844
|
}
|
|
36843
|
-
}, async (args, extra) => toMcp(await runTool(def, args, { ws, caller: getCaller(), signal: extra.signal, session }), session));
|
|
36845
|
+
}, async (args, extra) => toMcp(await runTool(def, args, { ws, caller: getCaller(), signal: extra.signal, session }), session, def.name));
|
|
36844
36846
|
}
|
|
36845
36847
|
for (const [topic, text] of Object.entries(GUIDES)) {
|
|
36846
36848
|
server.registerResource(`guide-${topic}`, `ponzu://guide/${topic}`, { title: `Ponzu guide: ${topic}`, mimeType: "text/markdown" }, async (uri) => ({ contents: [{ uri: uri.href, mimeType: "text/markdown", text }] }));
|
|
@@ -36879,13 +36881,19 @@ Read get_guide('basics'). Write the brief and your direction to a note, set toke
|
|
|
36879
36881
|
}));
|
|
36880
36882
|
return server;
|
|
36881
36883
|
}
|
|
36882
|
-
function toMcp(r, session) {
|
|
36884
|
+
function toMcp(r, session, tool) {
|
|
36883
36885
|
const content = [];
|
|
36884
36886
|
for (const img of r.images ?? [])
|
|
36885
36887
|
content.push({ type: "image", data: img.data, mimeType: img.mime });
|
|
36886
36888
|
content.push({ type: "text", text: r.text });
|
|
36887
|
-
const
|
|
36888
|
-
|
|
36889
|
+
const meta = {};
|
|
36890
|
+
if (session.files?.length)
|
|
36891
|
+
meta[FILES_META] = session.files;
|
|
36892
|
+
if (tool === "wait_for_activity" && r.data) {
|
|
36893
|
+
const { cursor, gap, waiting } = r.data;
|
|
36894
|
+
meta[WAIT_META] = { cursor, ...gap ? { gap, waiting: waiting?.length ?? 0 } : {} };
|
|
36895
|
+
}
|
|
36896
|
+
return { content, isError: r.isError, ...Object.keys(meta).length ? { _meta: meta } : {} };
|
|
36889
36897
|
}
|
|
36890
36898
|
function createHttpHandler(ws, opts = {}) {
|
|
36891
36899
|
const sessions = new Map;
|
|
@@ -37084,6 +37092,7 @@ function onBodyDone(res, done) {
|
|
|
37084
37092
|
|
|
37085
37093
|
// packages/mcp/src/bridge.ts
|
|
37086
37094
|
var CALL_TIMEOUT = 15 * 60000;
|
|
37095
|
+
var RESTART_GRACE = 1e4;
|
|
37087
37096
|
var readOnly = new Set(tools.filter((t) => t.readOnly).map((t) => t.name));
|
|
37088
37097
|
async function serveBridge(opts, transport = new StdioServerTransport) {
|
|
37089
37098
|
const server = new Server({ name: opts.name ?? "ponzu", version: opts.version ?? "0.1.0", title: "Ponzu" }, {
|
|
@@ -37213,19 +37222,70 @@ async function serveBridge(opts, transport = new StdioServerTransport) {
|
|
|
37213
37222
|
return fn(await localClient(), extra.signal);
|
|
37214
37223
|
}
|
|
37215
37224
|
};
|
|
37216
|
-
|
|
37217
|
-
const
|
|
37218
|
-
|
|
37219
|
-
|
|
37220
|
-
|
|
37225
|
+
const hostBack = async (until, signal) => {
|
|
37226
|
+
const giveUp = Math.min(until, Date.now() + (opts.restartGrace ?? RESTART_GRACE));
|
|
37227
|
+
while (!signal.aborted) {
|
|
37228
|
+
if (await opts.findHost(false).catch(() => null))
|
|
37229
|
+
return true;
|
|
37230
|
+
if (Date.now() >= giveUp)
|
|
37231
|
+
return false;
|
|
37232
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
37233
|
+
}
|
|
37234
|
+
return false;
|
|
37235
|
+
};
|
|
37236
|
+
const waitThrough = async (params, signal) => {
|
|
37237
|
+
const { since, timeout } = params.arguments ?? {};
|
|
37238
|
+
const deadline = Date.now() + (typeof timeout === "number" ? timeout : 60) * 1000;
|
|
37239
|
+
const left = () => Math.max(0, Math.ceil((deadline - Date.now()) / 1000));
|
|
37240
|
+
const withArgs = (more) => ({
|
|
37241
|
+
...params,
|
|
37242
|
+
arguments: { ...params.arguments, ...more }
|
|
37243
|
+
});
|
|
37244
|
+
let cutOff = false;
|
|
37245
|
+
const result = await call(params, signal, async () => {
|
|
37246
|
+
cutOff = true;
|
|
37247
|
+
if (!await hostBack(deadline, signal) && Date.now() >= deadline)
|
|
37248
|
+
return null;
|
|
37249
|
+
return withArgs({ timeout: left() });
|
|
37250
|
+
});
|
|
37251
|
+
if (!result) {
|
|
37252
|
+
const again = typeof since === "number" ? `Wait again with cursor=${since}` : "Wait again";
|
|
37253
|
+
return {
|
|
37254
|
+
content: [
|
|
37255
|
+
{
|
|
37256
|
+
type: "text",
|
|
37257
|
+
text: `Ponzu stopped while you waited and isn't back yet, so nothing was checked. ${again}: it's most likely restarting into an update.`
|
|
37258
|
+
}
|
|
37259
|
+
]
|
|
37260
|
+
};
|
|
37261
|
+
}
|
|
37262
|
+
const wait = result._meta?.[WAIT_META];
|
|
37263
|
+
if (!cutOff || wait?.gap !== "restart" || wait.waiting || !left())
|
|
37264
|
+
return result;
|
|
37265
|
+
const again = await call(withArgs({ since: wait.cursor, timeout: left() }), signal);
|
|
37266
|
+
const first = again.content.findIndex((c) => c.type === "text");
|
|
37267
|
+
return {
|
|
37268
|
+
...again,
|
|
37269
|
+
content: again.content.map((c, i) => i === first && c.type === "text" ? {
|
|
37270
|
+
...c,
|
|
37271
|
+
text: `Ponzu restarted while you waited, with nothing waiting on you.
|
|
37272
|
+
${c.text}`
|
|
37273
|
+
} : c)
|
|
37274
|
+
};
|
|
37275
|
+
};
|
|
37276
|
+
const call = async (params, signal, cutOff) => {
|
|
37277
|
+
const name = params.name;
|
|
37278
|
+
let sent = params;
|
|
37279
|
+
let ridden = cutOff;
|
|
37280
|
+
const options = { signal, timeout: CALL_TIMEOUT };
|
|
37221
37281
|
for (let attempt = 0;attempt < 2; attempt++) {
|
|
37222
37282
|
const client = await hostClient();
|
|
37223
37283
|
if (!client)
|
|
37224
37284
|
break;
|
|
37225
37285
|
try {
|
|
37226
|
-
return remember(await using(client, () => client.request({ method: "tools/call", params }, CallToolResultSchema, options)));
|
|
37286
|
+
return remember(await using(client, () => client.request({ method: "tools/call", params: sent }, CallToolResultSchema, options)));
|
|
37227
37287
|
} catch (err) {
|
|
37228
|
-
if (
|
|
37288
|
+
if (signal.aborted || err instanceof McpError && err.code !== ErrorCode.ConnectionClosed)
|
|
37229
37289
|
throw err;
|
|
37230
37290
|
await dropHost(client);
|
|
37231
37291
|
if (!neverArrived(err) && !readOnly.has(name)) {
|
|
@@ -37239,10 +37299,27 @@ async function serveBridge(opts, transport = new StdioServerTransport) {
|
|
|
37239
37299
|
isError: true
|
|
37240
37300
|
};
|
|
37241
37301
|
}
|
|
37302
|
+
if (ridden && !neverArrived(err)) {
|
|
37303
|
+
const next = await ridden();
|
|
37304
|
+
if (!next)
|
|
37305
|
+
return null;
|
|
37306
|
+
sent = next;
|
|
37307
|
+
ridden = undefined;
|
|
37308
|
+
}
|
|
37242
37309
|
}
|
|
37243
37310
|
}
|
|
37311
|
+
if (sent !== params)
|
|
37312
|
+
return null;
|
|
37244
37313
|
await opts.prepareLocal?.();
|
|
37245
|
-
return remember(await (await localClient()).request({ method: "tools/call", params }, CallToolResultSchema, options));
|
|
37314
|
+
return remember(await (await localClient()).request({ method: "tools/call", params: sent }, CallToolResultSchema, options));
|
|
37315
|
+
};
|
|
37316
|
+
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
37317
|
+
const name = req.params.name;
|
|
37318
|
+
const args = req.params.arguments ?? {};
|
|
37319
|
+
const params = { ...req.params, arguments: opts.mapArgs ? opts.mapArgs(name, args) : args };
|
|
37320
|
+
if (name === "wait_for_activity")
|
|
37321
|
+
return waitThrough(params, extra.signal);
|
|
37322
|
+
return await call(params, extra.signal);
|
|
37246
37323
|
});
|
|
37247
37324
|
server.setRequestHandler(ListToolsRequestSchema, (req, extra) => list((c, signal) => c.listTools(req.params, { signal }))(req, extra));
|
|
37248
37325
|
server.setRequestHandler(ListResourcesRequestSchema, (req, extra) => list((c, signal) => c.listResources(req.params, { signal }))(req, extra));
|
|
@@ -47639,7 +47716,7 @@ function remoteUpdater(endpoint, token) {
|
|
|
47639
47716
|
// apps/cli/package.json
|
|
47640
47717
|
var package_default = {
|
|
47641
47718
|
name: "ponzu",
|
|
47642
|
-
version: "1.71.
|
|
47719
|
+
version: "1.71.2",
|
|
47643
47720
|
description: "The open source canvas your agent draws on in HTML and CSS.",
|
|
47644
47721
|
type: "module",
|
|
47645
47722
|
license: "MIT",
|
|
@@ -47662,17 +47739,40 @@ var package_default = {
|
|
|
47662
47739
|
|
|
47663
47740
|
// apps/cli/src/host.ts
|
|
47664
47741
|
import { spawn as spawn6 } from "child_process";
|
|
47665
|
-
import { existsSync as existsSync9, readFileSync as
|
|
47742
|
+
import { existsSync as existsSync9, readFileSync as readFileSync3, statSync as statSync3 } from "fs";
|
|
47666
47743
|
import { chmod, copyFile, mkdir as mkdir11, rename as rename9, rm as rm5, utimes as utimes3, writeFile as writeFile9 } from "fs/promises";
|
|
47744
|
+
import { homedir as homedir6 } from "os";
|
|
47745
|
+
import { dirname as dirname7, join as join15, posix, win32 } from "path";
|
|
47746
|
+
|
|
47747
|
+
// packages/server/src/updating.ts
|
|
47748
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, rmSync, writeFileSync } from "fs";
|
|
47667
47749
|
import { homedir as homedir5 } from "os";
|
|
47668
|
-
import { dirname as dirname6, join as join14
|
|
47669
|
-
var
|
|
47670
|
-
var
|
|
47750
|
+
import { dirname as dirname6, join as join14 } from "path";
|
|
47751
|
+
var UPDATING_WITHIN = 2 * 60000;
|
|
47752
|
+
var updatingFile = () => join14(process.env.PONZU_HOME ?? join14(homedir5(), ".ponzu"), "updating.json");
|
|
47753
|
+
function read() {
|
|
47754
|
+
try {
|
|
47755
|
+
const u = JSON.parse(readFileSync2(updatingFile(), "utf8"));
|
|
47756
|
+
if (typeof u.from !== "string" || typeof u.to !== "string" || typeof u.at !== "number")
|
|
47757
|
+
return null;
|
|
47758
|
+
return { from: u.from, to: u.to, at: u.at, ...u.told ? { told: true } : {} };
|
|
47759
|
+
} catch {
|
|
47760
|
+
return null;
|
|
47761
|
+
}
|
|
47762
|
+
}
|
|
47763
|
+
function updating(now = Date.now()) {
|
|
47764
|
+
const u = read();
|
|
47765
|
+
return u && now - u.at < UPDATING_WITHIN ? u : null;
|
|
47766
|
+
}
|
|
47767
|
+
|
|
47768
|
+
// apps/cli/src/host.ts
|
|
47769
|
+
var ponzuHome = () => process.env.PONZU_HOME ?? join15(homedir6(), ".ponzu");
|
|
47770
|
+
var hostFile = () => join15(ponzuHome(), "host.json");
|
|
47671
47771
|
async function announceHost(url, opts = {}) {
|
|
47672
47772
|
if (!opts.takeOver && await runningHost())
|
|
47673
47773
|
return async () => {};
|
|
47674
47774
|
const path = hostFile();
|
|
47675
|
-
await mkdir11(
|
|
47775
|
+
await mkdir11(dirname7(path), { recursive: true });
|
|
47676
47776
|
const me = { url, mcp: `${url}/mcp`, pid: process.pid };
|
|
47677
47777
|
await writeFile9(path, `${JSON.stringify(me)}
|
|
47678
47778
|
`);
|
|
@@ -47683,7 +47783,7 @@ async function announceHost(url, opts = {}) {
|
|
|
47683
47783
|
}
|
|
47684
47784
|
function readHost() {
|
|
47685
47785
|
try {
|
|
47686
|
-
return JSON.parse(
|
|
47786
|
+
return JSON.parse(readFileSync3(hostFile(), "utf8"));
|
|
47687
47787
|
} catch {
|
|
47688
47788
|
return null;
|
|
47689
47789
|
}
|
|
@@ -47702,11 +47802,11 @@ async function runningHost() {
|
|
|
47702
47802
|
}
|
|
47703
47803
|
var SERVER = "Contents/Resources/server/ponzu";
|
|
47704
47804
|
var pathFor = (os) => os === "win32" ? win32 : posix;
|
|
47705
|
-
var appImageServer = () =>
|
|
47706
|
-
var appImageRecord = () =>
|
|
47805
|
+
var appImageServer = () => join15(ponzuHome(), "app/ponzu");
|
|
47806
|
+
var appImageRecord = () => join15(ponzuHome(), "app/appimage");
|
|
47707
47807
|
function recordedAppImage() {
|
|
47708
47808
|
try {
|
|
47709
|
-
const path =
|
|
47809
|
+
const path = readFileSync3(appImageRecord(), "utf8").trim();
|
|
47710
47810
|
return path && existsSync9(path) ? path : null;
|
|
47711
47811
|
} catch {
|
|
47712
47812
|
return null;
|
|
@@ -47721,7 +47821,7 @@ function isFolder(app) {
|
|
|
47721
47821
|
}
|
|
47722
47822
|
function appServer(app, os = process.platform) {
|
|
47723
47823
|
if (os === "darwin")
|
|
47724
|
-
return
|
|
47824
|
+
return join15(app, SERVER);
|
|
47725
47825
|
const path = pathFor(os);
|
|
47726
47826
|
if (os === "linux" && !isFolder(app))
|
|
47727
47827
|
return appImageServer();
|
|
@@ -47754,7 +47854,7 @@ function ownBundle(execPath = process.execPath, os = process.platform, env = pro
|
|
|
47754
47854
|
}
|
|
47755
47855
|
function installedApps(os = process.platform, env = process.env) {
|
|
47756
47856
|
if (os === "darwin")
|
|
47757
|
-
return ["/Applications/Ponzu.app",
|
|
47857
|
+
return ["/Applications/Ponzu.app", join15(homedir6(), "Applications/Ponzu.app")];
|
|
47758
47858
|
if (os === "win32") {
|
|
47759
47859
|
return [
|
|
47760
47860
|
env.LOCALAPPDATA && win32.join(env.LOCALAPPDATA, "Programs", "ponzu"),
|
|
@@ -47787,7 +47887,7 @@ async function adoptAppImage(execPath = process.execPath, os = process.platform,
|
|
|
47787
47887
|
const from = statSync3(execPath);
|
|
47788
47888
|
const to = statSync3(copy, { throwIfNoEntry: false });
|
|
47789
47889
|
if (!to || to.size !== from.size || Math.trunc(to.mtimeMs) !== Math.trunc(from.mtimeMs)) {
|
|
47790
|
-
await mkdir11(
|
|
47890
|
+
await mkdir11(dirname7(copy), { recursive: true });
|
|
47791
47891
|
const temp = `${copy}.${process.pid}`;
|
|
47792
47892
|
await copyFile(execPath, temp);
|
|
47793
47893
|
await chmod(temp, 493);
|
|
@@ -47802,7 +47902,7 @@ async function adoptAppImage(execPath = process.execPath, os = process.platform,
|
|
|
47802
47902
|
async function launchApp(app, timeoutMs = 30000) {
|
|
47803
47903
|
const deadline = Date.now() + timeoutMs;
|
|
47804
47904
|
for (let tick = 0;Date.now() < deadline; tick++) {
|
|
47805
|
-
if (tick % 40 === 0)
|
|
47905
|
+
if (tick % 40 === 0 && !updating())
|
|
47806
47906
|
startApp(app);
|
|
47807
47907
|
const url = await runningHost();
|
|
47808
47908
|
if (url)
|
|
@@ -47851,7 +47951,7 @@ async function findHost(launch) {
|
|
|
47851
47951
|
lastFailed = Date.now();
|
|
47852
47952
|
return url;
|
|
47853
47953
|
}
|
|
47854
|
-
var shimPath = (os = process.platform) =>
|
|
47954
|
+
var shimPath = (os = process.platform) => join15(ponzuHome(), os === "win32" ? "bin/ponzu.cmd" : "bin/ponzu");
|
|
47855
47955
|
function shimScript(app, os = process.platform) {
|
|
47856
47956
|
if (os === "win32") {
|
|
47857
47957
|
const candidates = [
|
|
@@ -47896,7 +47996,7 @@ exit 1
|
|
|
47896
47996
|
}
|
|
47897
47997
|
async function writeShim(app) {
|
|
47898
47998
|
const path = shimPath();
|
|
47899
|
-
await mkdir11(
|
|
47999
|
+
await mkdir11(dirname7(path), { recursive: true });
|
|
47900
48000
|
await writeFile9(path, shimScript(app));
|
|
47901
48001
|
await chmod(path, 493);
|
|
47902
48002
|
return path;
|
|
@@ -47904,28 +48004,28 @@ async function writeShim(app) {
|
|
|
47904
48004
|
|
|
47905
48005
|
// apps/cli/src/install.ts
|
|
47906
48006
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
47907
|
-
import { existsSync as existsSync11, readFileSync as
|
|
48007
|
+
import { existsSync as existsSync11, readFileSync as readFileSync5 } from "fs";
|
|
47908
48008
|
import { mkdir as mkdir13, writeFile as writeFile11 } from "fs/promises";
|
|
47909
|
-
import { homedir as
|
|
47910
|
-
import { delimiter as delimiter2, dirname as
|
|
48009
|
+
import { homedir as homedir8 } from "os";
|
|
48010
|
+
import { delimiter as delimiter2, dirname as dirname9, join as join17 } from "path";
|
|
47911
48011
|
|
|
47912
48012
|
// apps/cli/src/command.ts
|
|
47913
48013
|
import { spawnSync } from "child_process";
|
|
47914
|
-
import { accessSync, constants, existsSync as existsSync10, lstatSync, readFileSync as
|
|
48014
|
+
import { accessSync, constants, existsSync as existsSync10, lstatSync, readFileSync as readFileSync4, realpathSync as realpathSync3 } from "fs";
|
|
47915
48015
|
import { mkdir as mkdir12, symlink, writeFile as writeFile10 } from "fs/promises";
|
|
47916
|
-
import { homedir as
|
|
47917
|
-
import { delimiter, dirname as
|
|
47918
|
-
function commandDirs(home =
|
|
47919
|
-
return [
|
|
48016
|
+
import { homedir as homedir7 } from "os";
|
|
48017
|
+
import { delimiter, dirname as dirname8, join as join16 } from "path";
|
|
48018
|
+
function commandDirs(home = homedir7()) {
|
|
48019
|
+
return [join16(home, ".local/bin"), join16(home, "bin"), "/usr/local/bin"];
|
|
47920
48020
|
}
|
|
47921
|
-
var stateFile = () =>
|
|
48021
|
+
var stateFile = () => join16(ponzuHome(), "command.json");
|
|
47922
48022
|
async function linkCommand(shim, opts) {
|
|
47923
48023
|
const say = (s) => {
|
|
47924
48024
|
if (!opts.auto)
|
|
47925
48025
|
console.log(s);
|
|
47926
48026
|
};
|
|
47927
48027
|
if (process.platform === "win32")
|
|
47928
|
-
return addToUserPath(
|
|
48028
|
+
return addToUserPath(dirname8(shim), opts.auto, say);
|
|
47929
48029
|
const found = Bun.which("ponzu", { PATH: opts.path.join(delimiter) });
|
|
47930
48030
|
const app = found && opensApp(found) ? found : null;
|
|
47931
48031
|
if (found && !app) {
|
|
@@ -47936,16 +48036,16 @@ async function linkCommand(shim, opts) {
|
|
|
47936
48036
|
const state = readState();
|
|
47937
48037
|
if (opts.auto && state.linked)
|
|
47938
48038
|
return;
|
|
47939
|
-
const before = app ? opts.path.indexOf(
|
|
48039
|
+
const before = app ? opts.path.indexOf(dirname8(app)) : -1;
|
|
47940
48040
|
const dir = commandDirs(opts.home).find((d) => {
|
|
47941
48041
|
const at = opts.path.indexOf(d);
|
|
47942
48042
|
return at >= 0 && (before < 0 || at < before) && canLink(d, opts.home);
|
|
47943
48043
|
});
|
|
47944
48044
|
if (!dir) {
|
|
47945
|
-
say(process.platform === "darwin" ? `To run ponzu from a terminal, add ${
|
|
48045
|
+
say(process.platform === "darwin" ? `To run ponzu from a terminal, add ${dirname8(shim)} to your PATH, or choose Install Terminal Command in Ponzu's app menu.` : `To run ponzu from a terminal, add ${dirname8(shim)} to your PATH.`);
|
|
47946
48046
|
return;
|
|
47947
48047
|
}
|
|
47948
|
-
const link =
|
|
48048
|
+
const link = join16(dir, "ponzu");
|
|
47949
48049
|
try {
|
|
47950
48050
|
await mkdir12(dir, { recursive: true });
|
|
47951
48051
|
await symlink(shim, link);
|
|
@@ -47953,7 +48053,7 @@ async function linkCommand(shim, opts) {
|
|
|
47953
48053
|
say(`Couldn't link ponzu into ${dir}.`);
|
|
47954
48054
|
return;
|
|
47955
48055
|
}
|
|
47956
|
-
await mkdir12(
|
|
48056
|
+
await mkdir12(dirname8(stateFile()), { recursive: true });
|
|
47957
48057
|
await writeFile10(stateFile(), `${JSON.stringify({ linked: link }, null, 2)}
|
|
47958
48058
|
`);
|
|
47959
48059
|
say(`Linked ${link}, so ponzu runs from a terminal.`);
|
|
@@ -47992,21 +48092,21 @@ async function addToUserPath(dir, auto, say) {
|
|
|
47992
48092
|
return;
|
|
47993
48093
|
if (userPath(dir, true) !== "added")
|
|
47994
48094
|
return say(`Couldn't add ${dir} to your PATH. Add it yourself to run ponzu from a terminal.`);
|
|
47995
|
-
await mkdir12(
|
|
48095
|
+
await mkdir12(dirname8(stateFile()), { recursive: true });
|
|
47996
48096
|
await writeFile10(stateFile(), `${JSON.stringify({ linked: dir }, null, 2)}
|
|
47997
48097
|
`);
|
|
47998
48098
|
say(`Added ${dir} to your PATH. Open a new terminal and run ponzu.`);
|
|
47999
48099
|
}
|
|
48000
48100
|
function readState() {
|
|
48001
48101
|
try {
|
|
48002
|
-
return JSON.parse(
|
|
48102
|
+
return JSON.parse(readFileSync4(stateFile(), "utf8"));
|
|
48003
48103
|
} catch {
|
|
48004
48104
|
return {};
|
|
48005
48105
|
}
|
|
48006
48106
|
}
|
|
48007
|
-
function canLink(dir, home =
|
|
48107
|
+
function canLink(dir, home = homedir7()) {
|
|
48008
48108
|
try {
|
|
48009
|
-
lstatSync(
|
|
48109
|
+
lstatSync(join16(dir, "ponzu"));
|
|
48010
48110
|
return false;
|
|
48011
48111
|
} catch {}
|
|
48012
48112
|
if (!existsSync10(dir))
|
|
@@ -48020,7 +48120,7 @@ function canLink(dir, home = homedir6()) {
|
|
|
48020
48120
|
}
|
|
48021
48121
|
function opensApp(file) {
|
|
48022
48122
|
try {
|
|
48023
|
-
return existsSync10(
|
|
48123
|
+
return existsSync10(join16(dirname8(realpathSync3(file)), "resources/server/ponzu"));
|
|
48024
48124
|
} catch {
|
|
48025
48125
|
return false;
|
|
48026
48126
|
}
|
|
@@ -48040,7 +48140,7 @@ var AGENTS = [
|
|
|
48040
48140
|
label: "Claude Code",
|
|
48041
48141
|
detect: () => Boolean(which("claude")),
|
|
48042
48142
|
current: () => {
|
|
48043
|
-
const config = readJson(
|
|
48143
|
+
const config = readJson(join17(homedir8(), ".claude.json"));
|
|
48044
48144
|
return toEntry(config?.mcpServers?.ponzu);
|
|
48045
48145
|
},
|
|
48046
48146
|
register(entry) {
|
|
@@ -48090,7 +48190,7 @@ var AGENTS = [
|
|
|
48090
48190
|
{
|
|
48091
48191
|
id: "cursor",
|
|
48092
48192
|
label: "Cursor",
|
|
48093
|
-
detect: () => existsSync11(
|
|
48193
|
+
detect: () => existsSync11(join17(homedir8(), ".cursor")),
|
|
48094
48194
|
current: () => {
|
|
48095
48195
|
const config = readJson(cursorConfig());
|
|
48096
48196
|
return toEntry(config?.mcpServers?.ponzu);
|
|
@@ -48108,7 +48208,7 @@ var AGENTS = [
|
|
|
48108
48208
|
config = parsed;
|
|
48109
48209
|
}
|
|
48110
48210
|
config.mcpServers = { ...config.mcpServers, ponzu: entry };
|
|
48111
|
-
await mkdir13(
|
|
48211
|
+
await mkdir13(dirname9(path), { recursive: true });
|
|
48112
48212
|
await writeFile11(path, `${JSON.stringify(config, null, 2)}
|
|
48113
48213
|
`);
|
|
48114
48214
|
return true;
|
|
@@ -48177,7 +48277,7 @@ function agentStatus() {
|
|
|
48177
48277
|
}
|
|
48178
48278
|
function codexConfigured() {
|
|
48179
48279
|
try {
|
|
48180
|
-
return /^\[mcp_servers\.ponzu\]/m.test(
|
|
48280
|
+
return /^\[mcp_servers\.ponzu\]/m.test(readFileSync5(join17(process.env.CODEX_HOME ?? join17(homedir8(), ".codex"), "config.toml"), "utf8"));
|
|
48181
48281
|
} catch {
|
|
48182
48282
|
return false;
|
|
48183
48283
|
}
|
|
@@ -48221,22 +48321,22 @@ function shouldAutoRegister(current, setUpBefore) {
|
|
|
48221
48321
|
function isLegacy(e) {
|
|
48222
48322
|
return "url" in e && /^http:\/\/(127\.0\.0\.1|localhost):7777\/mcp\/?$/.test(e.url);
|
|
48223
48323
|
}
|
|
48224
|
-
var doneFile = () =>
|
|
48324
|
+
var doneFile = () => join17(ponzuHome(), "agents.json");
|
|
48225
48325
|
function readDone() {
|
|
48226
48326
|
const raw = readJson(doneFile());
|
|
48227
48327
|
return new Set(raw?.configured ?? []);
|
|
48228
48328
|
}
|
|
48229
48329
|
async function writeDone(done) {
|
|
48230
|
-
await mkdir13(
|
|
48330
|
+
await mkdir13(dirname9(doneFile()), { recursive: true });
|
|
48231
48331
|
await writeFile11(doneFile(), `${JSON.stringify({ configured: [...done].sort() }, null, 2)}
|
|
48232
48332
|
`);
|
|
48233
48333
|
}
|
|
48234
48334
|
function cursorConfig() {
|
|
48235
|
-
return
|
|
48335
|
+
return join17(homedir8(), ".cursor", "mcp.json");
|
|
48236
48336
|
}
|
|
48237
48337
|
function readJson(path) {
|
|
48238
48338
|
try {
|
|
48239
|
-
return JSON.parse(
|
|
48339
|
+
return JSON.parse(readFileSync5(path, "utf8"));
|
|
48240
48340
|
} catch {
|
|
48241
48341
|
return null;
|
|
48242
48342
|
}
|
|
@@ -48245,13 +48345,13 @@ var searchPath;
|
|
|
48245
48345
|
function agentPath() {
|
|
48246
48346
|
if (searchPath !== undefined)
|
|
48247
48347
|
return searchPath;
|
|
48248
|
-
const home =
|
|
48348
|
+
const home = homedir8();
|
|
48249
48349
|
const dirs = [
|
|
48250
48350
|
...(process.env.PATH ?? "").split(delimiter2),
|
|
48251
|
-
|
|
48252
|
-
|
|
48253
|
-
|
|
48254
|
-
|
|
48351
|
+
join17(home, ".local/bin"),
|
|
48352
|
+
join17(home, ".claude/local"),
|
|
48353
|
+
join17(home, ".bun/bin"),
|
|
48354
|
+
join17(home, ".npm-global/bin"),
|
|
48255
48355
|
"/opt/homebrew/bin",
|
|
48256
48356
|
"/usr/local/bin",
|
|
48257
48357
|
...loginPath()
|
|
@@ -48311,13 +48411,13 @@ function run(cmd, quiet = false) {
|
|
|
48311
48411
|
// apps/cli/src/source.ts
|
|
48312
48412
|
import { createHash as createHash5 } from "crypto";
|
|
48313
48413
|
import { existsSync as existsSync12 } from "fs";
|
|
48314
|
-
import { dirname as
|
|
48414
|
+
import { dirname as dirname10, join as join18, sep as sep4 } from "path";
|
|
48315
48415
|
import { fileURLToPath } from "url";
|
|
48316
48416
|
function sourceCheckout(file = fileURLToPath(import.meta.url)) {
|
|
48317
48417
|
if (file.startsWith("/$bunfs/") || file.split(sep4).includes("node_modules"))
|
|
48318
48418
|
return null;
|
|
48319
|
-
for (let dir =
|
|
48320
|
-
if (existsSync12(
|
|
48419
|
+
for (let dir = dirname10(file);dir !== dirname10(dir); dir = dirname10(dir))
|
|
48420
|
+
if (existsSync12(join18(dir, ".git")))
|
|
48321
48421
|
return dir;
|
|
48322
48422
|
return null;
|
|
48323
48423
|
}
|
|
@@ -48355,13 +48455,13 @@ function firstFree(ports, hostname) {
|
|
|
48355
48455
|
|
|
48356
48456
|
// apps/cli/src/telemetry.ts
|
|
48357
48457
|
import { createHash as createHash6, randomUUID } from "crypto";
|
|
48358
|
-
import { readFileSync as
|
|
48458
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
48359
48459
|
import { mkdir as mkdir14, rename as rename10, writeFile as writeFile12 } from "fs/promises";
|
|
48360
48460
|
import { arch, platform as platform2 } from "os";
|
|
48361
|
-
import { dirname as
|
|
48461
|
+
import { dirname as dirname12, join as join19 } from "path";
|
|
48362
48462
|
|
|
48363
48463
|
// node_modules/.bun/posthog-node@5.56.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
48364
|
-
import { dirname as
|
|
48464
|
+
import { dirname as dirname11, posix as posix2, sep as sep5 } from "path";
|
|
48365
48465
|
function createModulerModifier() {
|
|
48366
48466
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
48367
48467
|
return async (frames) => {
|
|
@@ -48370,7 +48470,7 @@ function createModulerModifier() {
|
|
|
48370
48470
|
return frames;
|
|
48371
48471
|
};
|
|
48372
48472
|
}
|
|
48373
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
48473
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname11(process.argv[1]) : process.cwd(), isWindows = sep5 === "\\") {
|
|
48374
48474
|
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
48375
48475
|
return (filename) => {
|
|
48376
48476
|
if (!filename)
|
|
@@ -57650,17 +57750,17 @@ var CATEGORY = {
|
|
|
57650
57750
|
praise: "Praise",
|
|
57651
57751
|
other: "Other"
|
|
57652
57752
|
};
|
|
57653
|
-
var settingsFile = () =>
|
|
57753
|
+
var settingsFile = () => join19(ponzuHome(), "telemetry.json");
|
|
57654
57754
|
function readSettings() {
|
|
57655
57755
|
try {
|
|
57656
|
-
return JSON.parse(
|
|
57756
|
+
return JSON.parse(readFileSync6(settingsFile(), "utf8"));
|
|
57657
57757
|
} catch (err) {
|
|
57658
57758
|
return err.code === "ENOENT" ? {} : null;
|
|
57659
57759
|
}
|
|
57660
57760
|
}
|
|
57661
57761
|
async function writeSettings(settings) {
|
|
57662
57762
|
const path = settingsFile();
|
|
57663
|
-
await mkdir14(
|
|
57763
|
+
await mkdir14(dirname12(path), { recursive: true });
|
|
57664
57764
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
57665
57765
|
await writeFile12(tmp, `${JSON.stringify(settings, null, 2)}
|
|
57666
57766
|
`);
|
|
@@ -57836,14 +57936,14 @@ async function telemetryCommand(arg = "status") {
|
|
|
57836
57936
|
// apps/cli/src/wake.ts
|
|
57837
57937
|
import { dlopen, FFIType, ptr } from "bun:ffi";
|
|
57838
57938
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
57839
|
-
import { fstatSync, readFileSync as
|
|
57939
|
+
import { fstatSync, readFileSync as readFileSync7 } from "fs";
|
|
57840
57940
|
import { mkdir as mkdir15, rm as rm6, writeFile as writeFile13 } from "fs/promises";
|
|
57841
|
-
import { homedir as
|
|
57842
|
-
import { join as
|
|
57941
|
+
import { homedir as homedir9 } from "os";
|
|
57942
|
+
import { join as join20 } from "path";
|
|
57843
57943
|
var WAKE_LABEL = "design.ponzu.app.wake";
|
|
57844
57944
|
var WAKE_PORT = 7778;
|
|
57845
|
-
var agentsDir = () => process.env.PONZU_LAUNCH_AGENTS ??
|
|
57846
|
-
var wakePlistPath = () =>
|
|
57945
|
+
var agentsDir = () => process.env.PONZU_LAUNCH_AGENTS ?? join20(homedir9(), "Library/LaunchAgents");
|
|
57946
|
+
var wakePlistPath = () => join20(agentsDir(), `${WAKE_LABEL}.plist`);
|
|
57847
57947
|
var xml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
57848
57948
|
function wakePlist(program, port = WAKE_PORT) {
|
|
57849
57949
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -57885,7 +57985,7 @@ async function installWake(program, run = launchctl) {
|
|
|
57885
57985
|
const plist = wakePlist(program);
|
|
57886
57986
|
let current = null;
|
|
57887
57987
|
try {
|
|
57888
|
-
current =
|
|
57988
|
+
current = readFileSync7(path, "utf8");
|
|
57889
57989
|
} catch {}
|
|
57890
57990
|
if (current === plist && run(["print", `${domain()}/${WAKE_LABEL}`]))
|
|
57891
57991
|
return false;
|
|
@@ -57899,7 +57999,7 @@ async function uninstallWake(run = launchctl) {
|
|
|
57899
57999
|
run(["bootout", `${domain()}/${WAKE_LABEL}`]);
|
|
57900
58000
|
await rm6(wakePlistPath(), { force: true });
|
|
57901
58001
|
}
|
|
57902
|
-
var systemdDir = () => process.env.PONZU_SYSTEMD_USER ??
|
|
58002
|
+
var systemdDir = () => process.env.PONZU_SYSTEMD_USER ?? join20(process.env.XDG_CONFIG_HOME || join20(homedir9(), ".config"), "systemd/user");
|
|
57903
58003
|
var WAKE_SOCKET = "ponzu-wake.socket";
|
|
57904
58004
|
var WAKE_SERVICE = "ponzu-wake@.service";
|
|
57905
58005
|
var systemdWord = (s) => `"${s.replace(/[\\"]/g, "\\$&").replace(/%/g, "%%").replace(/\$/g, "$$$$")}"`;
|
|
@@ -57933,7 +58033,7 @@ async function installSystemdWake(program, run = systemctl) {
|
|
|
57933
58033
|
const units = wakeUnits(program);
|
|
57934
58034
|
const current = Object.entries(units).every(([name, text]) => {
|
|
57935
58035
|
try {
|
|
57936
|
-
return
|
|
58036
|
+
return readFileSync7(join20(systemdDir(), name), "utf8") === text;
|
|
57937
58037
|
} catch {
|
|
57938
58038
|
return false;
|
|
57939
58039
|
}
|
|
@@ -57942,7 +58042,7 @@ async function installSystemdWake(program, run = systemctl) {
|
|
|
57942
58042
|
return false;
|
|
57943
58043
|
await mkdir15(systemdDir(), { recursive: true });
|
|
57944
58044
|
for (const [name, text] of Object.entries(units))
|
|
57945
|
-
await writeFile13(
|
|
58045
|
+
await writeFile13(join20(systemdDir(), name), text);
|
|
57946
58046
|
run(["daemon-reload"]);
|
|
57947
58047
|
run(["enable", WAKE_SOCKET]);
|
|
57948
58048
|
run(["restart", WAKE_SOCKET]);
|
|
@@ -57951,7 +58051,7 @@ async function installSystemdWake(program, run = systemctl) {
|
|
|
57951
58051
|
async function uninstallSystemdWake(run = systemctl) {
|
|
57952
58052
|
run(["disable", "--now", WAKE_SOCKET]);
|
|
57953
58053
|
for (const name of [WAKE_SOCKET, WAKE_SERVICE])
|
|
57954
|
-
await rm6(
|
|
58054
|
+
await rm6(join20(systemdDir(), name), { force: true });
|
|
57955
58055
|
run(["daemon-reload"]);
|
|
57956
58056
|
}
|
|
57957
58057
|
function peerKind(ip) {
|
|
@@ -58116,7 +58216,7 @@ function lsofPeer() {
|
|
|
58116
58216
|
|
|
58117
58217
|
// apps/cli/src/index.ts
|
|
58118
58218
|
var VERSION2 = package_default.version;
|
|
58119
|
-
var here =
|
|
58219
|
+
var here = dirname13(fileURLToPath2(import.meta.url));
|
|
58120
58220
|
var HELP = `Ponzu ${VERSION2}: the open source canvas your agent draws on in HTML and CSS.
|
|
58121
58221
|
|
|
58122
58222
|
Usage
|
|
@@ -58241,7 +58341,7 @@ async function openWorkspace(files, log) {
|
|
|
58241
58341
|
const paths = files.length ? files.map((f) => resolve5(f)) : await findDesigns(process.cwd());
|
|
58242
58342
|
const named = [];
|
|
58243
58343
|
for (const p of paths) {
|
|
58244
|
-
if (!existsSync13(
|
|
58344
|
+
if (!existsSync13(join21(p, "design.json")) && existsSync13(p) === false && files.length) {
|
|
58245
58345
|
log(`Creating ${p}`);
|
|
58246
58346
|
}
|
|
58247
58347
|
const { key } = await ws.open(p);
|
|
@@ -58253,7 +58353,8 @@ async function openWorkspace(files, log) {
|
|
|
58253
58353
|
telemetry?.capture("host started", {
|
|
58254
58354
|
launched_by: process.env.PONZU_LAUNCHED_BY ?? "person",
|
|
58255
58355
|
designs: ws.designs().length,
|
|
58256
|
-
renderer: Boolean(renderer)
|
|
58356
|
+
renderer: Boolean(renderer),
|
|
58357
|
+
...process.env.PONZU_UPDATE ? { update: process.env.PONZU_UPDATE } : {}
|
|
58257
58358
|
});
|
|
58258
58359
|
return { ws, telemetry, named };
|
|
58259
58360
|
}
|
|
@@ -58267,14 +58368,14 @@ async function runServe(files, o) {
|
|
|
58267
58368
|
root: process.cwd(),
|
|
58268
58369
|
tailnet: o.tailnet,
|
|
58269
58370
|
tailnetPort: 7777,
|
|
58270
|
-
dbFile:
|
|
58271
|
-
stateFile:
|
|
58371
|
+
dbFile: join21(ponzuHome(), "ponzu.db"),
|
|
58372
|
+
stateFile: join21(ponzuHome(), "catalog.json"),
|
|
58272
58373
|
spotlight: process.env.PONZU_SPOTLIGHT === "0" ? false : undefined,
|
|
58273
58374
|
agents: async () => agents(),
|
|
58274
58375
|
suggest: {
|
|
58275
58376
|
bin: (agent) => agentCli(agent),
|
|
58276
58377
|
env: agentEnv(),
|
|
58277
|
-
file:
|
|
58378
|
+
file: join21(ponzuHome(), "suggestions.json")
|
|
58278
58379
|
},
|
|
58279
58380
|
opened: named,
|
|
58280
58381
|
version: VERSION2,
|
|
@@ -58381,7 +58482,7 @@ function absolutePaths(args, cwd) {
|
|
|
58381
58482
|
}
|
|
58382
58483
|
async function runInit(target = "design/untitled.design") {
|
|
58383
58484
|
const path = resolve5(target.endsWith(".design") ? target : `${target}.design`);
|
|
58384
|
-
if (existsSync13(
|
|
58485
|
+
if (existsSync13(join21(path, "design.json"))) {
|
|
58385
58486
|
console.error(`${path} already exists.`);
|
|
58386
58487
|
process.exit(1);
|
|
58387
58488
|
}
|
|
@@ -58403,11 +58504,11 @@ Next: ponzu serve ${target}`);
|
|
|
58403
58504
|
}
|
|
58404
58505
|
function findStudio() {
|
|
58405
58506
|
const candidates = [
|
|
58406
|
-
|
|
58407
|
-
|
|
58408
|
-
|
|
58507
|
+
join21(here, "../studio"),
|
|
58508
|
+
join21(here, "../../studio/dist"),
|
|
58509
|
+
join21(here, "../../../apps/studio/dist")
|
|
58409
58510
|
];
|
|
58410
|
-
return candidates.find((c) => existsSync13(
|
|
58511
|
+
return candidates.find((c) => existsSync13(join21(c, "index.html")));
|
|
58411
58512
|
}
|
|
58412
58513
|
function lanAddresses() {
|
|
58413
58514
|
const out = [];
|