@love-moon/conductor-sdk 0.2.32 → 0.2.33
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/backend/client.d.ts +34 -6
- package/dist/backend/client.js +30 -6
- package/dist/client.d.ts +2 -1
- package/dist/client.js +70 -18
- package/dist/context/project_context.d.ts +11 -0
- package/dist/context/project_context.js +44 -0
- package/package.json +2 -2
package/dist/backend/client.d.ts
CHANGED
|
@@ -36,8 +36,14 @@ export declare class BackendApiError extends Error {
|
|
|
36
36
|
export declare class ProjectSummary {
|
|
37
37
|
readonly id: string;
|
|
38
38
|
readonly name?: string | undefined;
|
|
39
|
-
readonly
|
|
40
|
-
|
|
39
|
+
readonly daemonHost?: string | null | undefined;
|
|
40
|
+
readonly workspacePath?: string | null | undefined;
|
|
41
|
+
readonly repoRoot?: string | null | undefined;
|
|
42
|
+
readonly worktreeBranch?: string | null | undefined;
|
|
43
|
+
readonly lastCommit?: string | null | undefined;
|
|
44
|
+
readonly fileCount?: number | null | undefined;
|
|
45
|
+
readonly isDefault?: boolean | undefined;
|
|
46
|
+
constructor(id: string, name?: string | undefined, daemonHost?: string | null | undefined, workspacePath?: string | null | undefined, repoRoot?: string | null | undefined, worktreeBranch?: string | null | undefined, lastCommit?: string | null | undefined, fileCount?: number | null | undefined, isDefault?: boolean | undefined);
|
|
41
47
|
static fromJSON(payload: Record<string, any>): ProjectSummary;
|
|
42
48
|
asObject(): Record<string, unknown>;
|
|
43
49
|
}
|
|
@@ -62,9 +68,16 @@ export declare class BackendApiClient {
|
|
|
62
68
|
constructor(config: ConductorConfig, options?: BackendClientOptions);
|
|
63
69
|
listProjects(): Promise<ProjectSummary[]>;
|
|
64
70
|
createProject(params: {
|
|
65
|
-
name
|
|
66
|
-
description?: string;
|
|
71
|
+
name?: string;
|
|
67
72
|
metadata?: Record<string, unknown>;
|
|
73
|
+
isDefault?: boolean;
|
|
74
|
+
bindingConfirmed?: boolean;
|
|
75
|
+
daemonHost?: string;
|
|
76
|
+
workspacePath?: string;
|
|
77
|
+
repoRoot?: string;
|
|
78
|
+
worktreeBranch?: string;
|
|
79
|
+
lastCommit?: string;
|
|
80
|
+
fileCount?: number;
|
|
68
81
|
}): Promise<ProjectSummary>;
|
|
69
82
|
listTasks(params?: {
|
|
70
83
|
projectId?: string;
|
|
@@ -132,7 +145,9 @@ export declare class BackendApiClient {
|
|
|
132
145
|
accepted?: boolean;
|
|
133
146
|
}): Promise<Record<string, unknown>>;
|
|
134
147
|
matchProjectByPath(params: {
|
|
135
|
-
hostname
|
|
148
|
+
hostname?: string;
|
|
149
|
+
daemonHost?: string;
|
|
150
|
+
daemon_host?: string;
|
|
136
151
|
path: string;
|
|
137
152
|
}): Promise<{
|
|
138
153
|
project: ProjectSummary | null;
|
|
@@ -141,12 +156,25 @@ export declare class BackendApiClient {
|
|
|
141
156
|
getProject(projectId: string): Promise<{
|
|
142
157
|
id: string;
|
|
143
158
|
name?: string;
|
|
144
|
-
description?: string | null;
|
|
145
159
|
metadata?: Record<string, unknown>;
|
|
160
|
+
daemonHost?: string | null;
|
|
161
|
+
workspacePath?: string | null;
|
|
162
|
+
repoRoot?: string | null;
|
|
163
|
+
worktreeBranch?: string | null;
|
|
164
|
+
lastCommit?: string | null;
|
|
165
|
+
fileCount?: number | null;
|
|
166
|
+
isDefault?: boolean;
|
|
146
167
|
}>;
|
|
147
168
|
updateProject(projectId: string, params: {
|
|
148
169
|
name?: string;
|
|
149
170
|
metadata?: Record<string, unknown>;
|
|
171
|
+
bindingConfirmed?: boolean;
|
|
172
|
+
daemonHost?: string;
|
|
173
|
+
workspacePath?: string;
|
|
174
|
+
repoRoot?: string;
|
|
175
|
+
worktreeBranch?: string;
|
|
176
|
+
lastCommit?: string;
|
|
177
|
+
fileCount?: number;
|
|
150
178
|
}): Promise<ProjectSummary>;
|
|
151
179
|
private request;
|
|
152
180
|
private buildUrl;
|
package/dist/backend/client.js
CHANGED
|
@@ -10,24 +10,42 @@ export class BackendApiError extends Error {
|
|
|
10
10
|
export class ProjectSummary {
|
|
11
11
|
id;
|
|
12
12
|
name;
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
daemonHost;
|
|
14
|
+
workspacePath;
|
|
15
|
+
repoRoot;
|
|
16
|
+
worktreeBranch;
|
|
17
|
+
lastCommit;
|
|
18
|
+
fileCount;
|
|
19
|
+
isDefault;
|
|
20
|
+
constructor(id, name, daemonHost, workspacePath, repoRoot, worktreeBranch, lastCommit, fileCount, isDefault) {
|
|
15
21
|
this.id = id;
|
|
16
22
|
this.name = name;
|
|
17
|
-
this.
|
|
23
|
+
this.daemonHost = daemonHost;
|
|
24
|
+
this.workspacePath = workspacePath;
|
|
25
|
+
this.repoRoot = repoRoot;
|
|
26
|
+
this.worktreeBranch = worktreeBranch;
|
|
27
|
+
this.lastCommit = lastCommit;
|
|
28
|
+
this.fileCount = fileCount;
|
|
29
|
+
this.isDefault = isDefault;
|
|
18
30
|
}
|
|
19
31
|
static fromJSON(payload) {
|
|
20
32
|
const id = payload.id ? String(payload.id) : '';
|
|
21
33
|
if (!id) {
|
|
22
34
|
throw new Error('Project payload missing id');
|
|
23
35
|
}
|
|
24
|
-
return new ProjectSummary(id, payload.name ?? undefined, payload.
|
|
36
|
+
return new ProjectSummary(id, payload.name ?? undefined, payload.daemonHost ?? payload.daemon_host ?? null, payload.workspacePath ?? payload.workspace_path ?? null, payload.repoRoot ?? payload.repo_root ?? null, payload.worktreeBranch ?? payload.worktree_branch ?? null, payload.lastCommit ?? payload.last_commit ?? null, payload.fileCount ?? payload.file_count ?? null, payload.isDefault ?? payload.is_default ?? undefined);
|
|
25
37
|
}
|
|
26
38
|
asObject() {
|
|
27
39
|
return {
|
|
28
40
|
id: this.id,
|
|
29
41
|
name: this.name,
|
|
30
|
-
|
|
42
|
+
daemonHost: this.daemonHost,
|
|
43
|
+
workspacePath: this.workspacePath,
|
|
44
|
+
repoRoot: this.repoRoot,
|
|
45
|
+
worktreeBranch: this.worktreeBranch,
|
|
46
|
+
lastCommit: this.lastCommit,
|
|
47
|
+
fileCount: this.fileCount,
|
|
48
|
+
isDefault: this.isDefault,
|
|
31
49
|
};
|
|
32
50
|
}
|
|
33
51
|
}
|
|
@@ -270,8 +288,14 @@ export class BackendApiClient {
|
|
|
270
288
|
return {
|
|
271
289
|
id: payload.id,
|
|
272
290
|
name: payload.name,
|
|
273
|
-
description: payload.description,
|
|
274
291
|
metadata: payload.metadata ?? undefined,
|
|
292
|
+
daemonHost: payload.daemonHost ?? payload.daemon_host ?? undefined,
|
|
293
|
+
workspacePath: payload.workspacePath ?? payload.workspace_path ?? undefined,
|
|
294
|
+
repoRoot: payload.repoRoot ?? payload.repo_root ?? undefined,
|
|
295
|
+
worktreeBranch: payload.worktreeBranch ?? payload.worktree_branch ?? undefined,
|
|
296
|
+
lastCommit: payload.lastCommit ?? payload.last_commit ?? undefined,
|
|
297
|
+
fileCount: payload.fileCount ?? payload.file_count ?? undefined,
|
|
298
|
+
isDefault: payload.isDefault ?? payload.is_default ?? undefined,
|
|
275
299
|
};
|
|
276
300
|
}
|
|
277
301
|
async updateProject(projectId, params) {
|
package/dist/client.d.ts
CHANGED
|
@@ -104,7 +104,8 @@ export declare class ConductorClient {
|
|
|
104
104
|
receiveMessages(taskId: string, limit?: number): Promise<Record<string, any>>;
|
|
105
105
|
ackMessages(taskId: string, ackToken?: string | null): Promise<Record<string, any> | undefined>;
|
|
106
106
|
listProjects(): Promise<Record<string, any>>;
|
|
107
|
-
createProject(name: string,
|
|
107
|
+
createProject(name: string, metadata?: Record<string, unknown>): Promise<Record<string, any>>;
|
|
108
|
+
createProject(payload: Record<string, any>): Promise<Record<string, any>>;
|
|
108
109
|
listTasks(payload?: Record<string, any>): Promise<Record<string, any>>;
|
|
109
110
|
getLocalProjectRecord(payload?: Record<string, any>): Promise<Record<string, any>>;
|
|
110
111
|
getLocalTaskRecord(payload?: Record<string, any>): Promise<Record<string, any>>;
|
package/dist/client.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
2
4
|
import { BackendApiClient, BackendApiError } from './backend/index.js';
|
|
3
5
|
import { loadConfig } from './config/index.js';
|
|
6
|
+
import { ProjectContext } from './context/index.js';
|
|
4
7
|
import { getPlanLimitMessageFromError } from './limits/index.js';
|
|
5
8
|
import { MessageRouter } from './message/index.js';
|
|
6
9
|
import { DownstreamCursorStore, DurableUpstreamOutboxStore, normalizeDownstreamCommandCursor, } from './outbox/index.js';
|
|
@@ -338,12 +341,14 @@ export class ConductorClient {
|
|
|
338
341
|
: {
|
|
339
342
|
id: project.id,
|
|
340
343
|
name: project.name ?? null,
|
|
341
|
-
description: project.description ?? null,
|
|
342
344
|
}),
|
|
343
345
|
};
|
|
344
346
|
}
|
|
345
|
-
async createProject(
|
|
346
|
-
const
|
|
347
|
+
async createProject(nameOrPayload, metadata) {
|
|
348
|
+
const payload = typeof nameOrPayload === 'string'
|
|
349
|
+
? { name: nameOrPayload, metadata }
|
|
350
|
+
: { ...nameOrPayload };
|
|
351
|
+
const project = await this.backendApi.createProject(payload);
|
|
347
352
|
return typeof project.asObject === 'function' ? project.asObject() : project;
|
|
348
353
|
}
|
|
349
354
|
async listTasks(payload = {}) {
|
|
@@ -456,12 +461,20 @@ export class ConductorClient {
|
|
|
456
461
|
};
|
|
457
462
|
}
|
|
458
463
|
async matchProjectByPath(payload = {}) {
|
|
459
|
-
const
|
|
460
|
-
|
|
464
|
+
const daemonHost = (typeof payload.daemon_host === 'string' && payload.daemon_host.trim()) ||
|
|
465
|
+
(typeof payload.daemonHost === 'string' && payload.daemonHost.trim()) ||
|
|
466
|
+
(typeof payload.hostname === 'string' && payload.hostname.trim()) ||
|
|
467
|
+
this.agentHost;
|
|
468
|
+
const projectPath = resolveWorkspacePath(typeof payload.project_path === 'string' && payload.project_path
|
|
461
469
|
? payload.project_path
|
|
462
|
-
:
|
|
470
|
+
: typeof payload.projectPath === 'string' && payload.projectPath
|
|
471
|
+
? payload.projectPath
|
|
472
|
+
: this.projectPath);
|
|
473
|
+
if (!projectPath) {
|
|
474
|
+
throw new Error('project_path is required');
|
|
475
|
+
}
|
|
463
476
|
const result = await this.backendApi.matchProjectByPath({
|
|
464
|
-
|
|
477
|
+
daemon_host: daemonHost,
|
|
465
478
|
path: projectPath,
|
|
466
479
|
});
|
|
467
480
|
if (result.project) {
|
|
@@ -481,20 +494,36 @@ export class ConductorClient {
|
|
|
481
494
|
if (!projectId) {
|
|
482
495
|
throw new Error('project_id is required');
|
|
483
496
|
}
|
|
484
|
-
const
|
|
485
|
-
|
|
497
|
+
const daemonHost = (typeof payload.daemon_host === 'string' && payload.daemon_host.trim()) ||
|
|
498
|
+
(typeof payload.daemonHost === 'string' && payload.daemonHost.trim()) ||
|
|
499
|
+
(typeof payload.hostname === 'string' && payload.hostname.trim()) ||
|
|
500
|
+
this.agentHost;
|
|
501
|
+
const projectPath = resolveWorkspacePath(typeof payload.project_path === 'string' && payload.project_path
|
|
486
502
|
? payload.project_path
|
|
487
|
-
:
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
503
|
+
: typeof payload.projectPath === 'string' && payload.projectPath
|
|
504
|
+
? payload.projectPath
|
|
505
|
+
: this.projectPath);
|
|
506
|
+
const snapshot = resolveWorkspaceSnapshot(projectPath);
|
|
507
|
+
const boundProject = await this.backendApi.updateProject(projectId, {
|
|
508
|
+
bindingConfirmed: true,
|
|
509
|
+
daemonHost,
|
|
510
|
+
workspacePath: snapshot.projectRoot,
|
|
511
|
+
repoRoot: snapshot.repoRoot,
|
|
512
|
+
worktreeBranch: snapshot.worktreeBranch,
|
|
513
|
+
lastCommit: snapshot.lastCommit,
|
|
514
|
+
fileCount: snapshot.fileCount,
|
|
515
|
+
});
|
|
494
516
|
return {
|
|
495
517
|
success: true,
|
|
496
|
-
|
|
497
|
-
|
|
518
|
+
project_id: boundProject.id,
|
|
519
|
+
project_name: boundProject.name ?? null,
|
|
520
|
+
hostname: daemonHost,
|
|
521
|
+
daemon_host: daemonHost,
|
|
522
|
+
path: snapshot.projectRoot,
|
|
523
|
+
repo_root: snapshot.repoRoot ?? null,
|
|
524
|
+
worktree_branch: snapshot.worktreeBranch ?? null,
|
|
525
|
+
last_commit: snapshot.lastCommit ?? null,
|
|
526
|
+
file_count: snapshot.fileCount ?? null,
|
|
498
527
|
};
|
|
499
528
|
}
|
|
500
529
|
handleBackendEvent = async (payload) => {
|
|
@@ -906,3 +935,26 @@ function normalizeDeliveryScopeId(scopeId) {
|
|
|
906
935
|
const normalized = String(scopeId || '').trim();
|
|
907
936
|
return normalized || 'default';
|
|
908
937
|
}
|
|
938
|
+
function resolveWorkspacePath(candidate) {
|
|
939
|
+
const trimmed = typeof candidate === 'string' ? candidate.trim() : '';
|
|
940
|
+
if (!trimmed) {
|
|
941
|
+
return '';
|
|
942
|
+
}
|
|
943
|
+
try {
|
|
944
|
+
return fs.realpathSync(trimmed);
|
|
945
|
+
}
|
|
946
|
+
catch {
|
|
947
|
+
return path.resolve(trimmed);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
function resolveWorkspaceSnapshot(projectPath) {
|
|
951
|
+
try {
|
|
952
|
+
const context = new ProjectContext(projectPath);
|
|
953
|
+
return context.snapshot();
|
|
954
|
+
}
|
|
955
|
+
catch {
|
|
956
|
+
return {
|
|
957
|
+
projectRoot: resolveWorkspacePath(projectPath),
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
}
|
|
@@ -2,13 +2,24 @@ export interface GuessResult {
|
|
|
2
2
|
projectRoot: string;
|
|
3
3
|
repoRoot?: string;
|
|
4
4
|
}
|
|
5
|
+
export interface WorkspaceSnapshot {
|
|
6
|
+
projectRoot: string;
|
|
7
|
+
repoRoot?: string;
|
|
8
|
+
worktreeBranch?: string;
|
|
9
|
+
lastCommit?: string;
|
|
10
|
+
fileCount?: number;
|
|
11
|
+
}
|
|
5
12
|
export declare class ProjectContext {
|
|
6
13
|
private readonly root;
|
|
7
14
|
constructor(targetPath?: string);
|
|
8
15
|
guess(): GuessResult;
|
|
16
|
+
snapshot(): WorkspaceSnapshot;
|
|
9
17
|
listFiles(relativeToRepo?: boolean): string[];
|
|
10
18
|
readFile(relativePath: string): string;
|
|
11
19
|
getDiff(staged?: boolean): string;
|
|
12
20
|
private gitRoot;
|
|
21
|
+
private gitBranch;
|
|
22
|
+
private gitHead;
|
|
23
|
+
private gitFileCount;
|
|
13
24
|
private gitListFiles;
|
|
14
25
|
}
|
|
@@ -14,6 +14,21 @@ export class ProjectContext {
|
|
|
14
14
|
repoRoot: repoRoot ?? undefined,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
+
snapshot() {
|
|
18
|
+
const guess = this.guess();
|
|
19
|
+
if (!guess.repoRoot) {
|
|
20
|
+
return {
|
|
21
|
+
projectRoot: guess.projectRoot,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
projectRoot: guess.projectRoot,
|
|
26
|
+
repoRoot: guess.repoRoot,
|
|
27
|
+
worktreeBranch: this.gitBranch(guess.repoRoot) ?? undefined,
|
|
28
|
+
lastCommit: this.gitHead(guess.repoRoot) ?? undefined,
|
|
29
|
+
fileCount: this.gitFileCount(guess.repoRoot) ?? undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
17
32
|
listFiles(relativeToRepo = true) {
|
|
18
33
|
const guess = this.guess();
|
|
19
34
|
if (guess.repoRoot) {
|
|
@@ -55,6 +70,35 @@ export class ProjectContext {
|
|
|
55
70
|
return null;
|
|
56
71
|
}
|
|
57
72
|
}
|
|
73
|
+
gitBranch(repoRoot) {
|
|
74
|
+
try {
|
|
75
|
+
const branch = runGit(['rev-parse', '--abbrev-ref', 'HEAD'], repoRoot).trim();
|
|
76
|
+
if (!branch || branch === 'HEAD') {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return branch;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
gitHead(repoRoot) {
|
|
86
|
+
try {
|
|
87
|
+
const head = runGit(['rev-parse', 'HEAD'], repoRoot).trim();
|
|
88
|
+
return head || null;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
gitFileCount(repoRoot) {
|
|
95
|
+
try {
|
|
96
|
+
return this.gitListFiles(repoRoot).length;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
58
102
|
gitListFiles(repoRoot) {
|
|
59
103
|
try {
|
|
60
104
|
const output = runGit(['ls-files'], repoRoot);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@love-moon/conductor-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.33",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"typescript": "^5.6.3",
|
|
28
28
|
"vitest": "^2.1.4"
|
|
29
29
|
},
|
|
30
|
-
"gitCommitId": "
|
|
30
|
+
"gitCommitId": "db7f9bf"
|
|
31
31
|
}
|