@ctrl-spc/cli 1.3.3 → 1.3.4
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/commands/run.js +6 -5
- package/dist/companion-ui.js +4 -3
- package/dist/runtime-control.js +7 -2
- package/package.json +1 -1
package/dist/commands/run.js
CHANGED
|
@@ -697,8 +697,9 @@ export function createProjectPresenceReconciler(client, userId, profileName, mac
|
|
|
697
697
|
const intervalMs = deps.intervalMs ?? 30_000;
|
|
698
698
|
let timer;
|
|
699
699
|
let chain = Promise.resolve();
|
|
700
|
-
const runReconcile = async () => {
|
|
701
|
-
|
|
700
|
+
const runReconcile = async (refreshWorkspaces) => {
|
|
701
|
+
if (refreshWorkspaces)
|
|
702
|
+
await deps.refreshWorkspaces?.();
|
|
702
703
|
const projects = await loadProjects(client, userId, machine.id);
|
|
703
704
|
const currentIds = new Set(projects.map((project) => project.id));
|
|
704
705
|
for (const project of projects) {
|
|
@@ -722,10 +723,10 @@ export function createProjectPresenceReconciler(client, userId, profileName, mac
|
|
|
722
723
|
}
|
|
723
724
|
};
|
|
724
725
|
return {
|
|
725
|
-
reconcile() {
|
|
726
|
+
reconcile(options = {}) {
|
|
726
727
|
// Recover the queue after a transient failed poll; the caller still
|
|
727
728
|
// receives this run's rejection, but later intervals keep reconciling.
|
|
728
|
-
chain = chain.catch(() => { }).then(runReconcile);
|
|
729
|
+
chain = chain.catch(() => { }).then(() => runReconcile(options.refreshWorkspaces !== false));
|
|
729
730
|
return chain;
|
|
730
731
|
},
|
|
731
732
|
start() {
|
|
@@ -841,7 +842,7 @@ export async function run() {
|
|
|
841
842
|
loadProjects: loadRunnableMachineProjects,
|
|
842
843
|
refreshWorkspaces: () => reconcileMachineWorkspaces(client, userId, machine),
|
|
843
844
|
});
|
|
844
|
-
await presence.reconcile();
|
|
845
|
+
await presence.reconcile({ refreshWorkspaces: false });
|
|
845
846
|
presence.start();
|
|
846
847
|
let mcpServer;
|
|
847
848
|
try {
|
package/dist/companion-ui.js
CHANGED
|
@@ -1143,17 +1143,18 @@ export function renderCompanionUi(token, kind, runtimePort = kind === 'local' ?
|
|
|
1143
1143
|
const profile = snapshot.profiles.find((candidate) => candidate.kind === kind);
|
|
1144
1144
|
const action = profile.state === 'ready' ? 'stop' : 'start';
|
|
1145
1145
|
lastError = '';
|
|
1146
|
+
let succeeded = false;
|
|
1146
1147
|
setBusy(true, action === 'start' ? 'Switching connection…' : 'Turning connection off…');
|
|
1147
1148
|
try {
|
|
1148
|
-
await api('/api/runtime/' + kind + '/' + action, { method: 'POST' });
|
|
1149
|
-
|
|
1149
|
+
render(await api('/api/runtime/' + kind + '/' + action, { method: 'POST' }));
|
|
1150
|
+
succeeded = true;
|
|
1150
1151
|
} catch (error) {
|
|
1151
1152
|
lastError = error.message;
|
|
1152
1153
|
notice.className = 'notice error';
|
|
1153
1154
|
notice.textContent = lastError;
|
|
1154
1155
|
} finally {
|
|
1155
1156
|
setBusy(false);
|
|
1156
|
-
await refresh(false);
|
|
1157
|
+
if (!succeeded) await refresh(false);
|
|
1157
1158
|
}
|
|
1158
1159
|
}
|
|
1159
1160
|
|
package/dist/runtime-control.js
CHANGED
|
@@ -215,7 +215,7 @@ export async function startRuntime(kind) {
|
|
|
215
215
|
throw new Error(`Port ${profile.port} is already used by an unlabeled process. Turn it off before continuing.`);
|
|
216
216
|
}
|
|
217
217
|
mkdirSync(runtimeDir(), { recursive: true });
|
|
218
|
-
const logFd = openSync(logPath(kind), '
|
|
218
|
+
const logFd = openSync(logPath(kind), 'w', 0o600);
|
|
219
219
|
let child;
|
|
220
220
|
try {
|
|
221
221
|
child = spawn(process.execPath, [profile.entryPath, '__broker'], {
|
|
@@ -236,11 +236,16 @@ export async function startRuntime(kind) {
|
|
|
236
236
|
if (!child.pid)
|
|
237
237
|
throw new Error(`${profile.label} did not start.`);
|
|
238
238
|
writePrivateFile(pidPath(kind), String(child.pid));
|
|
239
|
+
let childExited = false;
|
|
240
|
+
child.once('exit', () => { childExited = true; });
|
|
239
241
|
const ready = await waitFor(async () => {
|
|
242
|
+
if (childExited)
|
|
243
|
+
return true;
|
|
240
244
|
const health = await probeBroker(profile.port);
|
|
241
245
|
return health?.runtime?.kind === kind;
|
|
242
246
|
}, 30_000, 250);
|
|
243
|
-
|
|
247
|
+
const health = await probeBroker(profile.port);
|
|
248
|
+
if (!ready || health?.runtime?.kind !== kind) {
|
|
244
249
|
rmSync(pidPath(kind), { force: true });
|
|
245
250
|
const log = existsSync(logPath(kind)) ? readFileSync(logPath(kind), 'utf8').trim().split('\n').slice(-4).join('\n') : '';
|
|
246
251
|
throw new Error(`${profile.label} did not become ready.${log ? `\n${log}` : ''}`);
|