@serviceme/devtools-core 0.1.6 → 0.1.7
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.d.mts +53 -43
- package/dist/index.d.ts +53 -43
- package/dist/index.js +140 -33
- package/dist/index.mjs +132 -25
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,36 @@ import * as _serviceme_devtools_protocol from '@serviceme/devtools-protocol';
|
|
|
2
2
|
import { AgentMarketplaceEntry, AgentMutationRequest, AgentPermissionSummary, CopilotDoctorResult, CopilotPromptOptions, CopilotPromptResult, EnvironmentCheckResult, KnownEnvironmentTool, ToolCheckResult, ServiceMeImageValidationResult, ServiceMeImageInfo, ServiceMeImageCompressOptions, ServiceMeImageCompressResult, JsonSortOptions, JsonValidationResult, AgentToolRiskLevel, AgentToolPermission, ServiceMeProjectExtractTemplateInput, ServiceMeProjectExtractTemplateResult, ServiceMeProjectInstallDepsResult, ServiceMeProjectMakeScriptsExecutableResult, ServiceMeProjectGitInitResult, ServiceMeProjectScaffoldPruneResult, TaskExecutionStatus, ScheduledTaskType, TaskPayload, ScheduledTasksConfig, ScheduledTask, TaskStartedEventParams, TaskOutputEventParams, TaskCompletedEventParams, TaskFailedEventParams, TaskCancelledEventParams, TaskExecutionSnapshot, RunningTaskInfo, TaskExecutionLog, SkillMarketplaceEntry, SkillMutationRequest } from '@serviceme/devtools-protocol';
|
|
3
3
|
import * as fs from 'node:fs/promises';
|
|
4
4
|
|
|
5
|
+
type AgentInstallScope = "workspace" | "user";
|
|
6
|
+
interface InstalledAgent {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
scope: AgentInstallScope;
|
|
10
|
+
installedAt: string;
|
|
11
|
+
}
|
|
12
|
+
interface AgentsStateFile {
|
|
13
|
+
schemaVersion: number;
|
|
14
|
+
installedAgents: InstalledAgent[];
|
|
15
|
+
}
|
|
16
|
+
interface AgentDownloadFile {
|
|
17
|
+
path: string;
|
|
18
|
+
content: string;
|
|
19
|
+
executable?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface AgentStoreFileSystem {
|
|
22
|
+
readdir: typeof fs.readdir;
|
|
23
|
+
readFile: typeof fs.readFile;
|
|
24
|
+
writeFile: typeof fs.writeFile;
|
|
25
|
+
mkdir: typeof fs.mkdir;
|
|
26
|
+
chmod: typeof fs.chmod;
|
|
27
|
+
}
|
|
28
|
+
interface AgentStoreOptions {
|
|
29
|
+
workspacePath: string;
|
|
30
|
+
userAgentsRoot: string;
|
|
31
|
+
fileSystem?: AgentStoreFileSystem;
|
|
32
|
+
schemaVersion?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
5
35
|
interface AgentCatalog {
|
|
6
36
|
agents: AgentMarketplaceEntry[];
|
|
7
37
|
fetchedAt: string;
|
|
@@ -15,6 +45,7 @@ declare class AgentCatalogClient {
|
|
|
15
45
|
private readonly baseUrl?;
|
|
16
46
|
constructor(options?: AgentCatalogClientOptions);
|
|
17
47
|
getCatalog(): Promise<AgentCatalog>;
|
|
48
|
+
downloadAgent(remoteId: string): Promise<AgentDownloadFile[]>;
|
|
18
49
|
}
|
|
19
50
|
|
|
20
51
|
interface AgentStoreLike {
|
|
@@ -47,36 +78,6 @@ declare class AgentReconciler {
|
|
|
47
78
|
private hasHighRiskTool;
|
|
48
79
|
}
|
|
49
80
|
|
|
50
|
-
type AgentInstallScope = "workspace" | "user";
|
|
51
|
-
interface InstalledAgent {
|
|
52
|
-
id: string;
|
|
53
|
-
name: string;
|
|
54
|
-
scope: AgentInstallScope;
|
|
55
|
-
installedAt: string;
|
|
56
|
-
}
|
|
57
|
-
interface AgentsStateFile {
|
|
58
|
-
schemaVersion: number;
|
|
59
|
-
installedAgents: InstalledAgent[];
|
|
60
|
-
}
|
|
61
|
-
interface AgentDownloadFile {
|
|
62
|
-
path: string;
|
|
63
|
-
content: string;
|
|
64
|
-
executable?: boolean;
|
|
65
|
-
}
|
|
66
|
-
interface AgentStoreFileSystem {
|
|
67
|
-
readdir: typeof fs.readdir;
|
|
68
|
-
readFile: typeof fs.readFile;
|
|
69
|
-
writeFile: typeof fs.writeFile;
|
|
70
|
-
mkdir: typeof fs.mkdir;
|
|
71
|
-
chmod: typeof fs.chmod;
|
|
72
|
-
}
|
|
73
|
-
interface AgentStoreOptions {
|
|
74
|
-
workspacePath: string;
|
|
75
|
-
userAgentsRoot: string;
|
|
76
|
-
fileSystem?: AgentStoreFileSystem;
|
|
77
|
-
schemaVersion?: number;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
81
|
declare class AgentStore {
|
|
81
82
|
private readonly workspacePath;
|
|
82
83
|
private readonly userAgentsRoot;
|
|
@@ -166,6 +167,7 @@ declare class ProjectTools {
|
|
|
166
167
|
makeScriptsExecutable(workspacePath: string): Promise<ServiceMeProjectMakeScriptsExecutableResult>;
|
|
167
168
|
initializeGit(workspacePath: string): Promise<ServiceMeProjectGitInitResult>;
|
|
168
169
|
runScaffoldPrune(workspacePath: string, preset?: string): Promise<ServiceMeProjectScaffoldPruneResult>;
|
|
170
|
+
private ensurePresetManifest;
|
|
169
171
|
private findScripts;
|
|
170
172
|
private pathExists;
|
|
171
173
|
private selectExtractedDirectory;
|
|
@@ -340,6 +342,24 @@ declare class TaskLogManager {
|
|
|
340
342
|
clearLogs(taskId?: string): number;
|
|
341
343
|
}
|
|
342
344
|
|
|
345
|
+
interface SkillDownloadFile {
|
|
346
|
+
path: string;
|
|
347
|
+
content: string;
|
|
348
|
+
executable: boolean;
|
|
349
|
+
}
|
|
350
|
+
interface SkillStoreFileSystem {
|
|
351
|
+
readdir: typeof fs.readdir;
|
|
352
|
+
readFile: typeof fs.readFile;
|
|
353
|
+
writeFile: typeof fs.writeFile;
|
|
354
|
+
mkdir: typeof fs.mkdir;
|
|
355
|
+
chmod: typeof fs.chmod;
|
|
356
|
+
}
|
|
357
|
+
interface SkillStoreOptions {
|
|
358
|
+
workspacePath: string;
|
|
359
|
+
userSkillsRoot: string;
|
|
360
|
+
fileSystem?: SkillStoreFileSystem;
|
|
361
|
+
}
|
|
362
|
+
|
|
343
363
|
interface SkillCatalog {
|
|
344
364
|
skills: SkillMarketplaceEntry[];
|
|
345
365
|
fetchedAt: string;
|
|
@@ -353,6 +373,7 @@ declare class SkillCatalogClient {
|
|
|
353
373
|
private readonly baseUrl?;
|
|
354
374
|
constructor(options?: SkillCatalogClientOptions);
|
|
355
375
|
getCatalog(): Promise<SkillCatalog>;
|
|
376
|
+
downloadSkill(remoteId: string): Promise<SkillDownloadFile[]>;
|
|
356
377
|
}
|
|
357
378
|
|
|
358
379
|
interface CatalogSkillLike {
|
|
@@ -389,18 +410,6 @@ declare class SkillReconciler {
|
|
|
389
410
|
mutate(request: SkillMutationRequest): Promise<SkillMutateResult>;
|
|
390
411
|
}
|
|
391
412
|
|
|
392
|
-
interface SkillStoreFileSystem {
|
|
393
|
-
readdir: typeof fs.readdir;
|
|
394
|
-
readFile: typeof fs.readFile;
|
|
395
|
-
writeFile: typeof fs.writeFile;
|
|
396
|
-
mkdir: typeof fs.mkdir;
|
|
397
|
-
}
|
|
398
|
-
interface SkillStoreOptions {
|
|
399
|
-
workspacePath: string;
|
|
400
|
-
userSkillsRoot: string;
|
|
401
|
-
fileSystem?: SkillStoreFileSystem;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
413
|
declare class SkillStore {
|
|
405
414
|
private readonly workspacePath;
|
|
406
415
|
private readonly userSkillsRoot;
|
|
@@ -414,9 +423,10 @@ declare class SkillStore {
|
|
|
414
423
|
listUserSkillIds(): Promise<string[]>;
|
|
415
424
|
writeManagedUserSkillMarker(skillId: string): Promise<void>;
|
|
416
425
|
isManagedUserSkill(skillId: string): Promise<boolean>;
|
|
426
|
+
writeSkillFiles(skillId: string, scope: "workspace" | "user", files: SkillDownloadFile[]): Promise<void>;
|
|
417
427
|
}
|
|
418
428
|
|
|
419
429
|
declare const unzipFile: (zipPath: string, dest: string) => Promise<void>;
|
|
420
430
|
declare const moveFiles: (sourceDir: string, destDir: string, overwrite?: boolean) => Promise<void>;
|
|
421
431
|
|
|
422
|
-
export { type AgentCatalog, AgentCatalogClient, type AgentCatalogClientOptions, type AgentDownloadFile, type AgentInstallScope, type AgentMutateResult, AgentReconciler, type AgentReconcilerDependencies, AgentStore, type AgentStoreFileSystem, type AgentStoreOptions, type AgentsStateFile, type AppendLogInput, type CreateTaskInput, DaemonLogger, type EditTaskInput, EnvironmentInspector, type ExecutorResult, GithubCopilotCliExecutor, HttpRequestExecutor, ImageTools, type InstalledAgent, type JsonTools, type OutputEventCallback, PidManager, ProjectTools, SchedulerDaemon, type ServiceMeLogger, ShellExecutor, type SkillCatalog, SkillCatalogClient, type SkillCatalogClientOptions, type SkillMutateResult, SkillReconciler, type SkillReconcilerDependencies, SkillStore, type SkillStoreFileSystem, type SkillStoreOptions, type StreamingExecutorHandle, type StreamingTaskExecutor, TOOL_RISK_MAP, TaskConfigManager, type TaskEventListener, TaskExecutionEngine, type TaskExecutor, TaskLogManager, copilotDoctor, copilotPrompt, createConsoleLogger, createCopilotAuthRequiredError, createCopilotNotInstalledError, createImageTools, createJsonTools, createProjectTools, getExecutor, isCopilotAuthenticated, isStreamingTaskExecutor, matchesCron, moveFiles, noopLogger, parseAgentToolPermissions, parseIntervalMs, resolveTaskExecutionPayload, unzipFile, validateTaskPayload };
|
|
432
|
+
export { type AgentCatalog, AgentCatalogClient, type AgentCatalogClientOptions, type AgentDownloadFile, type AgentInstallScope, type AgentMutateResult, AgentReconciler, type AgentReconcilerDependencies, AgentStore, type AgentStoreFileSystem, type AgentStoreOptions, type AgentsStateFile, type AppendLogInput, type CreateTaskInput, DaemonLogger, type EditTaskInput, EnvironmentInspector, type ExecutorResult, GithubCopilotCliExecutor, HttpRequestExecutor, ImageTools, type InstalledAgent, type JsonTools, type OutputEventCallback, PidManager, ProjectTools, SchedulerDaemon, type ServiceMeLogger, ShellExecutor, type SkillCatalog, SkillCatalogClient, type SkillCatalogClientOptions, type SkillDownloadFile, type SkillMutateResult, SkillReconciler, type SkillReconcilerDependencies, SkillStore, type SkillStoreFileSystem, type SkillStoreOptions, type StreamingExecutorHandle, type StreamingTaskExecutor, TOOL_RISK_MAP, TaskConfigManager, type TaskEventListener, TaskExecutionEngine, type TaskExecutor, TaskLogManager, copilotDoctor, copilotPrompt, createConsoleLogger, createCopilotAuthRequiredError, createCopilotNotInstalledError, createImageTools, createJsonTools, createProjectTools, getExecutor, isCopilotAuthenticated, isStreamingTaskExecutor, matchesCron, moveFiles, noopLogger, parseAgentToolPermissions, parseIntervalMs, resolveTaskExecutionPayload, unzipFile, validateTaskPayload };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,36 @@ import * as _serviceme_devtools_protocol from '@serviceme/devtools-protocol';
|
|
|
2
2
|
import { AgentMarketplaceEntry, AgentMutationRequest, AgentPermissionSummary, CopilotDoctorResult, CopilotPromptOptions, CopilotPromptResult, EnvironmentCheckResult, KnownEnvironmentTool, ToolCheckResult, ServiceMeImageValidationResult, ServiceMeImageInfo, ServiceMeImageCompressOptions, ServiceMeImageCompressResult, JsonSortOptions, JsonValidationResult, AgentToolRiskLevel, AgentToolPermission, ServiceMeProjectExtractTemplateInput, ServiceMeProjectExtractTemplateResult, ServiceMeProjectInstallDepsResult, ServiceMeProjectMakeScriptsExecutableResult, ServiceMeProjectGitInitResult, ServiceMeProjectScaffoldPruneResult, TaskExecutionStatus, ScheduledTaskType, TaskPayload, ScheduledTasksConfig, ScheduledTask, TaskStartedEventParams, TaskOutputEventParams, TaskCompletedEventParams, TaskFailedEventParams, TaskCancelledEventParams, TaskExecutionSnapshot, RunningTaskInfo, TaskExecutionLog, SkillMarketplaceEntry, SkillMutationRequest } from '@serviceme/devtools-protocol';
|
|
3
3
|
import * as fs from 'node:fs/promises';
|
|
4
4
|
|
|
5
|
+
type AgentInstallScope = "workspace" | "user";
|
|
6
|
+
interface InstalledAgent {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
scope: AgentInstallScope;
|
|
10
|
+
installedAt: string;
|
|
11
|
+
}
|
|
12
|
+
interface AgentsStateFile {
|
|
13
|
+
schemaVersion: number;
|
|
14
|
+
installedAgents: InstalledAgent[];
|
|
15
|
+
}
|
|
16
|
+
interface AgentDownloadFile {
|
|
17
|
+
path: string;
|
|
18
|
+
content: string;
|
|
19
|
+
executable?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface AgentStoreFileSystem {
|
|
22
|
+
readdir: typeof fs.readdir;
|
|
23
|
+
readFile: typeof fs.readFile;
|
|
24
|
+
writeFile: typeof fs.writeFile;
|
|
25
|
+
mkdir: typeof fs.mkdir;
|
|
26
|
+
chmod: typeof fs.chmod;
|
|
27
|
+
}
|
|
28
|
+
interface AgentStoreOptions {
|
|
29
|
+
workspacePath: string;
|
|
30
|
+
userAgentsRoot: string;
|
|
31
|
+
fileSystem?: AgentStoreFileSystem;
|
|
32
|
+
schemaVersion?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
5
35
|
interface AgentCatalog {
|
|
6
36
|
agents: AgentMarketplaceEntry[];
|
|
7
37
|
fetchedAt: string;
|
|
@@ -15,6 +45,7 @@ declare class AgentCatalogClient {
|
|
|
15
45
|
private readonly baseUrl?;
|
|
16
46
|
constructor(options?: AgentCatalogClientOptions);
|
|
17
47
|
getCatalog(): Promise<AgentCatalog>;
|
|
48
|
+
downloadAgent(remoteId: string): Promise<AgentDownloadFile[]>;
|
|
18
49
|
}
|
|
19
50
|
|
|
20
51
|
interface AgentStoreLike {
|
|
@@ -47,36 +78,6 @@ declare class AgentReconciler {
|
|
|
47
78
|
private hasHighRiskTool;
|
|
48
79
|
}
|
|
49
80
|
|
|
50
|
-
type AgentInstallScope = "workspace" | "user";
|
|
51
|
-
interface InstalledAgent {
|
|
52
|
-
id: string;
|
|
53
|
-
name: string;
|
|
54
|
-
scope: AgentInstallScope;
|
|
55
|
-
installedAt: string;
|
|
56
|
-
}
|
|
57
|
-
interface AgentsStateFile {
|
|
58
|
-
schemaVersion: number;
|
|
59
|
-
installedAgents: InstalledAgent[];
|
|
60
|
-
}
|
|
61
|
-
interface AgentDownloadFile {
|
|
62
|
-
path: string;
|
|
63
|
-
content: string;
|
|
64
|
-
executable?: boolean;
|
|
65
|
-
}
|
|
66
|
-
interface AgentStoreFileSystem {
|
|
67
|
-
readdir: typeof fs.readdir;
|
|
68
|
-
readFile: typeof fs.readFile;
|
|
69
|
-
writeFile: typeof fs.writeFile;
|
|
70
|
-
mkdir: typeof fs.mkdir;
|
|
71
|
-
chmod: typeof fs.chmod;
|
|
72
|
-
}
|
|
73
|
-
interface AgentStoreOptions {
|
|
74
|
-
workspacePath: string;
|
|
75
|
-
userAgentsRoot: string;
|
|
76
|
-
fileSystem?: AgentStoreFileSystem;
|
|
77
|
-
schemaVersion?: number;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
81
|
declare class AgentStore {
|
|
81
82
|
private readonly workspacePath;
|
|
82
83
|
private readonly userAgentsRoot;
|
|
@@ -166,6 +167,7 @@ declare class ProjectTools {
|
|
|
166
167
|
makeScriptsExecutable(workspacePath: string): Promise<ServiceMeProjectMakeScriptsExecutableResult>;
|
|
167
168
|
initializeGit(workspacePath: string): Promise<ServiceMeProjectGitInitResult>;
|
|
168
169
|
runScaffoldPrune(workspacePath: string, preset?: string): Promise<ServiceMeProjectScaffoldPruneResult>;
|
|
170
|
+
private ensurePresetManifest;
|
|
169
171
|
private findScripts;
|
|
170
172
|
private pathExists;
|
|
171
173
|
private selectExtractedDirectory;
|
|
@@ -340,6 +342,24 @@ declare class TaskLogManager {
|
|
|
340
342
|
clearLogs(taskId?: string): number;
|
|
341
343
|
}
|
|
342
344
|
|
|
345
|
+
interface SkillDownloadFile {
|
|
346
|
+
path: string;
|
|
347
|
+
content: string;
|
|
348
|
+
executable: boolean;
|
|
349
|
+
}
|
|
350
|
+
interface SkillStoreFileSystem {
|
|
351
|
+
readdir: typeof fs.readdir;
|
|
352
|
+
readFile: typeof fs.readFile;
|
|
353
|
+
writeFile: typeof fs.writeFile;
|
|
354
|
+
mkdir: typeof fs.mkdir;
|
|
355
|
+
chmod: typeof fs.chmod;
|
|
356
|
+
}
|
|
357
|
+
interface SkillStoreOptions {
|
|
358
|
+
workspacePath: string;
|
|
359
|
+
userSkillsRoot: string;
|
|
360
|
+
fileSystem?: SkillStoreFileSystem;
|
|
361
|
+
}
|
|
362
|
+
|
|
343
363
|
interface SkillCatalog {
|
|
344
364
|
skills: SkillMarketplaceEntry[];
|
|
345
365
|
fetchedAt: string;
|
|
@@ -353,6 +373,7 @@ declare class SkillCatalogClient {
|
|
|
353
373
|
private readonly baseUrl?;
|
|
354
374
|
constructor(options?: SkillCatalogClientOptions);
|
|
355
375
|
getCatalog(): Promise<SkillCatalog>;
|
|
376
|
+
downloadSkill(remoteId: string): Promise<SkillDownloadFile[]>;
|
|
356
377
|
}
|
|
357
378
|
|
|
358
379
|
interface CatalogSkillLike {
|
|
@@ -389,18 +410,6 @@ declare class SkillReconciler {
|
|
|
389
410
|
mutate(request: SkillMutationRequest): Promise<SkillMutateResult>;
|
|
390
411
|
}
|
|
391
412
|
|
|
392
|
-
interface SkillStoreFileSystem {
|
|
393
|
-
readdir: typeof fs.readdir;
|
|
394
|
-
readFile: typeof fs.readFile;
|
|
395
|
-
writeFile: typeof fs.writeFile;
|
|
396
|
-
mkdir: typeof fs.mkdir;
|
|
397
|
-
}
|
|
398
|
-
interface SkillStoreOptions {
|
|
399
|
-
workspacePath: string;
|
|
400
|
-
userSkillsRoot: string;
|
|
401
|
-
fileSystem?: SkillStoreFileSystem;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
413
|
declare class SkillStore {
|
|
405
414
|
private readonly workspacePath;
|
|
406
415
|
private readonly userSkillsRoot;
|
|
@@ -414,9 +423,10 @@ declare class SkillStore {
|
|
|
414
423
|
listUserSkillIds(): Promise<string[]>;
|
|
415
424
|
writeManagedUserSkillMarker(skillId: string): Promise<void>;
|
|
416
425
|
isManagedUserSkill(skillId: string): Promise<boolean>;
|
|
426
|
+
writeSkillFiles(skillId: string, scope: "workspace" | "user", files: SkillDownloadFile[]): Promise<void>;
|
|
417
427
|
}
|
|
418
428
|
|
|
419
429
|
declare const unzipFile: (zipPath: string, dest: string) => Promise<void>;
|
|
420
430
|
declare const moveFiles: (sourceDir: string, destDir: string, overwrite?: boolean) => Promise<void>;
|
|
421
431
|
|
|
422
|
-
export { type AgentCatalog, AgentCatalogClient, type AgentCatalogClientOptions, type AgentDownloadFile, type AgentInstallScope, type AgentMutateResult, AgentReconciler, type AgentReconcilerDependencies, AgentStore, type AgentStoreFileSystem, type AgentStoreOptions, type AgentsStateFile, type AppendLogInput, type CreateTaskInput, DaemonLogger, type EditTaskInput, EnvironmentInspector, type ExecutorResult, GithubCopilotCliExecutor, HttpRequestExecutor, ImageTools, type InstalledAgent, type JsonTools, type OutputEventCallback, PidManager, ProjectTools, SchedulerDaemon, type ServiceMeLogger, ShellExecutor, type SkillCatalog, SkillCatalogClient, type SkillCatalogClientOptions, type SkillMutateResult, SkillReconciler, type SkillReconcilerDependencies, SkillStore, type SkillStoreFileSystem, type SkillStoreOptions, type StreamingExecutorHandle, type StreamingTaskExecutor, TOOL_RISK_MAP, TaskConfigManager, type TaskEventListener, TaskExecutionEngine, type TaskExecutor, TaskLogManager, copilotDoctor, copilotPrompt, createConsoleLogger, createCopilotAuthRequiredError, createCopilotNotInstalledError, createImageTools, createJsonTools, createProjectTools, getExecutor, isCopilotAuthenticated, isStreamingTaskExecutor, matchesCron, moveFiles, noopLogger, parseAgentToolPermissions, parseIntervalMs, resolveTaskExecutionPayload, unzipFile, validateTaskPayload };
|
|
432
|
+
export { type AgentCatalog, AgentCatalogClient, type AgentCatalogClientOptions, type AgentDownloadFile, type AgentInstallScope, type AgentMutateResult, AgentReconciler, type AgentReconcilerDependencies, AgentStore, type AgentStoreFileSystem, type AgentStoreOptions, type AgentsStateFile, type AppendLogInput, type CreateTaskInput, DaemonLogger, type EditTaskInput, EnvironmentInspector, type ExecutorResult, GithubCopilotCliExecutor, HttpRequestExecutor, ImageTools, type InstalledAgent, type JsonTools, type OutputEventCallback, PidManager, ProjectTools, SchedulerDaemon, type ServiceMeLogger, ShellExecutor, type SkillCatalog, SkillCatalogClient, type SkillCatalogClientOptions, type SkillDownloadFile, type SkillMutateResult, SkillReconciler, type SkillReconcilerDependencies, SkillStore, type SkillStoreFileSystem, type SkillStoreOptions, type StreamingExecutorHandle, type StreamingTaskExecutor, TOOL_RISK_MAP, TaskConfigManager, type TaskEventListener, TaskExecutionEngine, type TaskExecutor, TaskLogManager, copilotDoctor, copilotPrompt, createConsoleLogger, createCopilotAuthRequiredError, createCopilotNotInstalledError, createImageTools, createJsonTools, createProjectTools, getExecutor, isCopilotAuthenticated, isStreamingTaskExecutor, matchesCron, moveFiles, noopLogger, parseAgentToolPermissions, parseIntervalMs, resolveTaskExecutionPayload, unzipFile, validateTaskPayload };
|
package/dist/index.js
CHANGED
|
@@ -72,6 +72,7 @@ __export(index_exports, {
|
|
|
72
72
|
module.exports = __toCommonJS(index_exports);
|
|
73
73
|
|
|
74
74
|
// src/agents/AgentCatalogClient.ts
|
|
75
|
+
var import_devtools_protocol = require("@serviceme/devtools-protocol");
|
|
75
76
|
var AgentCatalogClient = class {
|
|
76
77
|
constructor(options = {}) {
|
|
77
78
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -96,6 +97,30 @@ var AgentCatalogClient = class {
|
|
|
96
97
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
97
98
|
};
|
|
98
99
|
}
|
|
100
|
+
async downloadAgent(remoteId) {
|
|
101
|
+
if (!this.baseUrl) {
|
|
102
|
+
throw (0, import_devtools_protocol.createServicemeError)(
|
|
103
|
+
"workspace_not_found",
|
|
104
|
+
"Agent catalog baseUrl is not configured."
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const response = await this.fetchImpl(
|
|
108
|
+
`${this.baseUrl}/api/v1/marketplace/agents/download/${remoteId}`
|
|
109
|
+
);
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
if (response.status === 404) {
|
|
112
|
+
throw (0, import_devtools_protocol.createServicemeError)(
|
|
113
|
+
"not_found",
|
|
114
|
+
`Agent '${remoteId}' not found`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Failed to download agent ${remoteId}: ${response.status}`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
const payload = await response.json();
|
|
122
|
+
return payload.data?.files ?? [];
|
|
123
|
+
}
|
|
99
124
|
};
|
|
100
125
|
|
|
101
126
|
// src/permissions/agent-permissions.ts
|
|
@@ -353,7 +378,7 @@ var AgentStore = class {
|
|
|
353
378
|
};
|
|
354
379
|
|
|
355
380
|
// src/copilot/doctor.ts
|
|
356
|
-
var
|
|
381
|
+
var import_devtools_protocol2 = require("@serviceme/devtools-protocol");
|
|
357
382
|
|
|
358
383
|
// src/process/runCommand.ts
|
|
359
384
|
var import_node_child_process = require("child_process");
|
|
@@ -497,20 +522,20 @@ async function copilotDoctor() {
|
|
|
497
522
|
return { installed: true, version, authenticated };
|
|
498
523
|
}
|
|
499
524
|
function createCopilotNotInstalledError() {
|
|
500
|
-
return (0,
|
|
501
|
-
|
|
525
|
+
return (0, import_devtools_protocol2.createServicemeError)(
|
|
526
|
+
import_devtools_protocol2.COPILOT_ERROR_CODES.NOT_INSTALLED,
|
|
502
527
|
"GitHub Copilot CLI is not installed. Visit https://docs.github.com/en/copilot/using-github-copilot/using-github-copilot-in-the-command-line to install."
|
|
503
528
|
);
|
|
504
529
|
}
|
|
505
530
|
function createCopilotAuthRequiredError() {
|
|
506
|
-
return (0,
|
|
507
|
-
|
|
531
|
+
return (0, import_devtools_protocol2.createServicemeError)(
|
|
532
|
+
import_devtools_protocol2.COPILOT_ERROR_CODES.AUTH_REQUIRED,
|
|
508
533
|
"GitHub Copilot CLI requires authentication. Run `copilot auth login` to sign in."
|
|
509
534
|
);
|
|
510
535
|
}
|
|
511
536
|
|
|
512
537
|
// src/copilot/prompt.ts
|
|
513
|
-
var
|
|
538
|
+
var import_devtools_protocol3 = require("@serviceme/devtools-protocol");
|
|
514
539
|
var COPILOT_COMMAND2 = "copilot";
|
|
515
540
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
516
541
|
function stripAnsi(text) {
|
|
@@ -544,8 +569,8 @@ async function copilotPrompt(options) {
|
|
|
544
569
|
});
|
|
545
570
|
const output = stripAnsi(result.stdout);
|
|
546
571
|
if (output.includes("I'm sorry, but I cannot assist") && result.stderr?.includes("Stream completed without a response")) {
|
|
547
|
-
throw (0,
|
|
548
|
-
|
|
572
|
+
throw (0, import_devtools_protocol3.createServicemeError)(
|
|
573
|
+
import_devtools_protocol3.COPILOT_ERROR_CODES.AUTH_REQUIRED,
|
|
549
574
|
"Copilot CLI returned a refusal response. This typically indicates an expired authentication token. Run `gh auth login` to re-authenticate.",
|
|
550
575
|
{ exitCode: 0, output, stderr: result.stderr }
|
|
551
576
|
);
|
|
@@ -554,8 +579,8 @@ async function copilotPrompt(options) {
|
|
|
554
579
|
} catch (error) {
|
|
555
580
|
const err = error;
|
|
556
581
|
if (err.code === "ETIMEDOUT") {
|
|
557
|
-
throw (0,
|
|
558
|
-
|
|
582
|
+
throw (0, import_devtools_protocol3.createServicemeError)(
|
|
583
|
+
import_devtools_protocol3.COPILOT_ERROR_CODES.TIMEOUT,
|
|
559
584
|
`Copilot prompt timed out after ${String(timeout)}ms.`
|
|
560
585
|
);
|
|
561
586
|
}
|
|
@@ -563,8 +588,8 @@ async function copilotPrompt(options) {
|
|
|
563
588
|
const output = stripAnsi(err.stdout ?? "");
|
|
564
589
|
const stderr = err.stderr ?? err.message ?? "";
|
|
565
590
|
if (output.includes("I'm sorry, but I cannot assist") || stderr.includes("Stream completed without a response")) {
|
|
566
|
-
throw (0,
|
|
567
|
-
|
|
591
|
+
throw (0, import_devtools_protocol3.createServicemeError)(
|
|
592
|
+
import_devtools_protocol3.COPILOT_ERROR_CODES.AUTH_REQUIRED,
|
|
568
593
|
"Copilot CLI returned a refusal response. This typically indicates an expired authentication token. Run `gh auth login` to re-authenticate.",
|
|
569
594
|
{ exitCode, output, stderr }
|
|
570
595
|
);
|
|
@@ -572,8 +597,8 @@ async function copilotPrompt(options) {
|
|
|
572
597
|
if (exitCode !== 0 && output) {
|
|
573
598
|
return { output, exitCode };
|
|
574
599
|
}
|
|
575
|
-
throw (0,
|
|
576
|
-
|
|
600
|
+
throw (0, import_devtools_protocol3.createServicemeError)(
|
|
601
|
+
import_devtools_protocol3.COPILOT_ERROR_CODES.EXECUTION_FAILED,
|
|
577
602
|
stderr || `Copilot exited with code ${String(exitCode)}.`,
|
|
578
603
|
{ exitCode, stderr }
|
|
579
604
|
);
|
|
@@ -581,7 +606,7 @@ async function copilotPrompt(options) {
|
|
|
581
606
|
}
|
|
582
607
|
|
|
583
608
|
// src/env/environmentInspector.ts
|
|
584
|
-
var
|
|
609
|
+
var import_devtools_protocol4 = require("@serviceme/devtools-protocol");
|
|
585
610
|
var DEFAULT_TOOL_CHECK_TIMEOUT_MS = 5e3;
|
|
586
611
|
var TOOL_CHECK_TIMEOUT_MS = {
|
|
587
612
|
nuget: 12e3,
|
|
@@ -599,7 +624,7 @@ var ERROR_CODE_TIMEOUT = "ETIMEDOUT";
|
|
|
599
624
|
var EnvironmentInspector = class {
|
|
600
625
|
async checkEnvironment() {
|
|
601
626
|
const results = await Promise.all(
|
|
602
|
-
|
|
627
|
+
import_devtools_protocol4.KNOWN_ENVIRONMENT_TOOLS.map(
|
|
603
628
|
async (tool) => [tool, await this.checkTool(tool)]
|
|
604
629
|
)
|
|
605
630
|
);
|
|
@@ -607,7 +632,7 @@ var EnvironmentInspector = class {
|
|
|
607
632
|
}
|
|
608
633
|
async checkTool(toolName) {
|
|
609
634
|
if (!/^[a-zA-Z0-9-]+$/.test(toolName)) {
|
|
610
|
-
throw (0,
|
|
635
|
+
throw (0, import_devtools_protocol4.createServicemeError)("invalid_params", "Invalid tool name.");
|
|
611
636
|
}
|
|
612
637
|
try {
|
|
613
638
|
if (toolName === "nvm") {
|
|
@@ -791,7 +816,7 @@ var EnvironmentInspector = class {
|
|
|
791
816
|
const execError = error;
|
|
792
817
|
const message = execError.message || String(error);
|
|
793
818
|
const code = execError.code;
|
|
794
|
-
const isNotFound = message.includes("command not found") || message.includes("not recognized") || message.includes("ENOENT") || code === "ENOENT" || code === ERROR_CODE_NOT_FOUND;
|
|
819
|
+
const isNotFound = message.includes("command not found") || message.includes("not recognized") || message.includes("ENOENT") || message.includes("EACCES") || code === "ENOENT" || code === "EACCES" || code === ERROR_CODE_NOT_FOUND;
|
|
795
820
|
const isTimeout = code === ERROR_CODE_TIMEOUT || message.toLowerCase().includes("timed out");
|
|
796
821
|
return {
|
|
797
822
|
installed: false,
|
|
@@ -803,7 +828,7 @@ var EnvironmentInspector = class {
|
|
|
803
828
|
// src/image/imageTools.ts
|
|
804
829
|
var fs2 = __toESM(require("fs/promises"));
|
|
805
830
|
var path2 = __toESM(require("path"));
|
|
806
|
-
var
|
|
831
|
+
var import_devtools_protocol5 = require("@serviceme/devtools-protocol");
|
|
807
832
|
var SUPPORTED_FORMATS = [
|
|
808
833
|
".jpg",
|
|
809
834
|
".jpeg",
|
|
@@ -847,7 +872,7 @@ var ImageTools = class {
|
|
|
847
872
|
async compress(imagePath, options) {
|
|
848
873
|
const validation = await this.validate(imagePath, options.sharpModulePath);
|
|
849
874
|
if (!validation.valid) {
|
|
850
|
-
throw (0,
|
|
875
|
+
throw (0, import_devtools_protocol5.createServicemeError)(
|
|
851
876
|
"invalid_params",
|
|
852
877
|
`Invalid image file: ${imagePath}`
|
|
853
878
|
);
|
|
@@ -921,7 +946,7 @@ var ImageTools = class {
|
|
|
921
946
|
try {
|
|
922
947
|
return sharpModulePath ? require(sharpModulePath) : require("sharp");
|
|
923
948
|
} catch (error) {
|
|
924
|
-
throw (0,
|
|
949
|
+
throw (0, import_devtools_protocol5.createServicemeError)(
|
|
925
950
|
"internal_error",
|
|
926
951
|
`sharp is required for image operations: ${error instanceof Error ? error.message : String(error)}`
|
|
927
952
|
);
|
|
@@ -933,13 +958,13 @@ function createImageTools() {
|
|
|
933
958
|
}
|
|
934
959
|
|
|
935
960
|
// src/json/jsonTools.ts
|
|
936
|
-
var
|
|
961
|
+
var import_devtools_protocol6 = require("@serviceme/devtools-protocol");
|
|
937
962
|
var import_comment_json = require("comment-json");
|
|
938
963
|
var import_json5 = __toESM(require("json5"));
|
|
939
964
|
function createJsonTools() {
|
|
940
965
|
return {
|
|
941
966
|
sort(text, options) {
|
|
942
|
-
const finalOptions = { ...
|
|
967
|
+
const finalOptions = { ...import_devtools_protocol6.DEFAULT_JSON_SORT_OPTIONS, ...options };
|
|
943
968
|
const json = parseJson(text);
|
|
944
969
|
const sorted = sortObject(json, finalOptions);
|
|
945
970
|
return JSON.stringify(sorted, null, detectIndent(text));
|
|
@@ -975,7 +1000,7 @@ function parseJson(text) {
|
|
|
975
1000
|
} catch {
|
|
976
1001
|
}
|
|
977
1002
|
}
|
|
978
|
-
throw (0,
|
|
1003
|
+
throw (0, import_devtools_protocol6.createServicemeError)("json_invalid_input", "Invalid JSON format.");
|
|
979
1004
|
}
|
|
980
1005
|
function sortObject(obj, options) {
|
|
981
1006
|
if (Array.isArray(obj)) {
|
|
@@ -1069,7 +1094,7 @@ function createConsoleLogger(prefix = "serviceme") {
|
|
|
1069
1094
|
// src/project/projectTools.ts
|
|
1070
1095
|
var fs3 = __toESM(require("fs/promises"));
|
|
1071
1096
|
var path3 = __toESM(require("path"));
|
|
1072
|
-
var
|
|
1097
|
+
var import_devtools_protocol7 = require("@serviceme/devtools-protocol");
|
|
1073
1098
|
|
|
1074
1099
|
// src/utils/fileUtils.ts
|
|
1075
1100
|
var import_node_fs = require("fs");
|
|
@@ -1225,7 +1250,7 @@ var ProjectTools = class {
|
|
|
1225
1250
|
}
|
|
1226
1251
|
async installDependencies(workspacePath, command) {
|
|
1227
1252
|
if (!command) {
|
|
1228
|
-
throw (0,
|
|
1253
|
+
throw (0, import_devtools_protocol7.createServicemeError)("invalid_params", "Expected install command.");
|
|
1229
1254
|
}
|
|
1230
1255
|
await runCommand(command, {
|
|
1231
1256
|
cwd: workspacePath,
|
|
@@ -1288,13 +1313,16 @@ var ProjectTools = class {
|
|
|
1288
1313
|
}
|
|
1289
1314
|
async runScaffoldPrune(workspacePath, preset) {
|
|
1290
1315
|
if (!preset) {
|
|
1291
|
-
throw (0,
|
|
1316
|
+
throw (0, import_devtools_protocol7.createServicemeError)("invalid_params", "Expected scaffold preset.");
|
|
1292
1317
|
}
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
];
|
|
1318
|
+
await this.ensurePresetManifest(workspacePath, preset);
|
|
1319
|
+
const pruneCommand = `pnpm run scaffold:prune -- --preset ${preset} --project-root .`;
|
|
1320
|
+
const initMetadataCommand = `pnpm run scaffold:init-metadata -- --preset ${preset} --project-root . --force`;
|
|
1321
|
+
const commands = [pruneCommand, initMetadataCommand];
|
|
1297
1322
|
for (const command of commands) {
|
|
1323
|
+
if (command === initMetadataCommand) {
|
|
1324
|
+
await this.ensurePresetManifest(workspacePath, preset);
|
|
1325
|
+
}
|
|
1298
1326
|
await runCommand(command, {
|
|
1299
1327
|
cwd: workspacePath,
|
|
1300
1328
|
shell: true
|
|
@@ -1306,6 +1334,44 @@ var ProjectTools = class {
|
|
|
1306
1334
|
commands
|
|
1307
1335
|
};
|
|
1308
1336
|
}
|
|
1337
|
+
async ensurePresetManifest(workspacePath, preset) {
|
|
1338
|
+
const presetManifestPath = path3.join(
|
|
1339
|
+
workspacePath,
|
|
1340
|
+
".ms-scaffold",
|
|
1341
|
+
"presets",
|
|
1342
|
+
`${preset}.json`
|
|
1343
|
+
);
|
|
1344
|
+
if (await this.pathExists(presetManifestPath)) {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
const projectModePath = path3.join(
|
|
1348
|
+
workspacePath,
|
|
1349
|
+
".ms-scaffold",
|
|
1350
|
+
"project-mode.json"
|
|
1351
|
+
);
|
|
1352
|
+
if (!await this.pathExists(projectModePath)) {
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
const projectModeRaw = await fs3.readFile(projectModePath, "utf8");
|
|
1356
|
+
const projectMode = JSON.parse(projectModeRaw);
|
|
1357
|
+
const synthesizedPreset = {
|
|
1358
|
+
preset,
|
|
1359
|
+
selectedModules: Array.isArray(projectMode.selectedModules) ? projectMode.selectedModules : [],
|
|
1360
|
+
prunedModules: Array.isArray(projectMode.prunedModules) ? projectMode.prunedModules : [],
|
|
1361
|
+
exclude: [],
|
|
1362
|
+
recommendedFollowUps: [],
|
|
1363
|
+
managedFiles: [],
|
|
1364
|
+
mergeManagedFiles: [],
|
|
1365
|
+
userOwnedPaths: []
|
|
1366
|
+
};
|
|
1367
|
+
await fs3.mkdir(path3.dirname(presetManifestPath), { recursive: true });
|
|
1368
|
+
await fs3.writeFile(
|
|
1369
|
+
presetManifestPath,
|
|
1370
|
+
`${JSON.stringify(synthesizedPreset, null, 2)}
|
|
1371
|
+
`,
|
|
1372
|
+
"utf8"
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1309
1375
|
async findScripts(dir, extensions) {
|
|
1310
1376
|
const results = [];
|
|
1311
1377
|
let entries;
|
|
@@ -1926,7 +1992,7 @@ function getExecutor(taskType) {
|
|
|
1926
1992
|
var import_node_crypto = require("crypto");
|
|
1927
1993
|
var fs8 = __toESM(require("fs"));
|
|
1928
1994
|
var path7 = __toESM(require("path"));
|
|
1929
|
-
var
|
|
1995
|
+
var import_devtools_protocol8 = require("@serviceme/devtools-protocol");
|
|
1930
1996
|
var CONFIG_DIR3 = ".serviceme";
|
|
1931
1997
|
var CONFIG_FILE = "scheduled-tasks.json";
|
|
1932
1998
|
function emptyConfig() {
|
|
@@ -1937,7 +2003,7 @@ function isRecord(value) {
|
|
|
1937
2003
|
}
|
|
1938
2004
|
function requireNonEmptyString(payload, field, taskType) {
|
|
1939
2005
|
if (!isRecord(payload) || typeof payload[field] !== "string" || !payload[field].trim()) {
|
|
1940
|
-
throw (0,
|
|
2006
|
+
throw (0, import_devtools_protocol8.createServicemeError)(
|
|
1941
2007
|
"invalid_payload",
|
|
1942
2008
|
`${taskType} payload ${field} is required`
|
|
1943
2009
|
);
|
|
@@ -2585,6 +2651,7 @@ function matchCronField(field, value) {
|
|
|
2585
2651
|
}
|
|
2586
2652
|
|
|
2587
2653
|
// src/skills/SkillCatalogClient.ts
|
|
2654
|
+
var import_devtools_protocol9 = require("@serviceme/devtools-protocol");
|
|
2588
2655
|
var SkillCatalogClient = class {
|
|
2589
2656
|
constructor(options = {}) {
|
|
2590
2657
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -2609,6 +2676,30 @@ var SkillCatalogClient = class {
|
|
|
2609
2676
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2610
2677
|
};
|
|
2611
2678
|
}
|
|
2679
|
+
async downloadSkill(remoteId) {
|
|
2680
|
+
if (!this.baseUrl) {
|
|
2681
|
+
throw (0, import_devtools_protocol9.createServicemeError)(
|
|
2682
|
+
"workspace_not_found",
|
|
2683
|
+
"Skill catalog baseUrl is not configured."
|
|
2684
|
+
);
|
|
2685
|
+
}
|
|
2686
|
+
const response = await this.fetchImpl(
|
|
2687
|
+
`${this.baseUrl}/api/v1/marketplace/skills/download/${remoteId}`
|
|
2688
|
+
);
|
|
2689
|
+
if (!response.ok) {
|
|
2690
|
+
if (response.status === 404) {
|
|
2691
|
+
throw (0, import_devtools_protocol9.createServicemeError)(
|
|
2692
|
+
"not_found",
|
|
2693
|
+
`Skill '${remoteId}' not found`
|
|
2694
|
+
);
|
|
2695
|
+
}
|
|
2696
|
+
throw new Error(
|
|
2697
|
+
`Failed to download skill ${remoteId}: ${response.status}`
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
const payload = await response.json();
|
|
2701
|
+
return payload.data?.files ?? [];
|
|
2702
|
+
}
|
|
2612
2703
|
};
|
|
2613
2704
|
|
|
2614
2705
|
// src/skills/SkillReconciler.ts
|
|
@@ -2745,6 +2836,22 @@ var SkillStore = class {
|
|
|
2745
2836
|
return false;
|
|
2746
2837
|
}
|
|
2747
2838
|
}
|
|
2839
|
+
async writeSkillFiles(skillId, scope, files) {
|
|
2840
|
+
const root = scope === "workspace" ? path9.join(this.workspacePath, WORKSPACE_SKILLS_ROOT_RELATIVE) : this.userSkillsRoot;
|
|
2841
|
+
const targetDir = path9.join(root, skillId);
|
|
2842
|
+
await this.fileSystem.mkdir(targetDir, { recursive: true });
|
|
2843
|
+
for (const file of files) {
|
|
2844
|
+
const filePath = path9.join(targetDir, file.path);
|
|
2845
|
+
await this.fileSystem.mkdir(path9.dirname(filePath), { recursive: true });
|
|
2846
|
+
await this.fileSystem.writeFile(filePath, file.content, "utf-8");
|
|
2847
|
+
if (file.executable) {
|
|
2848
|
+
try {
|
|
2849
|
+
await this.fileSystem.chmod(filePath, 493);
|
|
2850
|
+
} catch {
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2748
2855
|
};
|
|
2749
2856
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2750
2857
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -6,6 +6,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/agents/AgentCatalogClient.ts
|
|
9
|
+
import { createServicemeError } from "@serviceme/devtools-protocol";
|
|
9
10
|
var AgentCatalogClient = class {
|
|
10
11
|
constructor(options = {}) {
|
|
11
12
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -30,6 +31,30 @@ var AgentCatalogClient = class {
|
|
|
30
31
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
31
32
|
};
|
|
32
33
|
}
|
|
34
|
+
async downloadAgent(remoteId) {
|
|
35
|
+
if (!this.baseUrl) {
|
|
36
|
+
throw createServicemeError(
|
|
37
|
+
"workspace_not_found",
|
|
38
|
+
"Agent catalog baseUrl is not configured."
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const response = await this.fetchImpl(
|
|
42
|
+
`${this.baseUrl}/api/v1/marketplace/agents/download/${remoteId}`
|
|
43
|
+
);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
if (response.status === 404) {
|
|
46
|
+
throw createServicemeError(
|
|
47
|
+
"not_found",
|
|
48
|
+
`Agent '${remoteId}' not found`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Failed to download agent ${remoteId}: ${response.status}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const payload = await response.json();
|
|
56
|
+
return payload.data?.files ?? [];
|
|
57
|
+
}
|
|
33
58
|
};
|
|
34
59
|
|
|
35
60
|
// src/permissions/agent-permissions.ts
|
|
@@ -289,7 +314,7 @@ var AgentStore = class {
|
|
|
289
314
|
// src/copilot/doctor.ts
|
|
290
315
|
import {
|
|
291
316
|
COPILOT_ERROR_CODES,
|
|
292
|
-
createServicemeError
|
|
317
|
+
createServicemeError as createServicemeError2
|
|
293
318
|
} from "@serviceme/devtools-protocol";
|
|
294
319
|
|
|
295
320
|
// src/process/runCommand.ts
|
|
@@ -434,13 +459,13 @@ async function copilotDoctor() {
|
|
|
434
459
|
return { installed: true, version, authenticated };
|
|
435
460
|
}
|
|
436
461
|
function createCopilotNotInstalledError() {
|
|
437
|
-
return
|
|
462
|
+
return createServicemeError2(
|
|
438
463
|
COPILOT_ERROR_CODES.NOT_INSTALLED,
|
|
439
464
|
"GitHub Copilot CLI is not installed. Visit https://docs.github.com/en/copilot/using-github-copilot/using-github-copilot-in-the-command-line to install."
|
|
440
465
|
);
|
|
441
466
|
}
|
|
442
467
|
function createCopilotAuthRequiredError() {
|
|
443
|
-
return
|
|
468
|
+
return createServicemeError2(
|
|
444
469
|
COPILOT_ERROR_CODES.AUTH_REQUIRED,
|
|
445
470
|
"GitHub Copilot CLI requires authentication. Run `copilot auth login` to sign in."
|
|
446
471
|
);
|
|
@@ -449,7 +474,7 @@ function createCopilotAuthRequiredError() {
|
|
|
449
474
|
// src/copilot/prompt.ts
|
|
450
475
|
import {
|
|
451
476
|
COPILOT_ERROR_CODES as COPILOT_ERROR_CODES2,
|
|
452
|
-
createServicemeError as
|
|
477
|
+
createServicemeError as createServicemeError3
|
|
453
478
|
} from "@serviceme/devtools-protocol";
|
|
454
479
|
var COPILOT_COMMAND2 = "copilot";
|
|
455
480
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -484,7 +509,7 @@ async function copilotPrompt(options) {
|
|
|
484
509
|
});
|
|
485
510
|
const output = stripAnsi(result.stdout);
|
|
486
511
|
if (output.includes("I'm sorry, but I cannot assist") && result.stderr?.includes("Stream completed without a response")) {
|
|
487
|
-
throw
|
|
512
|
+
throw createServicemeError3(
|
|
488
513
|
COPILOT_ERROR_CODES2.AUTH_REQUIRED,
|
|
489
514
|
"Copilot CLI returned a refusal response. This typically indicates an expired authentication token. Run `gh auth login` to re-authenticate.",
|
|
490
515
|
{ exitCode: 0, output, stderr: result.stderr }
|
|
@@ -494,7 +519,7 @@ async function copilotPrompt(options) {
|
|
|
494
519
|
} catch (error) {
|
|
495
520
|
const err = error;
|
|
496
521
|
if (err.code === "ETIMEDOUT") {
|
|
497
|
-
throw
|
|
522
|
+
throw createServicemeError3(
|
|
498
523
|
COPILOT_ERROR_CODES2.TIMEOUT,
|
|
499
524
|
`Copilot prompt timed out after ${String(timeout)}ms.`
|
|
500
525
|
);
|
|
@@ -503,7 +528,7 @@ async function copilotPrompt(options) {
|
|
|
503
528
|
const output = stripAnsi(err.stdout ?? "");
|
|
504
529
|
const stderr = err.stderr ?? err.message ?? "";
|
|
505
530
|
if (output.includes("I'm sorry, but I cannot assist") || stderr.includes("Stream completed without a response")) {
|
|
506
|
-
throw
|
|
531
|
+
throw createServicemeError3(
|
|
507
532
|
COPILOT_ERROR_CODES2.AUTH_REQUIRED,
|
|
508
533
|
"Copilot CLI returned a refusal response. This typically indicates an expired authentication token. Run `gh auth login` to re-authenticate.",
|
|
509
534
|
{ exitCode, output, stderr }
|
|
@@ -512,7 +537,7 @@ async function copilotPrompt(options) {
|
|
|
512
537
|
if (exitCode !== 0 && output) {
|
|
513
538
|
return { output, exitCode };
|
|
514
539
|
}
|
|
515
|
-
throw
|
|
540
|
+
throw createServicemeError3(
|
|
516
541
|
COPILOT_ERROR_CODES2.EXECUTION_FAILED,
|
|
517
542
|
stderr || `Copilot exited with code ${String(exitCode)}.`,
|
|
518
543
|
{ exitCode, stderr }
|
|
@@ -522,7 +547,7 @@ async function copilotPrompt(options) {
|
|
|
522
547
|
|
|
523
548
|
// src/env/environmentInspector.ts
|
|
524
549
|
import {
|
|
525
|
-
createServicemeError as
|
|
550
|
+
createServicemeError as createServicemeError4,
|
|
526
551
|
KNOWN_ENVIRONMENT_TOOLS
|
|
527
552
|
} from "@serviceme/devtools-protocol";
|
|
528
553
|
var DEFAULT_TOOL_CHECK_TIMEOUT_MS = 5e3;
|
|
@@ -550,7 +575,7 @@ var EnvironmentInspector = class {
|
|
|
550
575
|
}
|
|
551
576
|
async checkTool(toolName) {
|
|
552
577
|
if (!/^[a-zA-Z0-9-]+$/.test(toolName)) {
|
|
553
|
-
throw
|
|
578
|
+
throw createServicemeError4("invalid_params", "Invalid tool name.");
|
|
554
579
|
}
|
|
555
580
|
try {
|
|
556
581
|
if (toolName === "nvm") {
|
|
@@ -734,7 +759,7 @@ var EnvironmentInspector = class {
|
|
|
734
759
|
const execError = error;
|
|
735
760
|
const message = execError.message || String(error);
|
|
736
761
|
const code = execError.code;
|
|
737
|
-
const isNotFound = message.includes("command not found") || message.includes("not recognized") || message.includes("ENOENT") || code === "ENOENT" || code === ERROR_CODE_NOT_FOUND;
|
|
762
|
+
const isNotFound = message.includes("command not found") || message.includes("not recognized") || message.includes("ENOENT") || message.includes("EACCES") || code === "ENOENT" || code === "EACCES" || code === ERROR_CODE_NOT_FOUND;
|
|
738
763
|
const isTimeout = code === ERROR_CODE_TIMEOUT || message.toLowerCase().includes("timed out");
|
|
739
764
|
return {
|
|
740
765
|
installed: false,
|
|
@@ -747,7 +772,7 @@ var EnvironmentInspector = class {
|
|
|
747
772
|
import * as fs2 from "fs/promises";
|
|
748
773
|
import * as path2 from "path";
|
|
749
774
|
import {
|
|
750
|
-
createServicemeError as
|
|
775
|
+
createServicemeError as createServicemeError5
|
|
751
776
|
} from "@serviceme/devtools-protocol";
|
|
752
777
|
var SUPPORTED_FORMATS = [
|
|
753
778
|
".jpg",
|
|
@@ -792,7 +817,7 @@ var ImageTools = class {
|
|
|
792
817
|
async compress(imagePath, options) {
|
|
793
818
|
const validation = await this.validate(imagePath, options.sharpModulePath);
|
|
794
819
|
if (!validation.valid) {
|
|
795
|
-
throw
|
|
820
|
+
throw createServicemeError5(
|
|
796
821
|
"invalid_params",
|
|
797
822
|
`Invalid image file: ${imagePath}`
|
|
798
823
|
);
|
|
@@ -866,7 +891,7 @@ var ImageTools = class {
|
|
|
866
891
|
try {
|
|
867
892
|
return sharpModulePath ? __require(sharpModulePath) : __require("sharp");
|
|
868
893
|
} catch (error) {
|
|
869
|
-
throw
|
|
894
|
+
throw createServicemeError5(
|
|
870
895
|
"internal_error",
|
|
871
896
|
`sharp is required for image operations: ${error instanceof Error ? error.message : String(error)}`
|
|
872
897
|
);
|
|
@@ -879,7 +904,7 @@ function createImageTools() {
|
|
|
879
904
|
|
|
880
905
|
// src/json/jsonTools.ts
|
|
881
906
|
import {
|
|
882
|
-
createServicemeError as
|
|
907
|
+
createServicemeError as createServicemeError6,
|
|
883
908
|
DEFAULT_JSON_SORT_OPTIONS
|
|
884
909
|
} from "@serviceme/devtools-protocol";
|
|
885
910
|
import { parse as parseCommentJson } from "comment-json";
|
|
@@ -923,7 +948,7 @@ function parseJson(text) {
|
|
|
923
948
|
} catch {
|
|
924
949
|
}
|
|
925
950
|
}
|
|
926
|
-
throw
|
|
951
|
+
throw createServicemeError6("json_invalid_input", "Invalid JSON format.");
|
|
927
952
|
}
|
|
928
953
|
function sortObject(obj, options) {
|
|
929
954
|
if (Array.isArray(obj)) {
|
|
@@ -1018,7 +1043,7 @@ function createConsoleLogger(prefix = "serviceme") {
|
|
|
1018
1043
|
import * as fs3 from "fs/promises";
|
|
1019
1044
|
import * as path3 from "path";
|
|
1020
1045
|
import {
|
|
1021
|
-
createServicemeError as
|
|
1046
|
+
createServicemeError as createServicemeError7
|
|
1022
1047
|
} from "@serviceme/devtools-protocol";
|
|
1023
1048
|
|
|
1024
1049
|
// src/utils/fileUtils.ts
|
|
@@ -1183,7 +1208,7 @@ var ProjectTools = class {
|
|
|
1183
1208
|
}
|
|
1184
1209
|
async installDependencies(workspacePath, command) {
|
|
1185
1210
|
if (!command) {
|
|
1186
|
-
throw
|
|
1211
|
+
throw createServicemeError7("invalid_params", "Expected install command.");
|
|
1187
1212
|
}
|
|
1188
1213
|
await runCommand(command, {
|
|
1189
1214
|
cwd: workspacePath,
|
|
@@ -1246,13 +1271,16 @@ var ProjectTools = class {
|
|
|
1246
1271
|
}
|
|
1247
1272
|
async runScaffoldPrune(workspacePath, preset) {
|
|
1248
1273
|
if (!preset) {
|
|
1249
|
-
throw
|
|
1274
|
+
throw createServicemeError7("invalid_params", "Expected scaffold preset.");
|
|
1250
1275
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
];
|
|
1276
|
+
await this.ensurePresetManifest(workspacePath, preset);
|
|
1277
|
+
const pruneCommand = `pnpm run scaffold:prune -- --preset ${preset} --project-root .`;
|
|
1278
|
+
const initMetadataCommand = `pnpm run scaffold:init-metadata -- --preset ${preset} --project-root . --force`;
|
|
1279
|
+
const commands = [pruneCommand, initMetadataCommand];
|
|
1255
1280
|
for (const command of commands) {
|
|
1281
|
+
if (command === initMetadataCommand) {
|
|
1282
|
+
await this.ensurePresetManifest(workspacePath, preset);
|
|
1283
|
+
}
|
|
1256
1284
|
await runCommand(command, {
|
|
1257
1285
|
cwd: workspacePath,
|
|
1258
1286
|
shell: true
|
|
@@ -1264,6 +1292,44 @@ var ProjectTools = class {
|
|
|
1264
1292
|
commands
|
|
1265
1293
|
};
|
|
1266
1294
|
}
|
|
1295
|
+
async ensurePresetManifest(workspacePath, preset) {
|
|
1296
|
+
const presetManifestPath = path3.join(
|
|
1297
|
+
workspacePath,
|
|
1298
|
+
".ms-scaffold",
|
|
1299
|
+
"presets",
|
|
1300
|
+
`${preset}.json`
|
|
1301
|
+
);
|
|
1302
|
+
if (await this.pathExists(presetManifestPath)) {
|
|
1303
|
+
return;
|
|
1304
|
+
}
|
|
1305
|
+
const projectModePath = path3.join(
|
|
1306
|
+
workspacePath,
|
|
1307
|
+
".ms-scaffold",
|
|
1308
|
+
"project-mode.json"
|
|
1309
|
+
);
|
|
1310
|
+
if (!await this.pathExists(projectModePath)) {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
const projectModeRaw = await fs3.readFile(projectModePath, "utf8");
|
|
1314
|
+
const projectMode = JSON.parse(projectModeRaw);
|
|
1315
|
+
const synthesizedPreset = {
|
|
1316
|
+
preset,
|
|
1317
|
+
selectedModules: Array.isArray(projectMode.selectedModules) ? projectMode.selectedModules : [],
|
|
1318
|
+
prunedModules: Array.isArray(projectMode.prunedModules) ? projectMode.prunedModules : [],
|
|
1319
|
+
exclude: [],
|
|
1320
|
+
recommendedFollowUps: [],
|
|
1321
|
+
managedFiles: [],
|
|
1322
|
+
mergeManagedFiles: [],
|
|
1323
|
+
userOwnedPaths: []
|
|
1324
|
+
};
|
|
1325
|
+
await fs3.mkdir(path3.dirname(presetManifestPath), { recursive: true });
|
|
1326
|
+
await fs3.writeFile(
|
|
1327
|
+
presetManifestPath,
|
|
1328
|
+
`${JSON.stringify(synthesizedPreset, null, 2)}
|
|
1329
|
+
`,
|
|
1330
|
+
"utf8"
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1267
1333
|
async findScripts(dir, extensions) {
|
|
1268
1334
|
const results = [];
|
|
1269
1335
|
let entries;
|
|
@@ -1884,7 +1950,7 @@ function getExecutor(taskType) {
|
|
|
1884
1950
|
import { randomUUID } from "crypto";
|
|
1885
1951
|
import * as fs8 from "fs";
|
|
1886
1952
|
import * as path7 from "path";
|
|
1887
|
-
import { createServicemeError as
|
|
1953
|
+
import { createServicemeError as createServicemeError8 } from "@serviceme/devtools-protocol";
|
|
1888
1954
|
var CONFIG_DIR3 = ".serviceme";
|
|
1889
1955
|
var CONFIG_FILE = "scheduled-tasks.json";
|
|
1890
1956
|
function emptyConfig() {
|
|
@@ -1895,7 +1961,7 @@ function isRecord(value) {
|
|
|
1895
1961
|
}
|
|
1896
1962
|
function requireNonEmptyString(payload, field, taskType) {
|
|
1897
1963
|
if (!isRecord(payload) || typeof payload[field] !== "string" || !payload[field].trim()) {
|
|
1898
|
-
throw
|
|
1964
|
+
throw createServicemeError8(
|
|
1899
1965
|
"invalid_payload",
|
|
1900
1966
|
`${taskType} payload ${field} is required`
|
|
1901
1967
|
);
|
|
@@ -2543,6 +2609,7 @@ function matchCronField(field, value) {
|
|
|
2543
2609
|
}
|
|
2544
2610
|
|
|
2545
2611
|
// src/skills/SkillCatalogClient.ts
|
|
2612
|
+
import { createServicemeError as createServicemeError9 } from "@serviceme/devtools-protocol";
|
|
2546
2613
|
var SkillCatalogClient = class {
|
|
2547
2614
|
constructor(options = {}) {
|
|
2548
2615
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -2567,6 +2634,30 @@ var SkillCatalogClient = class {
|
|
|
2567
2634
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2568
2635
|
};
|
|
2569
2636
|
}
|
|
2637
|
+
async downloadSkill(remoteId) {
|
|
2638
|
+
if (!this.baseUrl) {
|
|
2639
|
+
throw createServicemeError9(
|
|
2640
|
+
"workspace_not_found",
|
|
2641
|
+
"Skill catalog baseUrl is not configured."
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
const response = await this.fetchImpl(
|
|
2645
|
+
`${this.baseUrl}/api/v1/marketplace/skills/download/${remoteId}`
|
|
2646
|
+
);
|
|
2647
|
+
if (!response.ok) {
|
|
2648
|
+
if (response.status === 404) {
|
|
2649
|
+
throw createServicemeError9(
|
|
2650
|
+
"not_found",
|
|
2651
|
+
`Skill '${remoteId}' not found`
|
|
2652
|
+
);
|
|
2653
|
+
}
|
|
2654
|
+
throw new Error(
|
|
2655
|
+
`Failed to download skill ${remoteId}: ${response.status}`
|
|
2656
|
+
);
|
|
2657
|
+
}
|
|
2658
|
+
const payload = await response.json();
|
|
2659
|
+
return payload.data?.files ?? [];
|
|
2660
|
+
}
|
|
2570
2661
|
};
|
|
2571
2662
|
|
|
2572
2663
|
// src/skills/SkillReconciler.ts
|
|
@@ -2703,6 +2794,22 @@ var SkillStore = class {
|
|
|
2703
2794
|
return false;
|
|
2704
2795
|
}
|
|
2705
2796
|
}
|
|
2797
|
+
async writeSkillFiles(skillId, scope, files) {
|
|
2798
|
+
const root = scope === "workspace" ? path9.join(this.workspacePath, WORKSPACE_SKILLS_ROOT_RELATIVE) : this.userSkillsRoot;
|
|
2799
|
+
const targetDir = path9.join(root, skillId);
|
|
2800
|
+
await this.fileSystem.mkdir(targetDir, { recursive: true });
|
|
2801
|
+
for (const file of files) {
|
|
2802
|
+
const filePath = path9.join(targetDir, file.path);
|
|
2803
|
+
await this.fileSystem.mkdir(path9.dirname(filePath), { recursive: true });
|
|
2804
|
+
await this.fileSystem.writeFile(filePath, file.content, "utf-8");
|
|
2805
|
+
if (file.executable) {
|
|
2806
|
+
try {
|
|
2807
|
+
await this.fileSystem.chmod(filePath, 493);
|
|
2808
|
+
} catch {
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2706
2813
|
};
|
|
2707
2814
|
export {
|
|
2708
2815
|
AgentCatalogClient,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serviceme/devtools-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Reusable Node.js core capabilities powering the SERVICEME CLI and integrations.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"repository": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"comment-json": "^4.5.1",
|
|
37
37
|
"json5": "^2.2.3",
|
|
38
38
|
"yauzl": "^3.2.0",
|
|
39
|
-
"@serviceme/devtools-protocol": "0.1.
|
|
39
|
+
"@serviceme/devtools-protocol": "0.1.7"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^24",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"scripts": {
|
|
49
49
|
"watch": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
50
50
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
51
52
|
"test": "pnpm run build && node --test test/**/*.test.js && node --import tsx --test src/**/__tests__/**/*.test.ts",
|
|
52
53
|
"release:check": "pnpm run build && npm pack --dry-run",
|
|
53
54
|
"pack": "npm pack",
|