piu-piu-cli 0.1.0 → 0.1.1
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/CHANGELOG.md +4 -0
- package/README.md +1 -1
- package/bin/piu-piu.mjs +23 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://unpkg.com/piu-piu-cli@0.1.
|
|
2
|
+
<img src="https://unpkg.com/piu-piu-cli@0.1.1/docs/banner.svg" alt="piu-piu: a 3D office for your Claude Code agents" width="100%">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
package/bin/piu-piu.mjs
CHANGED
|
@@ -33,6 +33,22 @@ const fail = (msg) => {
|
|
|
33
33
|
process.exit(1);
|
|
34
34
|
};
|
|
35
35
|
const quiet = (cmd, args) => spawnSync(cmd, args, { stdio: 'pipe', encoding: 'utf8' });
|
|
36
|
+
const sleepSync = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
37
|
+
|
|
38
|
+
// launchd unloads asynchronously: loading again too soon fails with
|
|
39
|
+
// "Bootstrap failed: 5". Unload, wait until it's gone, then load (retrying once).
|
|
40
|
+
function launchdUnload(target) {
|
|
41
|
+
quiet('launchctl', ['bootout', target]);
|
|
42
|
+
for (let i = 0; i < 40 && quiet('launchctl', ['print', target]).status === 0; i++) sleepSync(250);
|
|
43
|
+
}
|
|
44
|
+
function launchdLoad(domain, plist) {
|
|
45
|
+
let r = quiet('launchctl', ['bootstrap', domain, plist]);
|
|
46
|
+
for (let i = 0; i < 3 && r.status !== 0; i++) {
|
|
47
|
+
sleepSync(1000);
|
|
48
|
+
r = quiet('launchctl', ['bootstrap', domain, plist]);
|
|
49
|
+
}
|
|
50
|
+
return r;
|
|
51
|
+
}
|
|
36
52
|
|
|
37
53
|
function claudeBinary() {
|
|
38
54
|
for (const p of [join(homedir(), '.local', 'bin', 'claude'), '/opt/homebrew/bin/claude', '/usr/local/bin/claude']) if (existsSync(p)) return p;
|
|
@@ -138,9 +154,9 @@ function serviceInstall() {
|
|
|
138
154
|
if (MAC) {
|
|
139
155
|
const domain = `gui/${process.getuid()}`;
|
|
140
156
|
// the pre-rename service, if this Mac still has it
|
|
141
|
-
|
|
157
|
+
launchdUnload(`${domain}/${LEGACY_LABEL}`);
|
|
142
158
|
rmSync(join(homedir(), 'Library', 'LaunchAgents', `${LEGACY_LABEL}.plist`), { force: true });
|
|
143
|
-
|
|
159
|
+
launchdUnload(`${domain}/${LABEL}`);
|
|
144
160
|
const env = [['PATH', servicePath()], ['HOME', homedir()], ...passEnv()].map(([k, v]) => ` <key>${esc(k)}</key><string>${esc(v)}</string>`).join('\n');
|
|
145
161
|
mkdirSync(dirname(PLIST), { recursive: true });
|
|
146
162
|
mkdirSync(dirname(LOG), { recursive: true });
|
|
@@ -170,8 +186,8 @@ ${env}
|
|
|
170
186
|
</plist>
|
|
171
187
|
`,
|
|
172
188
|
);
|
|
173
|
-
const r =
|
|
174
|
-
if (r.status !== 0) fail(`launchctl could not start the service: ${r.stderr}`);
|
|
189
|
+
const r = launchdLoad(domain, PLIST);
|
|
190
|
+
if (r.status !== 0) fail(`launchctl could not start the service: ${r.stderr.trim()}. Try: piu-piu start`);
|
|
175
191
|
} else {
|
|
176
192
|
if (quiet('systemctl', ['--user', '--version']).status !== 0) fail('No systemd user session here. Run the office in the foreground instead: piu-piu run');
|
|
177
193
|
mkdirSync(dirname(UNIT), { recursive: true });
|
|
@@ -204,7 +220,7 @@ WantedBy=default.target
|
|
|
204
220
|
|
|
205
221
|
function serviceUninstall() {
|
|
206
222
|
if (MAC) {
|
|
207
|
-
|
|
223
|
+
launchdUnload(`gui/${process.getuid()}/${LABEL}`);
|
|
208
224
|
rmSync(PLIST, { force: true });
|
|
209
225
|
} else {
|
|
210
226
|
quiet('systemctl', ['--user', 'disable', '--now', 'piu-piu.service']);
|
|
@@ -231,7 +247,7 @@ function open() {
|
|
|
231
247
|
async function start() {
|
|
232
248
|
if (await state()) return say(c.ok('✓'), `piu-piu is running at ${c.b(URL)}`);
|
|
233
249
|
if (!serviceInstalled()) serviceInstall();
|
|
234
|
-
else if (MAC)
|
|
250
|
+
else if (MAC) launchdLoad(`gui/${process.getuid()}`, PLIST);
|
|
235
251
|
else quiet('systemctl', ['--user', 'start', 'piu-piu.service']);
|
|
236
252
|
if (!(await waitUp())) fail(`piu-piu didn't come up. Check the logs: piu-piu logs`);
|
|
237
253
|
say(c.ok('✓'), `piu-piu is running at ${c.b(URL)}`);
|
|
@@ -239,7 +255,7 @@ async function start() {
|
|
|
239
255
|
|
|
240
256
|
async function stop() {
|
|
241
257
|
await guardBusy('Stopping');
|
|
242
|
-
if (MAC)
|
|
258
|
+
if (MAC) launchdUnload(`gui/${process.getuid()}/${LABEL}`);
|
|
243
259
|
else quiet('systemctl', ['--user', 'stop', 'piu-piu.service']);
|
|
244
260
|
say(c.ok('✓'), 'piu-piu stopped. Start it again with: piu-piu start');
|
|
245
261
|
}
|
package/package.json
CHANGED