@ctrl-spc/cli 1.1.14 → 1.1.15

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.
@@ -11,6 +11,14 @@ export function makeControlRequestProcessor(deps) {
11
11
  .limit(1);
12
12
  return data?.[0]?.value ?? null;
13
13
  }
14
+ async function resolveMachineLabel() {
15
+ const { data } = await deps.session.client
16
+ .from('devices')
17
+ .select('label')
18
+ .eq('id', deps.session.machineId)
19
+ .single();
20
+ return (data?.label ?? 'This machine').trim() || 'This machine';
21
+ }
14
22
  async function mark(row, patch) {
15
23
  await deps.session.client.from('agent_control_requests').update(patch).eq('id', row.id);
16
24
  }
@@ -44,7 +52,7 @@ export function makeControlRequestProcessor(deps) {
44
52
  async function findSession(row) {
45
53
  let query = deps.session.client
46
54
  .from('sessions')
47
- .select('id, project_id, agent_type, model, effort, permission_mode, allowed_tools')
55
+ .select('id, project_id, device_id, agent_type, model, effort, permission_mode, allowed_tools')
48
56
  .eq('project_id', row.project_id)
49
57
  .is('ended_at', null);
50
58
  if (row.session_id)
@@ -66,8 +74,7 @@ export function makeControlRequestProcessor(deps) {
66
74
  throw new Error(`Message insert failed: ${error.message}`);
67
75
  return data?.id ?? null;
68
76
  }
69
- async function processPing(row) {
70
- const session = await findSession(row);
77
+ async function processPing(row, session) {
71
78
  if (!session) {
72
79
  await mark(row, completedPatch('failed', 'No active agent session was found.'));
73
80
  return;
@@ -80,15 +87,15 @@ export function makeControlRequestProcessor(deps) {
80
87
  const { cmd, args } = assembleCommand(session, PING_PROMPT);
81
88
  const handle = deps.spawnAgent(cmd, args, cwd);
82
89
  const stdout = await collectStdout(handle);
83
- const responseId = await insertMessage(row, session.id, 'agent', 'ping', cleanAgentText(stdout));
90
+ const machineLabel = await resolveMachineLabel();
91
+ const responseId = await insertMessage(row, session.id, 'agent', 'ping', `${machineLabel} responded: ${cleanAgentText(stdout)}`);
84
92
  await mark(row, { ...completedPatch('succeeded'), response_message_id: responseId });
85
93
  }
86
- async function processStop(row) {
94
+ async function processStop(row, session) {
87
95
  const owned = row.session_id
88
96
  ? deps.ownedSessions.get(row.session_id)
89
97
  : [...deps.ownedSessions.values()].find((entry) => entry.projectId === row.project_id);
90
98
  if (!owned) {
91
- const session = await findSession(row);
92
99
  if (session) {
93
100
  const endedAt = new Date(deps.now()).toISOString();
94
101
  await deps.session.client.from('sessions').update({
@@ -117,13 +124,16 @@ export function makeControlRequestProcessor(deps) {
117
124
  await mark(row, { status: 'succeeded', completed_at: endedAt });
118
125
  }
119
126
  async function processOne(row) {
127
+ const session = await findSession(row);
128
+ if (session?.device_id && session.device_id !== deps.session.machineId)
129
+ return;
120
130
  await mark(row, { status: 'processing' });
121
131
  if (row.action === 'ping') {
122
- await processPing(row);
132
+ await processPing(row, session);
123
133
  return;
124
134
  }
125
135
  if (row.action === 'stop') {
126
- await processStop(row);
136
+ await processStop(row, session);
127
137
  return;
128
138
  }
129
139
  await mark(row, completedPatch('failed', 'This control request is not supported by this version of the daemon.'));
package/dist/spawner.js CHANGED
@@ -77,6 +77,8 @@ export function makeSpawner(deps) {
77
77
  async function processOne(row) {
78
78
  if (!isRemote(row.agent_type))
79
79
  return; // manual types are never auto-fulfilled
80
+ if (row.target_device_id && row.target_device_id !== deps.session.machineId)
81
+ return;
80
82
  const last = lastAttempt.get(row.id);
81
83
  if (last !== undefined && deps.now() - last < backoffMs)
82
84
  return;
@@ -102,7 +104,7 @@ export function makeSpawner(deps) {
102
104
  async function processPending() {
103
105
  const { data, error } = await deps.session.client
104
106
  .from('spawn_requests')
105
- .select('id, project_id, agent_type, model, effort, permission_mode, allowed_tools')
107
+ .select('id, project_id, target_device_id, agent_type, model, effort, permission_mode, allowed_tools')
106
108
  .eq('status', 'pending');
107
109
  if (error) {
108
110
  deps.log(`spawn_requests scan failed: ${error.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-spc/cli",
3
- "version": "1.1.14",
3
+ "version": "1.1.15",
4
4
  "description": "Control Space CLI - machine setup and background daemon",
5
5
  "type": "module",
6
6
  "files": [