@staff0rd/assist 0.562.1 → 0.564.0

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 CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.562.1",
9
+ version: "0.564.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -13790,9 +13790,126 @@ function registerCloneCommand(cmd) {
13790
13790
 
13791
13791
  // src/commands/backlog/comment/index.ts
13792
13792
  import chalk71 from "chalk";
13793
+
13794
+ // src/commands/backlog/comment/reviewProposedComment.ts
13795
+ import { randomUUID as randomUUID2 } from "crypto";
13796
+
13797
+ // src/commands/sessions/shared/reportPreviewRejection.ts
13798
+ function reportPreviewRejection(subject, decision) {
13799
+ console.error(
13800
+ `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
13801
+ );
13802
+ const comments3 = decision.comments ?? [];
13803
+ if (comments3.length > 0) {
13804
+ console.error(
13805
+ `
13806
+ The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Address each one, then re-run this command:
13807
+ `
13808
+ );
13809
+ for (const [i, c] of comments3.entries()) {
13810
+ const quoted = c.quote.split("\n").map((line) => ` > ${line}`).join("\n");
13811
+ console.error(`${i + 1}. On:
13812
+ ${quoted}
13813
+ Comment: ${c.note}
13814
+ `);
13815
+ }
13816
+ }
13817
+ process.exit(1);
13818
+ }
13819
+
13820
+ // src/commands/sessions/shared/toPreviewDecision.ts
13821
+ function toPreviewDecision(msg) {
13822
+ if (msg.decision !== "approve" && msg.decision !== "reject") return null;
13823
+ return {
13824
+ decision: msg.decision,
13825
+ reason: msg.reason,
13826
+ comments: Array.isArray(msg.comments) ? msg.comments : void 0,
13827
+ screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
13828
+ reviewAfter: msg.reviewAfter === true,
13829
+ announceAfter: msg.announceAfter === true,
13830
+ draft: typeof msg.draft === "boolean" ? msg.draft : void 0
13831
+ };
13832
+ }
13833
+
13834
+ // src/commands/sessions/shared/parsePreviewDecision.ts
13835
+ function parsePreviewDecision(line, requestId) {
13836
+ try {
13837
+ const msg = JSON.parse(line);
13838
+ if (msg.type === "error" && (msg.message ?? "").includes("pr-preview"))
13839
+ return { kind: "error", message: msg.message ?? "pr-preview failed" };
13840
+ if (msg.type !== "pr-decision" || msg.requestId !== requestId) return null;
13841
+ const decision = toPreviewDecision(msg);
13842
+ return decision ? { kind: "decision", decision } : null;
13843
+ } catch {
13844
+ return null;
13845
+ }
13846
+ }
13847
+
13848
+ // src/commands/sessions/shared/requestPreviewDecision.ts
13849
+ function requestPreviewDecision(request) {
13850
+ return new Promise((resolve24, reject) => {
13851
+ connectToDaemon().then((socket) => {
13852
+ let settled = false;
13853
+ const finish = (error, decision) => {
13854
+ if (settled) return;
13855
+ settled = true;
13856
+ socket.destroy();
13857
+ if (error) reject(error);
13858
+ else resolve24(decision);
13859
+ };
13860
+ readSocketLines(socket, (line) => {
13861
+ const incoming = parsePreviewDecision(line, request.requestId);
13862
+ if (!incoming) return;
13863
+ if (incoming.kind === "error") finish(new Error(incoming.message));
13864
+ else finish(void 0, incoming.decision);
13865
+ });
13866
+ socket.on("error", (error) => finish(error));
13867
+ socket.on(
13868
+ "close",
13869
+ () => finish(new Error("daemon closed before a decision was made"))
13870
+ );
13871
+ socket.write(`${JSON.stringify({ type: "pr-preview", ...request })}
13872
+ `);
13873
+ }, reject);
13874
+ });
13875
+ }
13876
+
13877
+ // src/commands/sessions/shared/awaitPreviewApproval.ts
13878
+ async function awaitPreviewApproval(subject, request) {
13879
+ console.log("Awaiting your approval in the assist web UI preview pane\u2026");
13880
+ let decision;
13881
+ try {
13882
+ decision = await requestPreviewDecision(request);
13883
+ } catch (error) {
13884
+ console.error(
13885
+ `Error: ${error instanceof Error ? error.message : String(error)}`
13886
+ );
13887
+ process.exit(1);
13888
+ }
13889
+ if (decision.decision === "reject") reportPreviewRejection(subject, decision);
13890
+ return decision;
13891
+ }
13892
+
13893
+ // src/commands/backlog/comment/reviewProposedComment.ts
13894
+ async function reviewProposedComment(item, text18) {
13895
+ const sessionId = process.env.ASSIST_SESSION_ID;
13896
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
13897
+ await awaitPreviewApproval("Backlog comment preview", {
13898
+ sessionId,
13899
+ requestId: randomUUID2(),
13900
+ title: `Comment on ${formatItemId(item.id)}: ${item.name}`,
13901
+ body: text18,
13902
+ prNumber: null,
13903
+ kind: "backlog-item",
13904
+ itemType: item.type
13905
+ });
13906
+ }
13907
+
13908
+ // src/commands/backlog/comment/index.ts
13793
13909
  async function comment(id, text18) {
13794
13910
  const found = await findOneItem(id);
13795
13911
  if (!found) process.exit(1);
13912
+ await reviewProposedComment(found.item, text18);
13796
13913
  await appendComment(found.orm, found.item.id, text18);
13797
13914
  console.log(
13798
13915
  chalk71.green(`Comment added to item ${formatItemId(found.item.id)}.`)
@@ -14302,103 +14419,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
14302
14419
  }
14303
14420
 
14304
14421
  // src/commands/backlog/addPhase/reviewProposedPhase.ts
14305
- import { randomUUID as randomUUID2 } from "crypto";
14306
-
14307
- // src/commands/sessions/shared/reportPreviewRejection.ts
14308
- function reportPreviewRejection(subject, decision) {
14309
- console.error(
14310
- `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
14311
- );
14312
- const comments3 = decision.comments ?? [];
14313
- if (comments3.length > 0) {
14314
- console.error(
14315
- `
14316
- The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Address each one, then re-run this command:
14317
- `
14318
- );
14319
- for (const [i, c] of comments3.entries()) {
14320
- const quoted = c.quote.split("\n").map((line) => ` > ${line}`).join("\n");
14321
- console.error(`${i + 1}. On:
14322
- ${quoted}
14323
- Comment: ${c.note}
14324
- `);
14325
- }
14326
- }
14327
- process.exit(1);
14328
- }
14329
-
14330
- // src/commands/sessions/shared/toPreviewDecision.ts
14331
- function toPreviewDecision(msg) {
14332
- if (msg.decision !== "approve" && msg.decision !== "reject") return null;
14333
- return {
14334
- decision: msg.decision,
14335
- reason: msg.reason,
14336
- comments: Array.isArray(msg.comments) ? msg.comments : void 0,
14337
- screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
14338
- reviewAfter: msg.reviewAfter === true,
14339
- announceAfter: msg.announceAfter === true,
14340
- draft: typeof msg.draft === "boolean" ? msg.draft : void 0
14341
- };
14342
- }
14343
-
14344
- // src/commands/sessions/shared/parsePreviewDecision.ts
14345
- function parsePreviewDecision(line, requestId) {
14346
- try {
14347
- const msg = JSON.parse(line);
14348
- if (msg.type === "error" && (msg.message ?? "").includes("pr-preview"))
14349
- return { kind: "error", message: msg.message ?? "pr-preview failed" };
14350
- if (msg.type !== "pr-decision" || msg.requestId !== requestId) return null;
14351
- const decision = toPreviewDecision(msg);
14352
- return decision ? { kind: "decision", decision } : null;
14353
- } catch {
14354
- return null;
14355
- }
14356
- }
14357
-
14358
- // src/commands/sessions/shared/requestPreviewDecision.ts
14359
- function requestPreviewDecision(request) {
14360
- return new Promise((resolve24, reject) => {
14361
- connectToDaemon().then((socket) => {
14362
- let settled = false;
14363
- const finish = (error, decision) => {
14364
- if (settled) return;
14365
- settled = true;
14366
- socket.destroy();
14367
- if (error) reject(error);
14368
- else resolve24(decision);
14369
- };
14370
- readSocketLines(socket, (line) => {
14371
- const incoming = parsePreviewDecision(line, request.requestId);
14372
- if (!incoming) return;
14373
- if (incoming.kind === "error") finish(new Error(incoming.message));
14374
- else finish(void 0, incoming.decision);
14375
- });
14376
- socket.on("error", (error) => finish(error));
14377
- socket.on(
14378
- "close",
14379
- () => finish(new Error("daemon closed before a decision was made"))
14380
- );
14381
- socket.write(`${JSON.stringify({ type: "pr-preview", ...request })}
14382
- `);
14383
- }, reject);
14384
- });
14385
- }
14386
-
14387
- // src/commands/sessions/shared/awaitPreviewApproval.ts
14388
- async function awaitPreviewApproval(subject, request) {
14389
- console.log("Awaiting your approval in the assist web UI preview pane\u2026");
14390
- let decision;
14391
- try {
14392
- decision = await requestPreviewDecision(request);
14393
- } catch (error) {
14394
- console.error(
14395
- `Error: ${error instanceof Error ? error.message : String(error)}`
14396
- );
14397
- process.exit(1);
14398
- }
14399
- if (decision.decision === "reject") reportPreviewRejection(subject, decision);
14400
- return decision;
14401
- }
14422
+ import { randomUUID as randomUUID3 } from "crypto";
14402
14423
 
