promptcase 1.0.5 → 1.0.6
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 +1 -0
- package/dist/commands/init.js +27 -6
- package/dist/index.js +0 -0
- package/dist/services/daemon.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ The daemon auto-starts on login/boot and runs in the background.
|
|
|
40
40
|
| `promptcase show` | Show recent synced prompts |
|
|
41
41
|
| `promptcase stop` | Stop the running daemon (auto-start is preserved for next boot) |
|
|
42
42
|
| `promptcase logout` | Stop daemon, revoke token, clear credentials |
|
|
43
|
+
| `promptcase start` | **Internal** — run the daemon in the foreground. Invoked by the auto-start service (LaunchAgent / systemd / Startup folder). You don't normally need to run this directly. |
|
|
43
44
|
|
|
44
45
|
## How it works
|
|
45
46
|
|
package/dist/commands/init.js
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
import inquirer from 'inquirer';
|
|
9
9
|
import { Command } from 'commander';
|
|
10
10
|
import { exec, spawn } from 'child_process';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import os from 'os';
|
|
13
|
+
import path from 'path';
|
|
11
14
|
import { APIService } from '../services/api.js';
|
|
12
15
|
import { DaemonService } from '../services/daemon.js';
|
|
13
16
|
import { getConfig } from '../lib/config.js';
|
|
@@ -89,6 +92,15 @@ async function verifyAndShowUser(api) {
|
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
91
94
|
* Start daemon in detached background process
|
|
95
|
+
*
|
|
96
|
+
* Polls for the lock dir to appear (the daemon writes the lock as soon as it
|
|
97
|
+
* finishes starting). This avoids the previous 1500ms fixed wait that would
|
|
98
|
+
* give false "Daemon may not have started" warnings on slow machines where
|
|
99
|
+
* Node + module load + lock acquisition took longer than 1500ms — the daemon
|
|
100
|
+
* would actually be running, but the parent had already given up and
|
|
101
|
+
* returned, leaving the user to think the spawn failed. The 1500ms was a
|
|
102
|
+
* too-tight deadline and the real signal is "lock dir exists" which means
|
|
103
|
+
* "daemon is fully initialized".
|
|
92
104
|
*/
|
|
93
105
|
async function startDaemonDetached(apiUrl) {
|
|
94
106
|
// Detach the daemon process so it runs independently
|
|
@@ -98,12 +110,21 @@ async function startDaemonDetached(apiUrl) {
|
|
|
98
110
|
windowsHide: true,
|
|
99
111
|
});
|
|
100
112
|
child.unref();
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
113
|
+
// Poll for the lock to appear. The daemon writes the lock dir as the
|
|
114
|
+
// first step of its lifecycle, so seeing it is a reliable "running" signal.
|
|
115
|
+
// Cap at 10 seconds — if the lock hasn't appeared by then, the daemon
|
|
116
|
+
// process must have died.
|
|
117
|
+
const lockPath = path.join(os.homedir(), '.promptcase', 'daemon.pid.lock');
|
|
118
|
+
const deadline = Date.now() + 10_000;
|
|
119
|
+
let acquired = false;
|
|
120
|
+
while (Date.now() < deadline) {
|
|
121
|
+
if (fs.existsSync(lockPath)) {
|
|
122
|
+
acquired = true;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
126
|
+
}
|
|
127
|
+
if (acquired) {
|
|
107
128
|
console.log(' ✅ Daemon started in background');
|
|
108
129
|
}
|
|
109
130
|
else {
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/services/daemon.js
CHANGED
|
@@ -114,6 +114,14 @@ export class DaemonService {
|
|
|
114
114
|
async acquireExclusiveLock() {
|
|
115
115
|
try {
|
|
116
116
|
const lockDir = this.pidFile + '.lock';
|
|
117
|
+
// Ensure the parent dir exists before we try to mkdir the lock inside
|
|
118
|
+
// it. Without this, the very first run on a clean machine gets ENOENT
|
|
119
|
+
// because ~/.promptcase/ doesn't exist yet (writePidFile creates it
|
|
120
|
+
// later, but only if it gets to run).
|
|
121
|
+
const parentDir = path.dirname(lockDir);
|
|
122
|
+
if (!fs.existsSync(parentDir)) {
|
|
123
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
124
|
+
}
|
|
117
125
|
try {
|
|
118
126
|
fs.mkdirSync(lockDir);
|
|
119
127
|
// We won the race — write our PID into the lock dir for diagnostics
|