@wrongstack/webui 0.104.0 → 0.109.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.
@@ -1615,6 +1615,25 @@ function openBrowser(url, platform = process.platform) {
1615
1615
  child.on("error", () => {
1616
1616
  });
1617
1617
  child.unref();
1618
+ if (child.pid) {
1619
+ try {
1620
+ import("@wrongstack/tools").then(({ getProcessRegistry }) => {
1621
+ getProcessRegistry().register({
1622
+ pid: child.pid,
1623
+ name: "browser",
1624
+ command: `${command} ${args.join(" ")}`,
1625
+ startedAt: Date.now(),
1626
+ child,
1627
+ protected: true
1628
+ });
1629
+ child.on("exit", () => {
1630
+ getProcessRegistry().unregister(child.pid);
1631
+ });
1632
+ }).catch(() => {
1633
+ });
1634
+ } catch {
1635
+ }
1636
+ }
1618
1637
  } catch {
1619
1638
  }
1620
1639
  }
@@ -3144,6 +3163,111 @@ async function startWebUI(opts = {}) {
3144
3163
  });
3145
3164
  break;
3146
3165
  }
3166
+ case "process.list": {
3167
+ try {
3168
+ const { getProcessRegistry } = await import("@wrongstack/tools");
3169
+ const procs = getProcessRegistry().list();
3170
+ send(ws, {
3171
+ type: "process.list",
3172
+ payload: {
3173
+ processes: procs.map((p) => ({
3174
+ pid: p.pid,
3175
+ command: p.command,
3176
+ tool: p.name,
3177
+ startedAt: p.startedAt,
3178
+ status: p.killed ? "killed" : "running",
3179
+ protected: p.protected
3180
+ }))
3181
+ }
3182
+ });
3183
+ } catch {
3184
+ send(ws, { type: "process.list", payload: { processes: [] } });
3185
+ }
3186
+ break;
3187
+ }
3188
+ case "process.kill": {
3189
+ const { pid } = msg.payload;
3190
+ try {
3191
+ const { getProcessRegistry } = await import("@wrongstack/tools");
3192
+ const proc = getProcessRegistry().get(pid);
3193
+ if (proc?.protected) {
3194
+ sendResult(ws, false, `Cannot kill protected process (PID ${pid})`);
3195
+ break;
3196
+ }
3197
+ getProcessRegistry().kill(pid);
3198
+ sendResult(ws, true, `Killed PID ${pid}`);
3199
+ } catch (err) {
3200
+ sendResult(ws, false, errMessage(err));
3201
+ }
3202
+ break;
3203
+ }
3204
+ case "process.killAll": {
3205
+ try {
3206
+ const { getProcessRegistry } = await import("@wrongstack/tools");
3207
+ getProcessRegistry().killAll();
3208
+ sendResult(ws, true, "All processes killed");
3209
+ } catch (err) {
3210
+ sendResult(ws, false, errMessage(err));
3211
+ }
3212
+ break;
3213
+ }
3214
+ case "goal.get": {
3215
+ try {
3216
+ const goalPath = path4.join(projectRoot, ".wrongstack", "goal.json");
3217
+ const raw = await fs4.readFile(goalPath, "utf8");
3218
+ const goal = JSON.parse(raw);
3219
+ broadcast(clients, { type: "goal.updated", payload: goal });
3220
+ } catch {
3221
+ broadcast(clients, { type: "goal.updated", payload: null });
3222
+ }
3223
+ break;
3224
+ }
3225
+ case "autonomy.switch": {
3226
+ const { mode } = msg.payload;
3227
+ context.meta["autonomy"] = mode;
3228
+ sendResult(ws, true, `Autonomy mode set to "${mode}"`);
3229
+ break;
3230
+ }
3231
+ case "session.checkpoints": {
3232
+ try {
3233
+ const { DefaultSessionRewinder } = await import("@wrongstack/core");
3234
+ const rewinder = new DefaultSessionRewinder(
3235
+ path4.join(projectRoot, ".wrongstack", "sessions"),
3236
+ projectRoot
3237
+ );
3238
+ const checkpoints = await rewinder.listCheckpoints(session.id);
3239
+ send(ws, {
3240
+ type: "session.checkpoints",
3241
+ payload: { checkpoints }
3242
+ });
3243
+ } catch (err) {
3244
+ send(ws, {
3245
+ type: "session.checkpoints",
3246
+ payload: { checkpoints: [] }
3247
+ });
3248
+ }
3249
+ break;
3250
+ }
3251
+ case "session.rewind": {
3252
+ const { checkpointIndex } = msg.payload;
3253
+ try {
3254
+ const { DefaultSessionRewinder } = await import("@wrongstack/core");
3255
+ const rewinder = new DefaultSessionRewinder(
3256
+ path4.join(projectRoot, ".wrongstack", "sessions"),
3257
+ projectRoot
3258
+ );
3259
+ await rewinder.rewindToCheckpoint(session.id, checkpointIndex);
3260
+ await context.session.truncateToCheckpoint(checkpointIndex);
3261
+ sendResult(ws, true, `Rewound to checkpoint ${checkpointIndex}`);
3262
+ broadcast(clients, {
3263
+ type: "session.start",
3264
+ payload: { ...await sessionStartPayload(), reset: true }
3265
+ });
3266
+ } catch (err) {
3267
+ sendResult(ws, false, errMessage(err));
3268
+ }
3269
+ break;
3270
+ }
3147
3271
  default:
3148
3272
  if (msg.type.startsWith("autophase.")) {
3149
3273
  await autoPhaseHandler.handleMessage(