14403
14424
  // src/commands/backlog/renderPhaseSection.ts
14404
14425
  function renderPhaseSection(phase, idx) {
@@ -14422,7 +14443,7 @@ async function reviewProposedPhase(item, phaseIdx, phase) {
14422
14443
  return;
14423
14444
  await awaitPreviewApproval("Backlog phase preview", {
14424
14445
  sessionId,
14425
- requestId: randomUUID2(),
14446
+ requestId: randomUUID3(),
14426
14447
  title: `Add a phase to ${formatItemId(item.id)}: ${item.name}`,
14427
14448
  body: renderPhaseSection(phase, phaseIdx),
14428
14449
  prNumber: null,
@@ -14564,7 +14585,7 @@ function readProposedItem(source) {
14564
14585
  }
14565
14586
 
14566
14587
  // src/commands/backlog/propose/reviewProposal.ts
14567
- import { randomUUID as randomUUID3 } from "crypto";
14588
+ import { randomUUID as randomUUID4 } from "crypto";
14568
14589
  import chalk82 from "chalk";
14569
14590
 
14570
14591
  // src/commands/backlog/propose/renderProposedItem.ts
@@ -14587,7 +14608,7 @@ async function reviewProposal(item, sessionId, confirmed) {
14587
14608
  if (sessionId) {
14588
14609
  await awaitPreviewApproval("Backlog item preview", {
14589
14610
  sessionId,
14590
- requestId: randomUUID3(),
14611
+ requestId: randomUUID4(),
14591
14612
  title: item.name,
14592
14613
  body,
14593
14614
  prNumber: null,
@@ -14884,7 +14905,7 @@ import chalk91 from "chalk";
14884
14905
  import enquirer7 from "enquirer";
14885
14906
 
14886
14907
  // src/commands/backlog/launchMode.ts
14887
- import { randomUUID as randomUUID4 } from "crypto";
14908
+ import { randomUUID as randomUUID5 } from "crypto";
14888
14909
 
14889
14910
  // src/commands/backlog/handleLaunchSignal.ts
14890
14911
  import chalk90 from "chalk";
@@ -14989,7 +15010,7 @@ async function launchMode(slashCommand, options2) {
14989
15010
  const resumeSessionId = options2?.resumeSessionId;
14990
15011
  if (!resumeSessionId) pullIfConfigured();
14991
15012
  process.env.ASSIST_SESSION_ID ??= String(process.pid);
14992
- const claudeSessionId = resumeSessionId ?? randomUUID4();
15013
+ const claudeSessionId = resumeSessionId ?? randomUUID5();
14993
15014
  const harness = options2?.harness ?? "claude";
14994
15015
  reportLaunchActivity(slashCommand, claudeSessionId, harness, options2);
14995
15016
  const prompt = resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description);
@@ -16005,7 +16026,7 @@ async function replacePlan(orm, itemId2, phases, currentPhase) {
16005
16026
  }
16006
16027
 
16007
16028
  // src/commands/backlog/updatePlan/reviewPlanUpdate.ts
16008
- import { randomUUID as randomUUID5 } from "crypto";
16029
+ import { randomUUID as randomUUID6 } from "crypto";
16009
16030
  import chalk116 from "chalk";
16010
16031
 
16011
16032
  // src/commands/backlog/updatePlan/isCompleted.ts
@@ -16162,7 +16183,7 @@ async function reviewPlanUpdate(item, phases) {
16162
16183
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
16163
16184
  await awaitPreviewApproval("Plan update preview", {
16164
16185
  sessionId,
16165
- requestId: randomUUID5(),
16186
+ requestId: randomUUID6(),
16166
16187
  title: `Update the plan for ${formatItemId(item.id)}: ${item.name}`,
16167
16188
  body,
16168
16189
  prNumber: null,
@@ -20925,7 +20946,7 @@ function registerRefineLaunch(program2, resumeFlag) {
20925
20946
  }
20926
20947
 
20927
20948
  // src/commands/reviewPrComments.ts
20928
- import { randomUUID as randomUUID6 } from "crypto";
20949
+ import { randomUUID as randomUUID7 } from "crypto";
20929
20950
 
20930
20951
  // src/commands/review/checkoutPr.ts
20931
20952
  import { execFileSync as execFileSync7 } from "child_process";
@@ -21557,7 +21578,7 @@ async function reviewPrComments(number, options2 = {}) {
21557
21578
  const resumeSessionId = options2.resumeSessionId;
21558
21579
  validateAnnounce(number, announce);
21559
21580
  if (number && !resumeSessionId) await checkoutPr(number);
21560
- const claudeSessionId = resumeSessionId ?? randomUUID6();
21581
+ const claudeSessionId = resumeSessionId ?? randomUUID7();
21561
21582
  emitActivity({
21562
21583
  kind: "command",
21563
21584
  name: "review-pr-comments",
@@ -21575,14 +21596,14 @@ async function reviewPrComments(number, options2 = {}) {
21575
21596
  }
21576
21597
 
21577
21598
  // src/commands/fixConflict.ts
21578
- import { randomUUID as randomUUID7 } from "crypto";
21599
+ import { randomUUID as randomUUID8 } from "crypto";
21579
21600
  function buildPrompt3(rebase) {
21580
21601
  return rebase ? "/fix-conflict --rebase" : "/fix-conflict";
21581
21602
  }
21582
21603
  async function fixConflict(number, options2 = {}) {
21583
21604
  const { resumeSessionId } = options2;
21584
21605
  if (number && !resumeSessionId) await checkoutPr(number);
21585
- const claudeSessionId = resumeSessionId ?? randomUUID7();
21606
+ const claudeSessionId = resumeSessionId ?? randomUUID8();
21586
21607
  emitActivity({
21587
21608
  kind: "command",
21588
21609
  name: "fix-conflict",
@@ -22718,7 +22739,7 @@ function comment2(path80, line, body, startLine) {
22718
22739
  }
22719
22740
 
22720
22741
  // src/commands/prs/edit.ts
22721
- import { randomUUID as randomUUID8 } from "crypto";
22742
+ import { randomUUID as randomUUID9 } from "crypto";
22722
22743
 
22723
22744
  // src/commands/prs/appendScreenshots.ts
22724
22745
  function appendScreenshots(body, screenshots) {
@@ -22932,7 +22953,7 @@ async function edit(options2) {
22932
22953
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
22933
22954
  const decision = await awaitPreviewApproval("PR preview", {
22934
22955
  sessionId,
22935
- requestId: randomUUID8(),
22956
+ requestId: randomUUID9(),
22936
22957
  title: options2.title ?? title,
22937
22958
  body: newBody,
22938
22959
  prNumber: number
@@ -23643,7 +23664,7 @@ async function placePr(prNumber, title, body, options2) {
23643
23664
  }
23644
23665
 
23645
23666
  // src/commands/prs/previewAndPlace.ts
23646
- import { randomUUID as randomUUID9 } from "crypto";
23667
+ import { randomUUID as randomUUID10 } from "crypto";
23647
23668
 
23648
23669
  // src/commands/sessions/shared/requestSession.ts
23649
23670
  function parseIncoming(line, type) {
@@ -23778,7 +23799,7 @@ function warn(reason4) {
23778
23799
  async function previewAndPlace(args) {
23779
23800
  const decision = await awaitPreviewApproval("PR preview", {
23780
23801
  sessionId: args.sessionId,
23781
- requestId: randomUUID9(),
23802
+ requestId: randomUUID10(),
23782
23803
  title: args.title,
23783
23804
  body: args.body,
23784
23805
  prNumber: args.prNumber,
@@ -26248,10 +26269,10 @@ function registerRefactor(program2) {
26248
26269
  }
26249
26270
 
26250
26271
  // src/commands/review/checkoutOnlySession.ts
26251
- import { randomUUID as randomUUID10 } from "crypto";
26272
+ import { randomUUID as randomUUID11 } from "crypto";
26252
26273
  async function checkoutOnlySession(number) {
26253
26274
  await checkoutPr(number);
26254
- const claudeSessionId = randomUUID10();
26275
+ const claudeSessionId = randomUUID11();
26255
26276
  emitActivity({ kind: "command", name: "review", claudeSessionId });
26256
26277
  const { done: done2 } = spawnClaude("", {
26257
26278
  permissionMode: "acceptEdits",
@@ -31613,7 +31634,7 @@ var ClientHub = class extends Set {
31613
31634
  };
31614
31635
 
31615
31636
  // src/commands/sessions/daemon/createSession.ts
31616
- import { randomUUID as randomUUID11 } from "crypto";
31637
+ import { randomUUID as randomUUID12 } from "crypto";
31617
31638
 
31618
31639
  // src/commands/sessions/daemon/sessionBase.ts
31619
31640
  function sessionBase(id, status3) {
@@ -31809,7 +31830,7 @@ function spawnRun(opts) {
31809
31830
  function createSession(id, prompt, cwd, design, harness, holdPty) {
31810
31831
  if (harness && harness !== "claude")
31811
31832
  return createHarnessSession(id, harness, prompt, cwd, holdPty);
31812
- const claudeSessionId = randomUUID11();
31833
+ const claudeSessionId = randomUUID12();
31813
31834
  return {
31814
31835
  ...sessionBase(id, prompt ? "running" : "waiting"),
31815
31836
  name: `Session ${id}`,
@@ -33842,7 +33863,7 @@ function codexRespawnPlan(session) {
33842
33863
  }
33843
33864
 
33844
33865
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
33845
- import { randomUUID as randomUUID12 } from "crypto";
33866
+ import { randomUUID as randomUUID13 } from "crypto";
33846
33867
  function interactiveRespawnPlan(session, resumes) {
33847
33868
  const { claudeSessionId, cwd, initialPrompt } = session;
33848
33869
  if (!resumes) return null;
@@ -33860,7 +33881,7 @@ function interactiveRespawnPlan(session, resumes) {
33860
33881
  return null;
33861
33882
  }
33862
33883
  function freshClaudePlan(session, prompt, cwd) {
33863
- const claudeSessionId = randomUUID12();
33884
+ const claudeSessionId = randomUUID13();
33864
33885
  return {
33865
33886
  spawn: () => {
33866
33887
  session.claudeSessionId = claudeSessionId;
@@ -34738,10 +34759,10 @@ function startReusedRunPty(session, assistArgs, itemId2, hold, clients, onStatus
34738
34759
  }
34739
34760
 
34740
34761
  // src/commands/sessions/daemon/createWatcherSession.ts
34741
- import { randomUUID as randomUUID13 } from "crypto";
34762
+ import { randomUUID as randomUUID14 } from "crypto";
34742
34763
  var WATCH_PROMPT = "/watch";
34743
34764
  function createWatcherSession(id, cwd) {
34744
- const claudeSessionId = randomUUID13();
34765
+ const claudeSessionId = randomUUID14();
34745
34766
  return {
34746
34767
  ...sessionBase(id, "running"),
34747
34768
  name: `Session ${id}`,
@@ -35248,10 +35269,28 @@ function stripOutboundSessionId(data) {
35248
35269
  return stripped;
35249
35270
  }
35250
35271
 
35272
+ // src/commands/sessions/daemon/logWindowsForward.ts
35273
+ function logWindowsForward(delivered, type, sessionId) {
35274
+ if (!delivered)
35275
+ daemonLog(
35276
+ `windows proxy: DROPPED ${type} for ${sessionId} (windows connection not writable)`
35277
+ );
35278
+ else if (type !== "input")
35279
+ daemonLog(`windows proxy: forwarded ${type} for ${sessionId}`);
35280
+ }
35281
+
35282
+ // src/commands/sessions/daemon/forwardWindowsIo.ts
35283
+ function forwardWindowsIo(conn, data) {
35284
+ const sessionId = stripWindowsSessionId(data.sessionId);
35285
+ const delivered = conn.trySend({ ...data, sessionId });
35286
+ logWindowsForward(delivered, data.type, data.sessionId);
35287
+ }
35288
+
35251
35289
  // src/commands/sessions/daemon/WindowsProxyState.ts
35252
35290
  var MAX_SCROLLBACK2 = 256 * 1024;
35253
35291
  var DEFAULT_CREATE_TIMEOUT_MS = 5e3;
35254
- function createState(broadcast2, onSessionsChanged, onVersionMismatch, createTimeoutMs = DEFAULT_CREATE_TIMEOUT_MS) {
35292
+ function createState(broadcast2, onSessionsChanged, onVersionMismatch, onVersionOk = () => {
35293
+ }, createTimeoutMs = DEFAULT_CREATE_TIMEOUT_MS) {
35255
35294
  return {
35256
35295
  windowsSessions: [],
35257
35296
  scrollback: /* @__PURE__ */ new Map(),
@@ -35259,7 +35298,8 @@ function createState(broadcast2, onSessionsChanged, onVersionMismatch, createTim
35259
35298
  createTimeoutMs,
35260
35299
  broadcast: broadcast2,
35261
35300
  onSessionsChanged,
35262
- onVersionMismatch
35301
+ onVersionMismatch,
35302
+ onVersionOk
35263
35303
  };
35264
35304
  }
35265
35305
  function resetState(state) {
@@ -35337,7 +35377,11 @@ function windowsVersionCheck() {
35337
35377
 
35338
35378
  // src/commands/sessions/daemon/handleHello.ts
35339
35379
  function handleHello(state, msg) {
35340
- if (!isHello(msg) || helloCompatible(msg)) return;
35380
+ if (!isHello(msg)) return;
35381
+ if (helloCompatible(msg)) {
35382
+ state.onVersionOk();
35383
+ return;
35384
+ }
35341
35385
  const mode = windowsVersionCheck();
35342
35386
  const mismatch = `windows daemon ${helloMismatchKind(msg)} mismatch`;
35343
35387
  const detail = `protocol ${msg.protocol ?? "legacy"} version ${msg.version} (wsl protocol ${PROTOCOL_VERSION} version ${ASSIST_VERSION})`;
@@ -35473,16 +35517,6 @@ function isWindowsIo(data) {
35473
35517
  return typeof data.sessionId === "string" && isWindowsSessionId(data.sessionId);
35474
35518
  }
35475
35519
 
35476
- // src/commands/sessions/daemon/logWindowsForward.ts
35477
- function logWindowsForward(delivered, type, sessionId) {
35478
- if (!delivered)
35479
- daemonLog(
35480
- `windows proxy: DROPPED ${type} for ${sessionId} (windows connection not writable)`
35481
- );
35482
- else if (type !== "input")
35483
- daemonLog(`windows proxy: forwarded ${type} for ${sessionId}`);
35484
- }
35485
-
35486
35520
  // src/commands/sessions/daemon/WindowsConnection.ts
35487
35521
  import { createInterface as createInterface9 } from "readline";
35488
35522
 
@@ -35609,6 +35643,7 @@ function notifyHealing(state) {
35609
35643
 
35610
35644
  // src/commands/sessions/daemon/WindowsVersionHealer.ts
35611
35645
  var UNRECOVERABLE_MESSAGE = "Windows host is on an incompatible version that auto-update could not resolve; not reconnecting. Update the Windows host manually, then restart.";
35646
+ var HEALED_MESSAGE = "Windows host is up to date \u2014 you can reselect the repo now.";
35612
35647
  var WindowsVersionHealer = class {
35613
35648
  constructor(conn, state, heal) {
35614
35649
  this.conn = conn;
@@ -35618,6 +35653,7 @@ var WindowsVersionHealer = class {
35618
35653
  healAttempted = false;
35619
35654
  healing = false;
35620
35655
  unrecoverable = false;
35656
+ awaitingConfirmation = false;
35621
35657
  get blocked() {
35622
35658
  return this.unrecoverable;
35623
35659
  }
@@ -35629,14 +35665,24 @@ var WindowsVersionHealer = class {
35629
35665
  if (this.healAttempted) return this.giveUp(version2);
35630
35666
  this.healing = true;
35631
35667
  this.healAttempted = true;
35668
+ this.awaitingConfirmation = true;
35632
35669
  try {
35633
35670
  await autoHealWindowsDaemon(this.conn, this.state, this.heal, version2);
35634
35671
  } finally {
35635
35672
  this.healing = false;
35636
35673
  }
35637
35674
  }
35675
+ onCompatible() {
35676
+ if (!this.awaitingConfirmation) return;
35677
+ this.awaitingConfirmation = false;
35678
+ daemonLog(
35679
+ "windows proxy: post-heal handshake compatible; windows host is in step"
35680
+ );
35681
+ this.state.broadcast({ type: "notice", message: HEALED_MESSAGE });
35682
+ }
35638
35683
  giveUp(version2) {
35639
35684
  this.unrecoverable = true;
35685
+ this.awaitingConfirmation = false;
35640
35686
  daemonLog(
35641
35687
  `windows proxy: version mismatch ${version2} persists after heal; not reconnecting until the WSL daemon restarts`
35642
35688
  );
@@ -35657,6 +35703,7 @@ var WindowsProxy = class {
35657
35703
  (msg) => broadcast(clients, msg),
35658
35704
  onSessionsChanged,
35659
35705
  (version2) => void this.healer.onMismatch(version2),
35706
+ () => this.healer.onCompatible(),
35660
35707
  createTimeoutMs
35661
35708
  );
35662
35709
  this.conn = new WindowsConnection({
@@ -35681,7 +35728,10 @@ var WindowsProxy = class {
35681
35728
  route(client, data) {
35682
35729
  if (!this.enabled) return false;
35683
35730
  if (isWindowsCreate(data)) return this.routeCreate(client, data);
35684
- if (isWindowsIo(data)) return this.routeIo(data);
35731
+ if (isWindowsIo(data)) {
35732
+ forwardWindowsIo(this.conn, data);
35733
+ return true;
35734
+ }
35685
35735
  return false;
35686
35736
  }
35687
35737
  routeCreate(client, data) {
@@ -35693,12 +35743,6 @@ var WindowsProxy = class {
35693
35743
  } else void forwardWindowsCreate(this.conn, this.state, client, data);
35694
35744
  return true;
35695
35745
  }
35696
- routeIo(data) {
35697
- const sessionId = stripWindowsSessionId(data.sessionId);
35698
- const delivered = this.conn.trySend({ ...data, sessionId });
35699
- logWindowsForward(delivered, data.type, data.sessionId);
35700
- return true;
35701
- }
35702
35746
  dispose() {
35703
35747
  this.conn.dispose();
35704
35748
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.562.1",
3
+ "version": "0.564.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {