@staff0rd/assist 0.578.0 → 0.579.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.578.0",
9
+ version: "0.579.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -13973,6 +13973,12 @@ ${quoted}
13973
13973
  }
13974
13974
 
13975
13975
  // src/commands/sessions/shared/toPreviewDecision.ts
13976
+ function toSelection(value) {
13977
+ const selection = value;
13978
+ if (typeof selection?.topLeft !== "string" || typeof selection.bottomRight !== "string")
13979
+ return void 0;
13980
+ return { topLeft: selection.topLeft, bottomRight: selection.bottomRight };
13981
+ }
13976
13982
  function toPreviewDecision(msg) {
13977
13983
  if (msg.decision !== "approve" && msg.decision !== "reject") return null;
13978
13984
  return {
@@ -13983,7 +13989,8 @@ function toPreviewDecision(msg) {
13983
13989
  body: typeof msg.body === "string" ? msg.body : void 0,
13984
13990
  reviewAfter: msg.reviewAfter === true,
13985
13991
  announceAfter: msg.announceAfter === true,
13986
- draft: typeof msg.draft === "boolean" ? msg.draft : void 0
13992
+ draft: typeof msg.draft === "boolean" ? msg.draft : void 0,
13993
+ selection: toSelection(msg.selection)
13987
13994
  };
13988
13995
  }
13989
13996
 
@@ -22939,6 +22946,45 @@ function parseAnchorId(value) {
22939
22946
  return link3 ? decodeURIComponent(link3[1]).trim() : trimmed;
22940
22947
  }
22941
22948
 
22949
+ // src/commands/miro/pickAnchors.ts
22950
+ import { randomUUID as randomUUID12 } from "crypto";
22951
+
22952
+ // src/commands/miro/isBox.ts
22953
+ var boxTypes = /* @__PURE__ */ new Set(["shape", "sticky_note"]);
22954
+ function isBox(item) {
22955
+ return boxTypes.has(item.type) && item.text.length > 0;
22956
+ }
22957
+
22958
+ // src/commands/miro/encodeMiroBoardPreview.ts
22959
+ function encodeMiroBoardPreview(items2) {
22960
+ const preview = { boxes: items2.filter(isBox) };
22961
+ return JSON.stringify(preview);
22962
+ }
22963
+
22964
+ // src/commands/miro/pickAnchors.ts
22965
+ var skipAdvice = "Re-run with --top-left <id|link> --bottom-right <id|link> to skip the picker.";
22966
+ async function pickAnchors(sessionId, items2) {
22967
+ const decision = await awaitPreviewApproval(
22968
+ "Miro anchor selection",
22969
+ {
22970
+ sessionId,
22971
+ requestId: randomUUID12(),
22972
+ title: "Pick the top-left then the bottom-right box",
22973
+ body: encodeMiroBoardPreview(items2),
22974
+ prNumber: null,
22975
+ kind: "miro-board"
22976
+ },
22977
+ { rejectionAdvice: `Nothing was extracted. ${skipAdvice}` }
22978
+ );
22979
+ const selection = decision.selection;
22980
+ if (!selection)
22981
+ throw new MiroExtractError(`The picker returned no boxes. ${skipAdvice}`);
22982
+ console.log(
22983
+ `Anchors: --top-left ${selection.topLeft} --bottom-right ${selection.bottomRight}`
22984
+ );
22985
+ return [selection.topLeft, selection.bottomRight];
22986
+ }
22987
+
22942
22988
  // src/commands/miro/readMiroItems.ts
22943
22989
  import { readFileSync as readFileSync40 } from "fs";
22944
22990
  function tryParse(text18) {
@@ -22980,7 +23026,6 @@ function readMiroItems(file) {
22980
23026
  }
22981
23027
 
22982
23028
  // src/commands/miro/selectBoxes.ts
22983
- var boxTypes = /* @__PURE__ */ new Set(["shape", "sticky_note"]);
22984
23029
  function findAnchor(items2, id) {
22985
23030
  const anchor = items2.find((item) => item.id === id);
22986
23031
  if (!anchor)
@@ -22989,9 +23034,6 @@ function findAnchor(items2, id) {
22989
23034
  );
22990
23035
  return anchor;
22991
23036
  }
22992
- function isBox(item) {
22993
- return boxTypes.has(item.type) && item.text.length > 0;
22994
- }
22995
23037
  function centreInside(rect, item) {
22996
23038
  const x = (item.left + item.right) / 2;
22997
23039
  const y = (item.top + item.bottom) / 2;
@@ -23017,16 +23059,24 @@ function requireItems(file) {
23017
23059
  );
23018
23060
  return file;
23019
23061
  }
23020
- function requireAnchors(options2) {
23021
- if (!options2.topLeft || !options2.bottomRight)
23062
+ function anchorSource(options2) {
23063
+ if (options2.topLeft && options2.bottomRight)
23064
+ return {
23065
+ pick: false,
23066
+ topLeft: parseAnchorId(options2.topLeft),
23067
+ bottomRight: parseAnchorId(options2.bottomRight)
23068
+ };
23069
+ const sessionId = process.env.ASSIST_SESSION_ID;
23070
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId)
23022
23071
  throw new MiroExtractError(
23023
- "Both --top-left <id|link> and --bottom-right <id|link> are required."
23072
+ "Both --top-left <id|link> and --bottom-right <id|link> are required: there is no assist session to host the picker pane."
23024
23073
  );
23025
- return [parseAnchorId(options2.topLeft), parseAnchorId(options2.bottomRight)];
23074
+ return { pick: true, sessionId };
23026
23075
  }
23027
- function runExtract(options2) {
23028
- const [topLeft, bottomRight] = requireAnchors(options2);
23076
+ async function runExtract(options2) {
23077
+ const source = anchorSource(options2);
23029
23078
  const items2 = normaliseItems(readMiroItems(requireItems(options2.items)));
23079
+ const [topLeft, bottomRight] = source.pick ? await pickAnchors(source.sessionId, items2) : [source.topLeft, source.bottomRight];
23030
23080
  const boxes = selectBoxes(items2, topLeft, bottomRight);
23031
23081
  process.stdout.write(stringify(boxes.map((box) => box.text)));
23032
23082
  }
@@ -23036,7 +23086,7 @@ function registerMiro(program2) {
23036
23086
  const miroCommand = program2.command("miro").description("Miro board utilities");
23037
23087
  miroCommand.command("extract").description("Print the text of every box inside a rectangle on a board").option("--items <file>", "File of raw board_list_items response pages").option(
23038
23088
  "--top-left <id>",
23039
- "Widget id or ?moveToWidget=<id> link of the top-left box"
23089
+ "Widget id or ?moveToWidget=<id> link of the top-left box (omit both anchors to pick them in the assist web UI)"
23040
23090
  ).option(
23041
23091
  "--bottom-right <id>",
23042
23092
  "Widget id or ?moveToWidget=<id> link of the bottom-right box"
@@ -23868,13 +23918,13 @@ function postReviewComment(vars) {
23868
23918
  }
23869
23919
 
23870
23920
  // src/commands/prs/reviewProposedPrComment.ts
23871
- import { randomUUID as randomUUID12 } from "crypto";
23921
+ import { randomUUID as randomUUID13 } from "crypto";
23872
23922
  async function reviewProposedPrComment(title, body, prNumber) {
23873
23923
  const sessionId = process.env.ASSIST_SESSION_ID;
23874
23924
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
23875
23925
  await awaitPreviewApproval("PR comment preview", {
23876
23926
  sessionId,
23877
- requestId: randomUUID12(),
23927
+ requestId: randomUUID13(),
23878
23928
  title,
23879
23929
  body,
23880
23930
  prNumber,
@@ -24000,7 +24050,7 @@ async function comment2(path80, line, body, startLine) {
24000
24050
  }
24001
24051
 
24002
24052
  // src/commands/prs/edit.ts
24003
- import { randomUUID as randomUUID13 } from "crypto";
24053
+ import { randomUUID as randomUUID14 } from "crypto";
24004
24054
 
24005
24055
  // src/commands/prs/appendScreenshots.ts
24006
24056
  function appendScreenshots(body, screenshots) {
@@ -24197,7 +24247,7 @@ async function edit(options2) {
24197
24247
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
24198
24248
  const decision = await awaitPreviewApproval("PR preview", {
24199
24249
  sessionId,
24200
- requestId: randomUUID13(),
24250
+ requestId: randomUUID14(),
24201
24251
  title: options2.title ?? title,
24202
24252
  body: newBody,
24203
24253
  prNumber: number
@@ -24908,7 +24958,7 @@ async function placePr(prNumber, title, body, options2) {
24908
24958
  }
24909
24959
 
24910
24960
  // src/commands/prs/previewAndPlace.ts
24911
- import { randomUUID as randomUUID14 } from "crypto";
24961
+ import { randomUUID as randomUUID15 } from "crypto";
24912
24962
 
24913
24963
  // src/commands/sessions/shared/requestSession.ts
24914
24964
  function parseIncoming(line, type) {
@@ -25043,7 +25093,7 @@ function warn(reason4) {
25043
25093
  async function previewAndPlace(args) {
25044
25094
  const decision = await awaitPreviewApproval("PR preview", {
25045
25095
  sessionId: args.sessionId,
25046
- requestId: randomUUID14(),
25096
+ requestId: randomUUID15(),
25047
25097
  title: args.title,
25048
25098
  body: args.body,
25049
25099
  prNumber: args.prNumber,
@@ -27515,10 +27565,10 @@ function registerRefactor(program2) {
27515
27565
  }
27516
27566
 
27517
27567
  // src/commands/review/checkoutOnlySession.ts
27518
- import { randomUUID as randomUUID15 } from "crypto";
27568
+ import { randomUUID as randomUUID16 } from "crypto";
27519
27569
  async function checkoutOnlySession(number) {
27520
27570
  await checkoutPr(number);
27521
- const claudeSessionId = randomUUID15();
27571
+ const claudeSessionId = randomUUID16();
27522
27572
  emitActivity({ kind: "command", name: "review", claudeSessionId });
27523
27573
  const { done: done2 } = spawnClaude("", {
27524
27574
  permissionMode: "acceptEdits",
@@ -32959,7 +33009,7 @@ var ClientHub = class extends Set {
32959
33009
  };
32960
33010
 
32961
33011
  // src/commands/sessions/daemon/createSession.ts
32962
- import { randomUUID as randomUUID16 } from "crypto";
33012
+ import { randomUUID as randomUUID17 } from "crypto";
32963
33013
 
32964
33014
  // src/commands/sessions/daemon/sessionBase.ts
32965
33015
  function sessionBase(id, status3) {
@@ -33155,7 +33205,7 @@ function spawnRun(opts) {
33155
33205
  function createSession(id, { prompt, cwd, design, auto, harness, holdPty } = {}) {
33156
33206
  if (harness && harness !== "claude")
33157
33207
  return createHarnessSession(id, harness, prompt, cwd, holdPty);
33158
- const claudeSessionId = randomUUID16();
33208
+ const claudeSessionId = randomUUID17();
33159
33209
  return {
33160
33210
  ...sessionBase(id, prompt ? "running" : "waiting"),
33161
33211
  name: `Session ${id}`,
@@ -33754,7 +33804,8 @@ var PREVIEW_KINDS = [
33754
33804
  "pr-comment",
33755
33805
  "github-issue",
33756
33806
  "github-issue-comment",
33757
- "github-issue-edit"
33807
+ "github-issue-edit",
33808
+ "miro-board"
33758
33809
  ];
33759
33810
  function isPreviewKind(value) {
33760
33811
  return PREVIEW_KINDS.includes(value);
@@ -33767,6 +33818,7 @@ function previewTargetLabel(kind, itemType, prNumber, draft) {
33767
33818
  if (kind === "github-issue-comment") return "github issue comment";
33768
33819
  if (kind === "github-issue-edit") return "github issue edit";
33769
33820
  if (kind === "github-issue") return "github issue";
33821
+ if (kind === "miro-board") return "miro anchors";
33770
33822
  if (kind === "backlog-item") return `backlog ${itemType}`;
33771
33823
  if (prNumber !== null) return `edit #${prNumber}`;
33772
33824
  return draft ? "create draft" : "create";
@@ -35226,7 +35278,7 @@ function codexRespawnPlan(session) {
35226
35278
  }
35227
35279
 
35228
35280
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
35229
- import { randomUUID as randomUUID17 } from "crypto";
35281
+ import { randomUUID as randomUUID18 } from "crypto";
35230
35282
  function interactiveRespawnPlan(session, resumes) {
35231
35283
  const { claudeSessionId, cwd, initialPrompt, design, auto } = session;
35232
35284
  if (!resumes) return null;
@@ -35246,7 +35298,7 @@ function interactiveRespawnPlan(session, resumes) {
35246
35298
  return null;
35247
35299
  }
35248
35300
  function freshClaudePlan(session, prompt, cwd) {
35249
- const claudeSessionId = randomUUID17();
35301
+ const claudeSessionId = randomUUID18();
35250
35302
  return {
35251
35303
  spawn: () => {
35252
35304
  session.claudeSessionId = claudeSessionId;
@@ -36131,10 +36183,10 @@ function startReusedRunPty(session, assistArgs, itemId2, hold, clients, onStatus
36131
36183
  }
36132
36184
 
36133
36185
  // src/commands/sessions/daemon/createWatcherSession.ts
36134
- import { randomUUID as randomUUID18 } from "crypto";
36186
+ import { randomUUID as randomUUID19 } from "crypto";
36135
36187
  var WATCH_PROMPT = "/watch";
36136
36188
  function createWatcherSession(id, cwd) {
36137
- const claudeSessionId = randomUUID18();
36189
+ const claudeSessionId = randomUUID19();
36138
36190
  return {
36139
36191
  ...sessionBase(id, "running"),
36140
36192
  name: `Session ${id}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.578.0",
3
+ "version": "0.579.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {