@staff0rd/assist 0.574.1 → 0.575.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.574.1",
9
+ version: "0.575.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -4946,14 +4946,14 @@ function findRuleViolations(data, rule) {
4946
4946
  }
4947
4947
  return violations;
4948
4948
  }
4949
- function findForbiddenStrings(rules2, readJson) {
4950
- return rules2.flatMap((rule) => findRuleViolations(readJson(rule.file), rule));
4949
+ function findForbiddenStrings(rules3, readJson) {
4950
+ return rules3.flatMap((rule) => findRuleViolations(readJson(rule.file), rule));
4951
4951
  }
4952
4952
 
4953
4953
  // src/commands/verify/forbiddenStrings/index.ts
4954
4954
  function forbiddenStrings() {
4955
- const rules2 = loadConfig().forbiddenStrings ?? [];
4956
- if (rules2.length === 0) {
4955
+ const rules3 = loadConfig().forbiddenStrings ?? [];
4956
+ if (rules3.length === 0) {
4957
4957
  console.log("No forbidden-strings rules configured.");
4958
4958
  process.exit(0);
4959
4959
  }
@@ -4974,7 +4974,7 @@ function forbiddenStrings() {
4974
4974
  cache5.set(file, parsed);
4975
4975
  return parsed;
4976
4976
  };
4977
- const violations = findForbiddenStrings(rules2, readJson);
4977
+ const violations = findForbiddenStrings(rules3, readJson);
4978
4978
  if (violations.length === 0) {
4979
4979
  console.log("No forbidden strings found.");
4980
4980
  process.exit(0);
@@ -13979,6 +13979,7 @@ function toPreviewDecision(msg) {
13979
13979
  reason: msg.reason,
13980
13980
  comments: Array.isArray(msg.comments) ? msg.comments : void 0,
13981
13981
  screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
13982
+ body: typeof msg.body === "string" ? msg.body : void 0,
13982
13983
  reviewAfter: msg.reviewAfter === true,
13983
13984
  announceAfter: msg.announceAfter === true,
13984
13985
  draft: typeof msg.draft === "boolean" ? msg.draft : void 0
@@ -14029,7 +14030,7 @@ function requestPreviewDecision(request) {
14029
14030
  }
14030
14031
 
14031
14032
  // src/commands/sessions/shared/awaitPreviewApproval.ts
14032
- async function awaitPreviewApproval(subject, request) {
14033
+ async function awaitPreviewApproval(subject, request, saveEditedBody) {
14033
14034
  console.log("Awaiting your approval in the assist web UI preview pane\u2026");
14034
14035
  let decision;
14035
14036
  try {
@@ -14040,6 +14041,7 @@ async function awaitPreviewApproval(subject, request) {
14040
14041
  );
14041
14042
  process.exit(1);
14042
14043
  }
14044
+ if (decision.body !== void 0) saveEditedBody?.(decision.body);
14043
14045
  if (decision.decision === "reject") reportPreviewRejection(subject, decision);
14044
14046
  return decision;
14045
14047
  }
@@ -20840,19 +20842,36 @@ function pushIssueBody(number, repo, bodyPath) {
20840
20842
  }
20841
20843
  }
20842
20844
 
20845
+ // src/commands/github/issue/pushUnchangedIssue.ts
20846
+ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
20847
+ if (fetchIssue2(number, repo).updatedAt !== fetchedAt) {
20848
+ console.error(
20849
+ `${target} was updated on GitHub after it was fetched. Nothing was pushed; the markdown is at ${bodyPath}`
20850
+ );
20851
+ process.exit(1);
20852
+ }
20853
+ pushIssueBody(number, repo, bodyPath);
20854
+ console.log(`Issue body updated on ${target}`);
20855
+ }
20856
+
20843
20857
  // src/commands/github/issue/reviewProposedIssueEdit.ts
20844
20858
  import { randomUUID as randomUUID9 } from "crypto";
20845
- async function reviewProposedIssueEdit(title, body) {
20859
+ async function reviewProposedIssueEdit(title, body, saveEditedBody) {
20846
20860
  const sessionId = process.env.ASSIST_SESSION_ID;
20847
- if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
20848
- await awaitPreviewApproval("GitHub issue edit preview", {
20849
- sessionId,
20850
- requestId: randomUUID9(),
20851
- title,
20852
- body,
20853
- prNumber: null,
20854
- kind: "github-issue-edit"
20855
- });
20861
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
20862
+ const decision = await awaitPreviewApproval(
20863
+ "GitHub issue edit preview",
20864
+ {
20865
+ sessionId,
20866
+ requestId: randomUUID9(),
20867
+ title,
20868
+ body,
20869
+ prNumber: null,
20870
+ kind: "github-issue-edit"
20871
+ },
20872
+ saveEditedBody
20873
+ );
20874
+ return decision.body ?? body;
20856
20875
  }
20857
20876
 
20858
20877
  // src/commands/github/issue/viewIssue.ts
@@ -20919,22 +20938,19 @@ async function editIssue(numberArg, options2) {
20919
20938
  issue.title,
20920
20939
  issue.body
20921
20940
  );
20922
- const bodyPath = writeIssueWorkingFile(
20923
- slug,
20924
- number,
20925
- target,
20926
- issue.updatedAt,
20927
- issue.body
20941
+ const save = (markdown) => writeIssueWorkingFile(slug, number, target, issue.updatedAt, markdown);
20942
+ const bodyPath = save(issue.body);
20943
+ const edited = await reviewProposedIssueEdit(
20944
+ `Edit ${target}: ${issue.title}`,
20945
+ issue.body,
20946
+ save
20928
20947
  );
20929
- await reviewProposedIssueEdit(`Edit ${target}: ${issue.title}`, issue.body);
20930
- if (fetchIssue2(number, options2.repo).updatedAt !== issue.updatedAt) {
20931
- console.error(
20932
- `${target} was updated on GitHub after it was fetched. Nothing was pushed; the markdown is at ${bodyPath}`
20933
- );
20934
- process.exit(1);
20935
- }
20936
- pushIssueBody(number, options2.repo, bodyPath);
20937
- console.log(`Issue body updated on ${target}`);
20948
+ validateProposedContent(
20949
+ { subject: "Issue", context: "GitHub issues" },
20950
+ issue.title,
20951
+ edited
20952
+ );
20953
+ pushUnchangedIssue(number, options2.repo, target, issue.updatedAt, bodyPath);
20938
20954
  }
20939
20955
 
20940
20956
  // src/commands/prs/readBodyArgument.ts
@@ -30436,7 +30452,8 @@ function renderWatchReport({
30436
30452
  version: version2,
30437
30453
  commits: commits2,
30438
30454
  newShas,
30439
- restarts
30455
+ restarts,
30456
+ syncs
30440
30457
  }) {
30441
30458
  const isNew = new Set(newShas);
30442
30459
  const lines2 = [`**Version** ${version2}`, ""];
@@ -30455,6 +30472,10 @@ function renderWatchReport({
30455
30472
  lines2.push(
30456
30473
  ...restarts.length === 0 ? ["- none needed"] : restarts.map((restart) => `- ${restart}`)
30457
30474
  );
30475
+ lines2.push("", "**Sync**", "");
30476
+ lines2.push(
30477
+ ...syncs.length === 0 ? ["- not needed"] : syncs.map((sync2) => `- ${sync2}`)
30478
+ );
30458
30479
  return lines2.join("\n");
30459
30480
  }
30460
30481
 
@@ -30475,17 +30496,52 @@ function restartAdvice(paths) {
30475
30496
  return rules.filter((rule) => paths.some(rule.matches)).map((rule) => rule.advice);
30476
30497
  }
30477
30498
 
30499
+ // src/commands/watch/syncAdvice.ts
30500
+ var rules2 = [
30501
+ {
30502
+ matches: (path80) => path80.startsWith("claude/commands/"),
30503
+ reason: "claude/commands changed"
30504
+ },
30505
+ {
30506
+ matches: (path80) => path80.startsWith("claude/skills/"),
30507
+ reason: "claude/skills changed"
30508
+ },
30509
+ {
30510
+ matches: (path80) => path80 === "claude/settings.json",
30511
+ reason: "claude/settings.json changed"
30512
+ },
30513
+ {
30514
+ matches: (path80) => path80 === "claude/CLAUDE.md",
30515
+ reason: "claude/CLAUDE.md changed"
30516
+ },
30517
+ {
30518
+ matches: (path80) => path80 === "claude/design-system-prompt.md",
30519
+ reason: "claude/design-system-prompt.md changed"
30520
+ },
30521
+ {
30522
+ matches: (path80) => path80.startsWith("codex/"),
30523
+ reason: "codex sources changed"
30524
+ },
30525
+ {
30526
+ matches: (path80) => path80.startsWith("pi/"),
30527
+ reason: "pi sources changed"
30528
+ }
30529
+ ];
30530
+ function syncAdvice(paths) {
30531
+ return rules2.filter((rule) => paths.some(rule.matches)).map((rule) => rule.reason);
30532
+ }
30533
+
30478
30534
  // src/commands/watch/buildWatchReport.ts
30479
30535
  var lines = (output) => output.split("\n").filter((line) => line.length > 0);
30480
30536
  function buildWatchReport(from, cwd) {
30481
30537
  const range = from ? `${from}..HEAD` : void 0;
30538
+ const changed = range ? lines(runGit3(["diff", "--name-only", range], cwd)) : [];
30482
30539
  return renderWatchReport({
30483
30540
  version: readBuiltVersion(cwd),
30484
30541
  commits: readRecentCommits(10, cwd),
30485
30542
  newShas: range ? lines(runGit3(["rev-list", range], cwd)) : [],
30486
- restarts: restartAdvice(
30487
- range ? lines(runGit3(["diff", "--name-only", range], cwd)) : []
30488
- )
30543
+ restarts: restartAdvice(changed),
30544
+ syncs: syncAdvice(changed)
30489
30545
  });
30490
30546
  }
30491
30547
 
@@ -30971,10 +31027,10 @@ function registerWatch(program2) {
30971
31027
  (options2) => watchWait(options2)
30972
31028
  );
30973
31029
  watchCommand.command("report").description(
30974
- "Print the built version, the last 10 commits as a markdown table, and the restarts the new commits make necessary"
31030
+ "Print the built version, the last 10 commits as a markdown table, the restarts the new commits make necessary, and whether ~/.claude needs a sync"
30975
31031
  ).option(
30976
31032
  "--from <sha>",
30977
- "Mark commits reachable from HEAD but not <sha> as new, and derive restart advice from the files they changed"
31033
+ "Mark commits reachable from HEAD but not <sha> as new, and derive the restart and sync advice from the files they changed"
30978
31034
  ).action((options2) => watchReport(options2));
30979
31035
  }
30980
31036
 
@@ -32885,6 +32941,7 @@ function decidePrPreview(sessions, waiters, notify2, d) {
32885
32941
  reason: d.reason,
32886
32942
  comments: d.comments,
32887
32943
  screenshots: d.screenshots,
32944
+ body: d.body,
32888
32945
  reviewAfter: d.reviewAfter,
32889
32946
  announceAfter: d.announceAfter,
32890
32947
  draft: d.draft
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.574.1",
3
+ "version": "0.575.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {