@staff0rd/assist 0.394.0 → 0.396.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.394.0",
9
+ version: "0.396.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -6437,6 +6437,7 @@ import { dirname as dirname16, join as join20 } from "path";
6437
6437
  import { z as z4 } from "zod";
6438
6438
  var activitySchema = z4.object({
6439
6439
  kind: z4.enum(["command", "backlog"]),
6440
+ harness: z4.enum(["claude", "codex", "pi"]).optional(),
6440
6441
  name: z4.string().optional(),
6441
6442
  itemId: z4.number().optional(),
6442
6443
  itemName: z4.string().optional(),
@@ -8466,11 +8467,13 @@ async function listUsagePeaks(db, paging) {
8466
8467
  resetsAt: phaseCycleContext.resetsAt,
8467
8468
  avgContextPct: sql11`cast(avg(${phaseCycleContext.peakContextPct}) as double precision)`.as(
8468
8469
  "avg_context_pct"
8469
- )
8470
+ ),
8471
+ phaseCount: count().as("phase_count")
8470
8472
  }).from(phaseCycleContext).groupBy(phaseCycleContext.window, phaseCycleContext.resetsAt).as("avg_context");
8471
8473
  const query = db.select({
8472
8474
  ...getTableColumns(usagePeaks),
8473
- avgContextPct: avgContext.avgContextPct
8475
+ avgContextPct: avgContext.avgContextPct,
8476
+ phaseCount: avgContext.phaseCount
8474
8477
  }).from(usagePeaks).leftJoin(
8475
8478
  avgContext,
8476
8479
  and7(
@@ -23666,9 +23669,6 @@ function reportStrays(pids) {
23666
23669
  // src/commands/sessions/daemon/drainDaemon.ts
23667
23670
  import { createInterface as createInterface6 } from "readline";
23668
23671
 
23669
- // src/commands/sessions/daemon/loadPersistedSessions.ts
23670
- import { z as z5 } from "zod";
23671
-
23672
23672
  // src/commands/sessions/daemon/daemonLog.ts
23673
23673
  var RING_CAPACITY = 1e3;
23674
23674
  var ring = [];
@@ -23692,13 +23692,14 @@ function recentDaemonLogLines() {
23692
23692
  return [...ring];
23693
23693
  }
23694
23694
 
23695
- // src/commands/sessions/daemon/loadPersistedSessions.ts
23696
- var SESSIONS_FILE = "sessions.json";
23695
+ // src/commands/sessions/daemon/persistedSessionSchema.ts
23696
+ import { z as z5 } from "zod";
23697
23697
  var persistedSessionSchema = z5.object({
23698
23698
  name: z5.string(),
23699
23699
  title: z5.string().optional(),
23700
23700
  subtitle: z5.string().optional(),
23701
23701
  commandType: z5.enum(["claude", "run", "assist"]),
23702
+ harness: z5.enum(["claude", "codex", "pi"]).optional(),
23702
23703
  status: z5.enum(["running", "waiting", "done", "error"]).optional(),
23703
23704
  cwd: z5.string(),
23704
23705
  startedAt: z5.number(),
@@ -23711,6 +23712,34 @@ var persistedSessionSchema = z5.object({
23711
23712
  activity: activitySchema.optional(),
23712
23713
  starred: z5.boolean().optional()
23713
23714
  });
23715
+
23716
+ // src/commands/sessions/daemon/toPersistedSession.ts
23717
+ function toPersistedSession(session) {
23718
+ return {
23719
+ name: session.name,
23720
+ title: session.title,
23721
+ subtitle: session.subtitle,
23722
+ commandType: session.commandType,
23723
+ harness: session.harness,
23724
+ status: session.status,
23725
+ cwd: session.cwd ?? process.cwd(),
23726
+ startedAt: session.startedAt,
23727
+ runningMs: accumulatedRunningMs(session),
23728
+ claudeSessionId: session.claudeSessionId,
23729
+ initialPrompt: session.initialPrompt,
23730
+ runName: session.runName,
23731
+ runArgs: session.runArgs,
23732
+ assistArgs: session.assistArgs,
23733
+ activity: session.activity,
23734
+ starred: session.starred
23735
+ };
23736
+ }
23737
+ function accumulatedRunningMs(session) {
23738
+ return session.runningSince != null ? session.runningMs + Date.now() - session.runningSince : session.runningMs;
23739
+ }
23740
+
23741
+ // src/commands/sessions/daemon/loadPersistedSessions.ts
23742
+ var SESSIONS_FILE = "sessions.json";
23714
23743
  function loadPersistedSessions() {
23715
23744
  const data = loadJson(SESSIONS_FILE);
23716
23745
  if (!Array.isArray(data)) return [];
@@ -23738,28 +23767,6 @@ function logPersist(live) {
23738
23767
  live.length > 0 ? `persisted ${live.length} session(s): ${live.map((s) => s.name).join(", ")}` : "persisted 0 sessions (sessions.json cleared)"
23739
23768
  );
23740
23769
  }
23741
- function toPersistedSession(session) {
23742
- return {
23743
- name: session.name,
23744
- title: session.title,
23745
- subtitle: session.subtitle,
23746
- commandType: session.commandType,
23747
- status: session.status,
23748
- cwd: session.cwd ?? process.cwd(),
23749
- startedAt: session.startedAt,
23750
- runningMs: accumulatedRunningMs(session),
23751
- claudeSessionId: session.claudeSessionId,
23752
- initialPrompt: session.initialPrompt,
23753
- runName: session.runName,
23754
- runArgs: session.runArgs,
23755
- assistArgs: session.assistArgs,
23756
- activity: session.activity,
23757
- starred: session.starred
23758
- };
23759
- }
23760
- function accumulatedRunningMs(session) {
23761
- return session.runningSince != null ? session.runningMs + Date.now() - session.runningSince : session.runningMs;
23762
- }
23763
23770
 
23764
23771
  // src/commands/sessions/daemon/drainDaemon.ts
23765
23772
  var DRAIN_TIMEOUT_MS = 5e3;
@@ -23870,6 +23877,7 @@ function toSessionInfo({
23870
23877
  title,
23871
23878
  subtitle,
23872
23879
  commandType,
23880
+ harness,
23873
23881
  status: status3,
23874
23882
  startedAt,
23875
23883
  runningMs,
@@ -23893,6 +23901,7 @@ function toSessionInfo({
23893
23901
  title,
23894
23902
  subtitle,
23895
23903
  commandType,
23904
+ harness,
23896
23905
  status: status3,
23897
23906
  startedAt,
23898
23907
  runningMs,
@@ -24100,6 +24109,13 @@ function buildArgs3(opts) {
24100
24109
  return base;
24101
24110
  }
24102
24111
 
24112
+ // src/commands/sessions/daemon/spawnPi.ts
24113
+ function spawnPi2(opts = {}) {
24114
+ const args = ["pi"];
24115
+ if (opts.prompt) args.push(opts.prompt);
24116
+ return spawnPty(args, opts.cwd, opts.sessionId);
24117
+ }
24118
+
24103
24119
  // src/commands/sessions/daemon/spawnRun.ts
24104
24120
  function spawnRun(opts) {
24105
24121
  return spawnPty(["assist", "run", opts.name, ...opts.args ?? []], opts.cwd);
@@ -24119,7 +24135,8 @@ function sessionBase(id, status3) {
24119
24135
  scrollback: ""
24120
24136
  };
24121
24137
  }
24122
- function createSession(id, prompt, cwd, design) {
24138
+ function createSession(id, prompt, cwd, design, harness) {
24139
+ if (harness === "pi") return createPiSession(id, prompt, cwd);
24123
24140
  const claudeSessionId = randomUUID4();
24124
24141
  return {
24125
24142
  ...sessionBase(id, prompt ? "running" : "waiting"),
@@ -24132,6 +24149,17 @@ function createSession(id, prompt, cwd, design) {
24132
24149
  design
24133
24150
  };
24134
24151
  }
24152
+ function createPiSession(id, prompt, cwd) {
24153
+ return {
24154
+ ...sessionBase(id, prompt ? "running" : "waiting"),
24155
+ name: prompt?.slice(0, 40) || `Session ${id}`,
24156
+ commandType: "claude",
24157
+ harness: "pi",
24158
+ pty: spawnPi2({ prompt, cwd, sessionId: id }),
24159
+ cwd,
24160
+ initialPrompt: prompt
24161
+ };
24162
+ }
24135
24163
  function createRunSession(id, runName, runArgs, cwd) {
24136
24164
  return {
24137
24165
  ...sessionBase(id, "running"),
@@ -24796,6 +24824,7 @@ function restoreBase(id, persisted) {
24796
24824
  title: persisted.title,
24797
24825
  subtitle: persisted.subtitle,
24798
24826
  commandType: persisted.commandType,
24827
+ harness: persisted.harness,
24799
24828
  scrollback: "",
24800
24829
  cwd: persisted.cwd,
24801
24830
  assistArgs: persisted.assistArgs,
@@ -25809,8 +25838,10 @@ var SessionManager = class {
25809
25838
  return session.id;
25810
25839
  }
25811
25840
  spawnWith = (create) => this.add(create(sessionLimits.nextId(this.sessions.size, this.idCounter)));
25812
- spawn(prompt, cwd, design) {
25813
- return this.spawnWith((id) => createSession(id, prompt, cwd, design));
25841
+ spawn(prompt, cwd, design, harness) {
25842
+ return this.spawnWith(
25843
+ (id) => createSession(id, prompt, cwd, design, harness)
25844
+ );
25814
25845
  }
25815
25846
  spawnRun(runName, runArgs, cwd) {
25816
25847
  return this.spawnWith((id) => createRunSession(id, runName, runArgs, cwd));
@@ -26009,12 +26040,16 @@ var lifecycleHandlers = {
26009
26040
  // src/commands/sessions/daemon/spawnCreate.ts
26010
26041
  function spawnCreate(m, d) {
26011
26042
  const design = d.design === true;
26043
+ const harness = d.harness;
26012
26044
  if (design)
26013
26045
  daemonLog(`create: design session (cwd=${d.cwd ?? ""})`);
26046
+ if (harness && harness !== "claude")
26047
+ daemonLog(`create: ${harness} session (cwd=${d.cwd ?? ""})`);
26014
26048
  return m.spawn(
26015
26049
  d.prompt,
26016
26050
  d.cwd,
26017
- design
26051
+ design,
26052
+ harness
26018
26053
  );
26019
26054
  }
26020
26055
 
@@ -26850,16 +26885,21 @@ import * as path63 from "path";
26850
26885
  // src/commands/sync/syncPiHooks.ts
26851
26886
  import * as fs43 from "fs";
26852
26887
  import * as path62 from "path";
26853
- var PI_PERMISSION_GATE_FILE = "assist-permission-gate.ts";
26854
- function piPermissionGateTarget() {
26855
- return path62.join(harnesses.pi.homeDir, "extensions", PI_PERMISSION_GATE_FILE);
26856
- }
26857
- function syncPiHooks(sourcePath) {
26858
- const target = piPermissionGateTarget();
26859
- fs43.mkdirSync(path62.dirname(target), { recursive: true });
26860
- fs43.copyFileSync(sourcePath, target);
26888
+ function piExtensionsDir() {
26889
+ return path62.join(harnesses.pi.homeDir, "extensions");
26890
+ }
26891
+ function syncPiHooks(sourceDir) {
26892
+ const target = piExtensionsDir();
26893
+ fs43.mkdirSync(target, { recursive: true });
26894
+ const files = fs43.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
26895
+ for (const file of files) {
26896
+ fs43.copyFileSync(
26897
+ path62.join(sourceDir, file),
26898
+ path62.join(target, `assist-${file}`)
26899
+ );
26900
+ }
26861
26901
  console.log(
26862
- "Registered assist permission-gate extension in ~/.pi/agent/extensions"
26902
+ `Registered ${files.length} assist extension(s) in ~/.pi/agent/extensions`
26863
26903
  );
26864
26904
  }
26865
26905
 
@@ -26892,7 +26932,7 @@ function syncPi(claudeDir) {
26892
26932
  harnesses.pi,
26893
26933
  commandToPrompt
26894
26934
  );
26895
- syncPiHooks(path63.join(claudeDir, "..", "pi", "permission-gate.ts"));
26935
+ syncPiHooks(path63.join(claudeDir, "..", "pi"));
26896
26936
  console.log(
26897
26937
  `Synced ${synced} prompt(s) to ~/.pi/agent/prompts and CLAUDE.md to ~/.pi/agent/AGENTS.md`
26898
26938
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.394.0",
3
+ "version": "0.396.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -0,0 +1,22 @@
1
+ import { spawn } from "node:child_process";
2
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
+
4
+ function setStatus(status: "running" | "waiting"): void {
5
+ try {
6
+ const child = spawn("assist", ["sessions", "set-status", status], {
7
+ stdio: "ignore",
8
+ detached: true,
9
+ });
10
+ child.on("error", () => {});
11
+ child.unref();
12
+ } catch {}
13
+ }
14
+
15
+ export default function (pi: ExtensionAPI) {
16
+ pi.on("agent_start", () => {
17
+ setStatus("running");
18
+ });
19
+ pi.on("agent_settled", () => {
20
+ setStatus("waiting");
21
+ });
22
+ }