@shipers-dev/multi 0.11.0 → 0.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipers-dev/multi",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "multi-agent": "./dist/index.js"
@@ -10,7 +10,8 @@
10
10
  "build": "bun build src/index.ts --outdir=dist --target=bun"
11
11
  },
12
12
  "dependencies": {
13
- "@zed-industries/agent-client-protocol": "^0.4.5",
14
- "@zed-industries/claude-code-acp": "^0.16.2"
13
+ "@agentclientprotocol/sdk": "^0.20.0",
14
+ "@agentclientprotocol/claude-agent-acp": "^0.31.0",
15
+ "@multi/lib": "workspace:*"
15
16
  }
16
17
  }
package/src/acp-runner.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  // Spawns the adapter as a subprocess over stdio, converts ACP events → our StreamEvent shape
3
3
  // and handles client-side callbacks (requestPermission forwarded to server, fs read/write local).
4
4
 
5
- import { ClientSideConnection, ndJsonStream } from '@zed-industries/agent-client-protocol';
6
- import type { Client, SessionNotification, RequestPermissionRequest, RequestPermissionResponse, ReadTextFileRequest, ReadTextFileResponse, WriteTextFileRequest, WriteTextFileResponse } from '@zed-industries/agent-client-protocol';
5
+ import { ClientSideConnection, ndJsonStream } from '@agentclientprotocol/sdk';
6
+ import type { Client, SessionNotification, RequestPermissionRequest, RequestPermissionResponse, ReadTextFileRequest, ReadTextFileResponse, WriteTextFileRequest, WriteTextFileResponse } from '@agentclientprotocol/sdk';
7
7
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
8
8
  import { dirname } from 'path';
9
9
  import { apiClient } from './client';
@@ -22,13 +22,8 @@ function fmtErr(e: any): string {
22
22
  return String(e);
23
23
  }
24
24
 
25
- export type AcpEvent =
26
- | { event_type: 'progress'; payload: any }
27
- | { event_type: 'assistant_text'; payload: { text: string } }
28
- | { event_type: 'tool_call'; payload: { id: string; tool: string; kind?: string; status?: string; input?: any; locations?: any[] } }
29
- | { event_type: 'tool_result'; payload: { tool_use_id: string; content: string } }
30
- | { event_type: 'result'; payload: { result?: string; duration_ms?: number; total_cost_usd?: number; stopReason?: string } }
31
- | { event_type: 'error'; payload: { message: string } };
25
+ import type { CliStreamEmit } from '@multi/lib';
26
+ export type AcpEvent = CliStreamEmit;
32
27
 
33
28
  export type AcpRunOpts = {
34
29
  apiUrl: string;
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ import { apiClient, setAuthToken } from './client';
5
5
  import { Database } from 'bun:sqlite';
6
6
  import { runAcp } from './acp-runner';
7
7
  import { runAcpx } from './acpx-runner';
8
+ import { STREAM_SCHEMA_VERSION, type StreamEventType, type CliStreamEmit } from '@multi/lib';
8
9
  import { ensureWorktree } from './worktree';
9
10
  import { materializeBundle, lastMaterializedRevision } from './materializer';
10
11
  import { parseArgs } from 'util';
@@ -1130,7 +1131,7 @@ Rules:
1130
1131
  - Omit the block if no actions are needed.
1131
1132
  - Max 10 actions per turn. Sub-caps: agent.create=2, skill.create=3 per turn.
1132
1133
  - Planning depth capped at ${PLANNING_DEPTH_LIMIT}. At depth ≥ 1 you can only \`update\` your own issue — no creates, no agents, no skills.
1133
- - \`agent.create\` produces an agent in **pending** status. A human must approve it before any issue can be dispatched to it.
1134
+ - \`agent.create\` is auto-approved on auto-autonomy issues. Caps + rate limits prevent abuse.
1134
1135
  - \`skill.create\` ALWAYS waits for human review (skill bodies become future system prompts).
1135
1136
  - \`allowed_tools\` on a new agent must be a subset of your own tools.
1136
1137
  - \`create\` / \`update\` / \`delegate\` target issues only in the current project (${projectId || 'this project'}).
@@ -1235,7 +1236,7 @@ async function executePlanActions(apiUrl: string, parentTask: any, actions: Plan
1235
1236
  const res = await apiClient.post<any>(`${apiUrl}/api/agent_ops/agents/mutate`, { action: 'create', name: a.name, type: a.agent_type, prompt: a.prompt, skill_ids: a.skill_ids, allowed_tools: a.allowed_tools }, { headers });
1236
1237
  if (!res.success) { lines.push(`- ❌ agent.create "${a.name}": ${res.error || res.status}`); continue; }
1237
1238
  if (res.data?.queued) lines.push(`- ⏳ agent.create "${a.name}" queued for human approval (op ${res.data.pending_op_id})`);
1238
- else lines.push(`- ✓ agent.create "${a.name}" → ${res.data?.agent_id} (status=pending — needs human approval before dispatch)`);
1239
+ else lines.push(`- ✓ agent.create "${a.name}" → ${res.data?.agent_id}`);
1239
1240
  } else if (a.type === 'agent.update') {
1240
1241
  const res = await apiClient.post<any>(`${apiUrl}/api/agent_ops/agents/mutate`, { action: 'update', ...a }, { headers });
1241
1242
  if (!res.success) { lines.push(`- ❌ agent.update ${a.id}: ${res.error || res.status}`); continue; }
@@ -1304,8 +1305,8 @@ async function resolveAcpAdapter(agentType: string, detectedPath?: string): Prom
1304
1305
  return [detectedPath, '--mode', 'rpc'];
1305
1306
  }
1306
1307
 
1307
- // claude-code → Zed adapter wrapper (stdio ACP)
1308
- const adapterName = 'claude-code-acp';
1308
+ // claude-code → claude-agent-acp adapter wrapper (stdio ACP)
1309
+ const adapterName = 'claude-agent-acp';
1309
1310
  const candidates = [
1310
1311
  join(HOME, '.bun', 'install', 'global', 'node_modules', '.bin', adapterName),
1311
1312
  ];
@@ -1371,7 +1372,7 @@ async function drainOfflineDispatches(apiUrl: string, deviceId: string, secret:
1371
1372
  onEnqueued();
1372
1373
  }
1373
1374
 
1374
- async function postStream(apiUrl: string, issueId: string, event_type: string, payload: any) {
1375
+ async function postStream(apiUrl: string, issueId: string, event_type: StreamEventType, payload: unknown) {
1375
1376
  // Local ndjson sink for tail -f debugging.
1376
1377
  try {
1377
1378
  ensureDirs();
@@ -1379,7 +1380,9 @@ async function postStream(apiUrl: string, issueId: string, event_type: string, p
1379
1380
  const path = join(MULTI_DIR, 'logs', `events-${date}.ndjson`);
1380
1381
  appendFileSync(path, JSON.stringify({ ts: Date.now(), issue_id: issueId, event_type, payload }) + '\n');
1381
1382
  } catch {}
1382
- await apiClient.post(`${apiUrl}/api/streams/${issueId}`, { event_type, payload });
1383
+ await apiClient.post(`${apiUrl}/api/streams/${issueId}`, { event_type, payload }, {
1384
+ headers: { 'X-Stream-Version': String(STREAM_SCHEMA_VERSION) },
1385
+ });
1383
1386
  }
1384
1387
 
1385
1388
  // Download attachments of a comment to a local dir. Returns list of absolute paths.
@@ -1445,7 +1448,7 @@ async function uploadOutputDir(apiUrl: string, commentId: string, dir: string):
1445
1448
  return uploaded;
1446
1449
  }
1447
1450
 
1448
- type StreamEvent = { event_type: 'progress' | 'stdout' | 'stderr' | 'tool_call' | 'done' | 'error'; payload: any };
1451
+ type StreamEvent = CliStreamEmit;
1449
1452
  type Runner = (task: any) => AsyncGenerator<StreamEvent>;
1450
1453
 
1451
1454
  function pickRunner(detected: { type: string; path: string }[], preferType?: string): Runner {