@staff0rd/assist 0.528.3 → 0.530.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.528.3",
9
+ version: "0.530.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -4256,7 +4256,7 @@ var sessionsConfigHelp = [
4256
4256
  {
4257
4257
  key: "worktree.watcher",
4258
4258
  setter: "assist config set worktree.watcher true -g --repo",
4259
- note: "a backlog run also starts one starred claude session in the clone running /watch, so the built version stays current while the run works in its worktree; requires worktree.enabled and a /watch command in the repo (default off)"
4259
+ note: "a backlog run also starts one starred claude session in the clone running /watch, so the built version stays current while the run works in its worktree; requires worktree.enabled, a /watch command in the repo and an auto-build run entry (default off)"
4260
4260
  },
4261
4261
  {
4262
4262
  key: "worktree.trunk",
@@ -29924,7 +29924,12 @@ import { fileURLToPath as fileURLToPath8 } from "url";
29924
29924
  var __filename4 = fileURLToPath8(import.meta.url);
29925
29925
  var __dirname6 = path58.dirname(__filename4);
29926
29926
  function readDesignSystemPrompt() {
29927
- const promptPath = path58.join(__dirname6, "..", "claude", "system-prompt.md");
29927
+ const promptPath = path58.join(
29928
+ __dirname6,
29929
+ "..",
29930
+ "claude",
29931
+ "design-system-prompt.md"
29932
+ );
29928
29933
  return fs35.readFileSync(promptPath, "utf8");
29929
29934
  }
29930
29935
 
@@ -30103,6 +30108,10 @@ function setStatus2(session, newStatus) {
30103
30108
  session.runningSince = newStatus === "running" ? now : null;
30104
30109
  session.waitingSince = newStatus === "waiting" ? now : null;
30105
30110
  session.status = newStatus;
30111
+ if (newStatus !== "running" && session.verifying) {
30112
+ session.verifying = false;
30113
+ daemonLog(`session ${session.id} verifying cleared: status=${newStatus}`);
30114
+ }
30106
30115
  if (newStatus === "waiting") {
30107
30116
  daemonLog(
30108
30117
  `session ${session.id} waiting since ${new Date(now).toISOString()}`
@@ -32632,6 +32641,20 @@ function runRetry(sessions, id, replace, deps2) {
32632
32641
  return null;
32633
32642
  }
32634
32643
 
32644
+ // src/commands/sessions/daemon/attachReusedRun.ts
32645
+ function attachReusedRun(session, alloc, clients, onStatusChange, tree) {
32646
+ broadcast(clients, { type: "clear", sessionId: session.id });
32647
+ if (alloc)
32648
+ bindNewWorktree(
32649
+ session,
32650
+ alloc,
32651
+ tree?.notify ?? (() => {
32652
+ }),
32653
+ tree?.startHeld
32654
+ );
32655
+ else wirePtyEvents(session, clients, onStatusChange);
32656
+ }
32657
+
32635
32658
  // src/commands/sessions/daemon/resetCardForRun.ts
32636
32659
  function resetCardForRun(session, assistArgs) {
32637
32660
  session.pty?.kill();
@@ -32675,25 +32698,28 @@ function startReusedRunPty(session, assistArgs, itemId2, hold, clients, onStatus
32675
32698
  return true;
32676
32699
  }
32677
32700
 
32678
- // src/commands/sessions/daemon/worktree/isBacklogRunArgs.ts
32679
- var ITEM_ID = /^a?\d+$/;
32680
- function isBacklogRunArgs(args) {
32681
- const [command, subcommand, ...rest] = args;
32682
- if (command !== "backlog" || subcommand !== "run") return false;
32683
- return rest.some((arg) => ITEM_ID.test(arg));
32684
- }
32685
-
32686
- // src/commands/sessions/daemon/worktree/isPrCheckoutArgs.ts
32687
- var CHECKOUT_COMMANDS = /* @__PURE__ */ new Set(["review", "review-pr-comments"]);
32688
- function isPrCheckoutArgs(args) {
32689
- const [command, ...rest] = args;
32690
- if (!command || !CHECKOUT_COMMANDS.has(command)) return false;
32691
- return rest.some((arg) => /^[1-9]\d*$/.test(arg));
32692
- }
32693
-
32694
- // src/commands/sessions/daemon/worktree/isCommittingArgs.ts
32695
- function isCommittingArgs(args) {
32696
- return isPrCheckoutArgs(args) || isBacklogRunArgs(args);
32701
+ // src/commands/sessions/daemon/createWatcherSession.ts
32702
+ import { randomUUID as randomUUID11 } from "crypto";
32703
+ var WATCH_PROMPT = "/watch";
32704
+ function createWatcherSession(id, cwd) {
32705
+ const claudeSessionId = randomUUID11();
32706
+ return {
32707
+ ...sessionBase(id, "running"),
32708
+ name: `Session ${id}`,
32709
+ commandType: "claude",
32710
+ pty: spawnClaude2({
32711
+ prompt: WATCH_PROMPT,
32712
+ cwd,
32713
+ sessionId: id,
32714
+ claudeSessionId,
32715
+ auto: true
32716
+ }),
32717
+ cwd,
32718
+ claudeSessionId,
32719
+ initialPrompt: WATCH_PROMPT,
32720
+ starred: true,
32721
+ watcher: true
32722
+ };
32697
32723
  }
32698
32724
 
32699
32725
  // src/commands/sessions/daemon/worktree/boundTreeRoots.ts
@@ -32726,6 +32752,68 @@ function releaseReason(durability, session) {
32726
32752
  return `free for allocation: session ${session.id} finished and its work is landed`;
32727
32753
  }
32728
32754
 
32755
+ // src/commands/sessions/daemon/worktree/allocateAndBind.ts
32756
+ function allocateAndBind(ctx, cwd, create, options2 = {}) {
32757
+ const alloc = allocateTree(cwd, boundTreeRoots(ctx.sessions), options2);
32758
+ const needsSeeding = alloc.kind === "worktree" && alloc.created === true;
32759
+ const id = ctx.spawnWith((sid) => create(sid, alloc.cwd, needsSeeding));
32760
+ bindNewWorktree(ctx.sessions.get(id), alloc, ctx.notify, ctx.startHeld);
32761
+ return id;
32762
+ }
32763
+
32764
+ // src/commands/sessions/daemon/worktree/ensureWatcher.ts
32765
+ function ensureWatcher(ctx, cwd) {
32766
+ if (!cwd) return void 0;
32767
+ const repoRoot2 = findRepoRoot(cwd) ?? cwd;
32768
+ const cfg = worktreeConfigFor(repoRoot2);
32769
+ if (!cfg.enabled || cfg.watcher !== true) return void 0;
32770
+ const clone = mainWorktree(repoRoot2) ?? repoRoot2;
32771
+ const live = liveWatcherFor(ctx.sessions, clone);
32772
+ if (live) {
32773
+ daemonLog(
32774
+ `no watcher spawned for the clone ${clone}: session ${live.id} is already watching it (${live.status})`
32775
+ );
32776
+ return void 0;
32777
+ }
32778
+ const id = allocateAndBind(
32779
+ ctx,
32780
+ clone,
32781
+ (sid, resolvedCwd) => createWatcherSession(sid, resolvedCwd ?? clone),
32782
+ { inPlace: true }
32783
+ );
32784
+ daemonLog(
32785
+ `spawned watcher session ${id} running /watch in the clone ${clone}`
32786
+ );
32787
+ return id;
32788
+ }
32789
+ function liveWatcherFor(sessions, clone) {
32790
+ for (const session of sessions.values())
32791
+ if (session.watcher === true && session.cwd === clone && session.status !== "stopped" && session.status !== "error")
32792
+ return session;
32793
+ return void 0;
32794
+ }
32795
+
32796
+ // src/commands/sessions/daemon/worktree/isBacklogRunArgs.ts
32797
+ var ITEM_ID = /^a?\d+$/;
32798
+ function isBacklogRunArgs(args) {
32799
+ const [command, subcommand, ...rest] = args;
32800
+ if (command !== "backlog" || subcommand !== "run") return false;
32801
+ return rest.some((arg) => ITEM_ID.test(arg));
32802
+ }
32803
+
32804
+ // src/commands/sessions/daemon/worktree/isPrCheckoutArgs.ts
32805
+ var CHECKOUT_COMMANDS = /* @__PURE__ */ new Set(["review", "review-pr-comments"]);
32806
+ function isPrCheckoutArgs(args) {
32807
+ const [command, ...rest] = args;
32808
+ if (!command || !CHECKOUT_COMMANDS.has(command)) return false;
32809
+ return rest.some((arg) => /^[1-9]\d*$/.test(arg));
32810
+ }
32811
+
32812
+ // src/commands/sessions/daemon/worktree/isCommittingArgs.ts
32813
+ function isCommittingArgs(args) {
32814
+ return isPrCheckoutArgs(args) || isBacklogRunArgs(args);
32815
+ }
32816
+
32729
32817
  // src/commands/sessions/daemon/worktree/planReuseTree.ts
32730
32818
  function planReuseTree(session, ctx, options2 = {}) {
32731
32819
  if (!ctx || !session.cwd || session.worktree) return void 0;
@@ -32764,6 +32852,7 @@ function failChainedRun(session, itemId2, error, clients, tree) {
32764
32852
  // src/commands/sessions/daemon/reuseSessionForRun.ts
32765
32853
  function reuseSessionForRun(session, itemId2, clients, onStatusChange, tree) {
32766
32854
  const assistArgs = ["backlog", "run", String(itemId2)];
32855
+ const originCwd = session.cwd;
32767
32856
  resetCardForRun(session, assistArgs);
32768
32857
  let alloc;
32769
32858
  try {
@@ -32784,16 +32873,8 @@ function reuseSessionForRun(session, itemId2, clients, onStatusChange, tree) {
32784
32873
  onStatusChange
32785
32874
  );
32786
32875
  if (!started) return;
32787
- broadcast(clients, { type: "clear", sessionId: session.id });
32788
- if (alloc)
32789
- bindNewWorktree(
32790
- session,
32791
- alloc,
32792
- tree?.notify ?? (() => {
32793
- }),
32794
- tree?.startHeld
32795
- );
32796
- else wirePtyEvents(session, clients, onStatusChange);
32876
+ if (tree) ensureWatcher(tree, originCwd);
32877
+ attachReusedRun(session, alloc, clients, onStatusChange, tree);
32797
32878
  daemonLog(
32798
32879
  `session ${session.id} reused for backlog run ${itemId2}: ${session.name}`
32799
32880
  );
@@ -33664,71 +33745,6 @@ function resumeSession(id, sessionId, cwd, name, holdPty) {
33664
33745
  };
33665
33746
  }
33666
33747
 
33667
- // src/commands/sessions/daemon/worktree/allocateAndBind.ts
33668
- function allocateAndBind(ctx, cwd, create, options2 = {}) {
33669
- const alloc = allocateTree(cwd, boundTreeRoots(ctx.sessions), options2);
33670
- const needsSeeding = alloc.kind === "worktree" && alloc.created === true;
33671
- const id = ctx.spawnWith((sid) => create(sid, alloc.cwd, needsSeeding));
33672
- bindNewWorktree(ctx.sessions.get(id), alloc, ctx.notify, ctx.startHeld);
33673
- return id;
33674
- }
33675
-
33676
- // src/commands/sessions/daemon/createWatcherSession.ts
33677
- import { randomUUID as randomUUID11 } from "crypto";
33678
- var WATCH_PROMPT = "/watch";
33679
- function createWatcherSession(id, cwd) {
33680
- const claudeSessionId = randomUUID11();
33681
- return {
33682
- ...sessionBase(id, "running"),
33683
- name: `Session ${id}`,
33684
- commandType: "claude",
33685
- pty: spawnClaude2({
33686
- prompt: WATCH_PROMPT,
33687
- cwd,
33688
- sessionId: id,
33689
- claudeSessionId,
33690
- auto: true
33691
- }),
33692
- cwd,
33693
- claudeSessionId,
33694
- initialPrompt: WATCH_PROMPT,
33695
- starred: true,
33696
- watcher: true
33697
- };
33698
- }
33699
-
33700
- // src/commands/sessions/daemon/worktree/ensureWatcher.ts
33701
- function ensureWatcher(ctx, cwd) {
33702
- if (!cwd) return void 0;
33703
- const repoRoot2 = findRepoRoot(cwd) ?? cwd;
33704
- const cfg = worktreeConfigFor(repoRoot2);
33705
- if (!cfg.enabled || cfg.watcher !== true) return void 0;
33706
- const clone = mainWorktree(repoRoot2) ?? repoRoot2;
33707
- const live = liveWatcherFor(ctx.sessions, clone);
33708
- if (live) {
33709
- daemonLog(
33710
- `no watcher spawned for the clone ${clone}: session ${live.id} is already watching it (${live.status})`
33711
- );
33712
- return void 0;
33713
- }
33714
- const id = allocateAndBind(
33715
- ctx,
33716
- clone,
33717
- (sid, resolvedCwd) => createWatcherSession(sid, resolvedCwd ?? clone),
33718
- { inPlace: true }
33719
- );
33720
- daemonLog(
33721
- `spawned watcher session ${id} running /watch in the clone ${clone}`
33722
- );
33723
- return id;
33724
- }
33725
- function liveWatcherFor(sessions, clone) {
33726
- for (const session of sessions.values())
33727
- if (session.watcher === true && session.cwd === clone && session.status !== "stopped" && session.status !== "error")
33728
- return session;
33729
- return void 0;
33730
- }
33731
-
33732
33748
  // src/commands/sessions/daemon/worktree/resumeInReplacementTree.ts
33733
33749
  import { existsSync as existsSync76 } from "fs";
33734
33750
 
@@ -34294,7 +34310,9 @@ var messageHandlers = {
34294
34310
  ),
34295
34311
  "set-active": (_client, m, d) => m.active.set(d.cwd, d.sessionId),
34296
34312
  "set-status": handleSetStatus,
34297
- "verify-started": (client, m, d) => m.verify.start(client, d.sessionId),
34313
+ "verify-started": routed(
34314
+ (client, m, d) => m.verify.start(client, d.sessionId)
34315
+ ),
34298
34316
  "pr-preview": (client, m, d) => m.prPreview.set(client, d),
34299
34317
  "pr-decision": (_client, m, d) => m.prPreview.decide(d),
34300
34318
  "ui-status": (_client, _m, d) => daemonLog(`ui rendered: id=${d.sessionId} status=${d.status}`)
@@ -34945,10 +34963,12 @@ function syncCodex(claudeDir) {
34945
34963
  import * as fs45 from "fs";
34946
34964
  import * as path65 from "path";
34947
34965
  function syncDesign(claudeDir, targetBase) {
34948
- const systemPromptSource = path65.join(claudeDir, "system-prompt.md");
34949
- const systemPromptTarget = path65.join(targetBase, "system-prompt.md");
34966
+ const systemPromptSource = path65.join(claudeDir, "design-system-prompt.md");
34967
+ const systemPromptTarget = path65.join(targetBase, "design-system-prompt.md");
34950
34968
  fs45.copyFileSync(systemPromptSource, systemPromptTarget);
34951
- console.log("Copied system-prompt.md to ~/.claude/system-prompt.md");
34969
+ console.log(
34970
+ "Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
34971
+ );
34952
34972
  const skillsSource = path65.join(claudeDir, "skills");
34953
34973
  const skillsTarget = path65.join(targetBase, "skills");
34954
34974
  fs45.mkdirSync(skillsTarget, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.528.3",
3
+ "version": "0.530.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {