@love-moon/conductor-sdk 0.12.0 → 0.13.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @love-moon/conductor-sdk
2
2
 
3
+ ## 0.13.1
4
+
5
+ ## 0.13.0
6
+
7
+ ### Patch Changes
8
+
9
+ - 80ab13e: `listTasks({ projectId })` now lists a project's tasks by their real project.
10
+
11
+ Tasks can now be moved (filed) under any project in the web UI. That move is
12
+ display-only, and `GET /api/tasks?project_id=` keeps grouping by where a task is
13
+ filed for user-facing clients. The SDK now sends `project_scope=real`, so an
14
+ agent's `list_tasks` still sees every task that actually belongs to the project
15
+ (including ones the user filed elsewhere) and does not pick up tasks filed into
16
+ it from other projects.
17
+
3
18
  ## 0.12.0
4
19
 
5
20
  ## 0.11.2
@@ -6,6 +6,8 @@ export interface Issue {
6
6
  description?: string | null;
7
7
  status: string;
8
8
  priority?: string | null;
9
+ /** "feature", "bug", or "research". */
10
+ type?: string | null;
9
11
  position?: number | null;
10
12
  metadata?: Record<string, unknown> | null;
11
13
  createdAt?: string | null;
@@ -23,6 +25,7 @@ export interface CreateIssueInput {
23
25
  title: string;
24
26
  description?: string;
25
27
  priority?: string;
28
+ type?: string;
26
29
  status?: string;
27
30
  metadata?: Record<string, unknown>;
28
31
  clientRequestId?: string;
@@ -31,6 +34,7 @@ export interface UpdateIssueInput {
31
34
  title?: string;
32
35
  description?: string;
33
36
  priority?: string;
37
+ type?: string;
34
38
  status?: string;
35
39
  metadata?: Record<string, unknown>;
36
40
  }
@@ -11,6 +11,7 @@ const normalizeIssue = (payload) => {
11
11
  description: payload.description ?? null,
12
12
  status: String(payload.status ?? ''),
13
13
  priority: payload.priority ?? null,
14
+ type: payload.type ?? null,
14
15
  position: typeof payload.position === 'number' ? payload.position : null,
15
16
  metadata: payload.metadata && typeof payload.metadata === 'object' && !Array.isArray(payload.metadata)
16
17
  ? payload.metadata
@@ -109,6 +110,9 @@ export class IssuesApi {
109
110
  if (input.priority !== undefined) {
110
111
  params.priority = input.priority;
111
112
  }
113
+ if (input.type !== undefined) {
114
+ params.type = input.type;
115
+ }
112
116
  if (input.status !== undefined) {
113
117
  params.status = input.status;
114
118
  }
@@ -130,6 +134,9 @@ export class IssuesApi {
130
134
  if (patch.priority !== undefined) {
131
135
  params.priority = patch.priority;
132
136
  }
137
+ if (patch.type !== undefined) {
138
+ params.type = patch.type;
139
+ }
133
140
  if (patch.status !== undefined) {
134
141
  params.status = patch.status;
135
142
  }
@@ -157,6 +157,10 @@ export class BackendApiClient {
157
157
  const query = new URLSearchParams();
158
158
  if (params.projectId) {
159
159
  query.set('project_id', params.projectId);
160
+ // Match the task's REAL project. By default the server groups by where the
161
+ // user filed a task in the web UI (display-only), which would hide this
162
+ // project's filed-out tasks from agents and include foreign ones.
163
+ query.set('project_scope', 'real');
160
164
  }
161
165
  if (params.status) {
162
166
  query.set('status', params.status);
package/dist/client.d.ts CHANGED
@@ -31,6 +31,7 @@ export interface ConductorClientConnectOptions {
31
31
  onStopTask?: (event: StopTaskEvent) => Promise<void> | void;
32
32
  onInterruptTurn?: (event: InterruptTurnEvent) => Promise<boolean | void> | boolean | void;
33
33
  onRefreshSession?: (event: RefreshSessionEvent) => Promise<boolean | void> | boolean | void;
34
+ onReportRuntimeStatus?: (event: ReportRuntimeStatusEvent) => Promise<void> | void;
34
35
  }
35
36
  interface ConductorClientInit {
36
37
  config: ConductorConfig;
@@ -50,6 +51,7 @@ interface ConductorClientInit {
50
51
  onStopTask?: (event: StopTaskEvent) => Promise<void> | void;
51
52
  onInterruptTurn?: (event: InterruptTurnEvent) => Promise<boolean | void> | boolean | void;
52
53
  onRefreshSession?: (event: RefreshSessionEvent) => Promise<boolean | void> | boolean | void;
54
+ onReportRuntimeStatus?: (event: ReportRuntimeStatusEvent) => Promise<void> | void;
53
55
  }
54
56
  export interface StopTaskEvent {
55
57
  taskId: string;
@@ -69,6 +71,9 @@ export interface RefreshSessionEvent {
69
71
  sessionId: string;
70
72
  sessionFilePath?: string;
71
73
  }
74
+ export interface ReportRuntimeStatusEvent {
75
+ taskId: string;
76
+ }
72
77
  export interface FlushPendingUpstreamEventsOptions {
73
78
  timeoutMs?: number;
74
79
  retryIntervalMs?: number;
@@ -90,6 +95,7 @@ export declare class ConductorClient {
90
95
  private readonly onStopTask?;
91
96
  private readonly onInterruptTurn?;
92
97
  private readonly onRefreshSession?;
98
+ private readonly onReportRuntimeStatus?;
93
99
  private deliveryScopeId;
94
100
  private closed;
95
101
  private durableOutboxFlushPromise;
package/dist/client.js CHANGED
@@ -36,6 +36,7 @@ export class ConductorClient {
36
36
  onStopTask;
37
37
  onInterruptTurn;
38
38
  onRefreshSession;
39
+ onReportRuntimeStatus;
39
40
  deliveryScopeId;
40
41
  closed = false;
41
42
  durableOutboxFlushPromise = null;
@@ -63,6 +64,7 @@ export class ConductorClient {
63
64
  this.onStopTask = init.onStopTask;
64
65
  this.onInterruptTurn = init.onInterruptTurn;
65
66
  this.onRefreshSession = init.onRefreshSession;
67
+ this.onReportRuntimeStatus = init.onReportRuntimeStatus;
66
68
  this.deliveryScopeId = init.deliveryScopeId;
67
69
  this.wsClient.registerHandler(this.handleBackendEvent);
68
70
  }
@@ -115,6 +117,7 @@ export class ConductorClient {
115
117
  onStopTask: options.onStopTask,
116
118
  onInterruptTurn: options.onInterruptTurn,
117
119
  onRefreshSession: options.onRefreshSession,
120
+ onReportRuntimeStatus: options.onReportRuntimeStatus,
118
121
  });
119
122
  client.replayDurableDownstreamInbox();
120
123
  try {
@@ -510,12 +513,19 @@ export class ConductorClient {
510
513
  ? payload.hostname
511
514
  : existing?.hostname ?? this.resolveHostname(),
512
515
  });
516
+ // An explicit project_path is the fire's real working directory; record it
517
+ // as `cwd` so an attached terminal opens where the task actually runs.
518
+ const explicitCwd = typeof payload.project_path === 'string' && payload.project_path ? payload.project_path : null;
519
+ const metadata = {
520
+ ...(explicitDaemonName ? { daemonName: explicitDaemonName } : {}),
521
+ ...(explicitCwd ? { cwd: explicitCwd } : {}),
522
+ };
513
523
  if (typeof this.backendApi.updateTask === 'function') {
514
524
  await this.backendApi.updateTask(normalizedTaskId, {
515
525
  backendType: record.backendType ?? null,
516
526
  sessionId: record.sessionId ?? null,
517
527
  sessionFilePath: record.sessionFilePath ?? null,
518
- metadata: explicitDaemonName ? { daemonName: explicitDaemonName } : undefined,
528
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
519
529
  });
520
530
  }
521
531
  return {
@@ -608,6 +618,19 @@ export class ConductorClient {
608
618
  });
609
619
  return;
610
620
  }
621
+ if (typeof payload?.type === 'string' && payload.type === 'report_runtime_status') {
622
+ // Best-effort, non-durable: the app re-asks on its next page load.
623
+ const taskId = typeof payload.payload?.task_id === 'string' ? payload.payload.task_id.trim() : '';
624
+ if (taskId && this.onReportRuntimeStatus) {
625
+ void Promise.resolve()
626
+ .then(() => this.onReportRuntimeStatus?.({ taskId }))
627
+ .catch((error) => {
628
+ const message = error instanceof Error ? error.message : String(error);
629
+ console.warn(`[sdk] report_runtime_status callback failed for task ${taskId}: ${message}`);
630
+ });
631
+ }
632
+ return;
633
+ }
611
634
  if (typeof payload?.type === 'string' && payload.type === 'interrupt_turn') {
612
635
  await this.handleInterruptTurnCommand(payload);
613
636
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@love-moon/conductor-sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/lovemoon-ai/conductor.git"
@@ -33,5 +33,5 @@
33
33
  "typescript": "^5.6.3",
34
34
  "vitest": "^2.1.4"
35
35
  },
36
- "gitCommitId": "c1047e8"
36
+ "gitCommitId": "b82ba1c"
37
37
  }