@serviceme/devtools-cli 0.1.4 → 0.1.6
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/bridgeServer.js +1202 -96
- package/dist/cli.js +2087 -253
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var fs12 = require('fs/promises');
|
|
5
|
+
var path11 = require('path');
|
|
4
6
|
var child_process = require('child_process');
|
|
5
|
-
var
|
|
6
|
-
var path = require('path');
|
|
7
|
-
var fs8 = require('fs');
|
|
7
|
+
var fs9 = require('fs');
|
|
8
8
|
var crypto = require('crypto');
|
|
9
9
|
var os = require('os');
|
|
10
10
|
var readline = require('readline');
|
|
@@ -27,9 +27,9 @@ function _interopNamespace(e) {
|
|
|
27
27
|
return Object.freeze(n);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
var
|
|
30
|
+
var fs12__namespace = /*#__PURE__*/_interopNamespace(fs12);
|
|
31
|
+
var path11__namespace = /*#__PURE__*/_interopNamespace(path11);
|
|
32
|
+
var fs9__namespace = /*#__PURE__*/_interopNamespace(fs9);
|
|
33
33
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
34
34
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
35
35
|
|
|
@@ -72,12 +72,24 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
72
72
|
mod
|
|
73
73
|
));
|
|
74
74
|
|
|
75
|
+
// ../../packages/serviceme-protocol/src/agent.ts
|
|
76
|
+
var init_agent = __esm({
|
|
77
|
+
"../../packages/serviceme-protocol/src/agent.ts"() {
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
75
81
|
// ../../packages/serviceme-protocol/src/scheduled-tasks.ts
|
|
76
82
|
var init_scheduled_tasks = __esm({
|
|
77
83
|
"../../packages/serviceme-protocol/src/scheduled-tasks.ts"() {
|
|
78
84
|
}
|
|
79
85
|
});
|
|
80
86
|
|
|
87
|
+
// ../../packages/serviceme-protocol/src/skill.ts
|
|
88
|
+
var init_skill = __esm({
|
|
89
|
+
"../../packages/serviceme-protocol/src/skill.ts"() {
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
81
93
|
// ../../packages/serviceme-protocol/src/bridge.ts
|
|
82
94
|
function isRecord(value) {
|
|
83
95
|
return typeof value === "object" && value !== null;
|
|
@@ -97,7 +109,9 @@ function isBridgeRequest(value) {
|
|
|
97
109
|
var SERVICEME_PROTOCOL_VERSION, BRIDGE_METHODS;
|
|
98
110
|
var init_bridge = __esm({
|
|
99
111
|
"../../packages/serviceme-protocol/src/bridge.ts"() {
|
|
112
|
+
init_agent();
|
|
100
113
|
init_scheduled_tasks();
|
|
114
|
+
init_skill();
|
|
101
115
|
SERVICEME_PROTOCOL_VERSION = 2;
|
|
102
116
|
BRIDGE_METHODS = [
|
|
103
117
|
"system.hello",
|
|
@@ -105,7 +119,14 @@ var init_bridge = __esm({
|
|
|
105
119
|
"system.shutdown",
|
|
106
120
|
"task.execute",
|
|
107
121
|
"task.cancel",
|
|
108
|
-
"task.list-running"
|
|
122
|
+
"task.list-running",
|
|
123
|
+
"skill.marketplace-state",
|
|
124
|
+
"skill.mutate",
|
|
125
|
+
"skill.reconcile",
|
|
126
|
+
"skill.publishable",
|
|
127
|
+
"agent.marketplace-state",
|
|
128
|
+
"agent.mutate",
|
|
129
|
+
"agent.permissions"
|
|
109
130
|
];
|
|
110
131
|
}
|
|
111
132
|
});
|
|
@@ -159,6 +180,7 @@ var init_env = __esm({
|
|
|
159
180
|
"pnpm",
|
|
160
181
|
"nvm",
|
|
161
182
|
"nrm",
|
|
183
|
+
"rtk",
|
|
162
184
|
"dotnet",
|
|
163
185
|
"nuget"
|
|
164
186
|
];
|
|
@@ -324,6 +346,7 @@ var init_project = __esm({
|
|
|
324
346
|
// ../../packages/serviceme-protocol/src/index.ts
|
|
325
347
|
var init_src = __esm({
|
|
326
348
|
"../../packages/serviceme-protocol/src/index.ts"() {
|
|
349
|
+
init_agent();
|
|
327
350
|
init_bridge();
|
|
328
351
|
init_cli();
|
|
329
352
|
init_copilot();
|
|
@@ -334,6 +357,328 @@ var init_src = __esm({
|
|
|
334
357
|
init_metadata();
|
|
335
358
|
init_project();
|
|
336
359
|
init_scheduled_tasks();
|
|
360
|
+
init_skill();
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
// ../../packages/serviceme-core/src/agents/AgentCatalogClient.ts
|
|
365
|
+
var AgentCatalogClient;
|
|
366
|
+
var init_AgentCatalogClient = __esm({
|
|
367
|
+
"../../packages/serviceme-core/src/agents/AgentCatalogClient.ts"() {
|
|
368
|
+
AgentCatalogClient = class {
|
|
369
|
+
constructor(options2 = {}) {
|
|
370
|
+
this.fetchImpl = options2.fetchImpl ?? fetch;
|
|
371
|
+
this.baseUrl = options2.baseUrl;
|
|
372
|
+
}
|
|
373
|
+
async getCatalog() {
|
|
374
|
+
if (!this.baseUrl) {
|
|
375
|
+
return {
|
|
376
|
+
agents: [],
|
|
377
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
const response = await this.fetchImpl(
|
|
381
|
+
`${this.baseUrl}/api/v1/marketplace/agents`
|
|
382
|
+
);
|
|
383
|
+
if (!response.ok) {
|
|
384
|
+
throw new Error(`Failed to fetch agents catalog: ${response.status}`);
|
|
385
|
+
}
|
|
386
|
+
const data = await response.json();
|
|
387
|
+
return {
|
|
388
|
+
agents: data.agents ?? [],
|
|
389
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// ../../packages/serviceme-core/src/permissions/agent-permissions.ts
|
|
397
|
+
function parseAgentToolPermissions(content) {
|
|
398
|
+
const fmMatch = content.match(FRONTMATTER_REGEX);
|
|
399
|
+
if (!fmMatch?.[1]) return [];
|
|
400
|
+
const frontmatter = fmMatch[1];
|
|
401
|
+
const inlineMatch = frontmatter.match(TOOLS_INLINE_REGEX);
|
|
402
|
+
if (inlineMatch?.[1] != null) {
|
|
403
|
+
const raw = inlineMatch[1];
|
|
404
|
+
return raw.split(",").map((t) => t.trim()).filter(Boolean).map((tool) => ({
|
|
405
|
+
tool,
|
|
406
|
+
riskLevel: TOOL_RISK_MAP[tool] ?? "medium"
|
|
407
|
+
}));
|
|
408
|
+
}
|
|
409
|
+
const blockMatch = frontmatter.match(TOOLS_LINE_REGEX);
|
|
410
|
+
if (!blockMatch?.[0]) return [];
|
|
411
|
+
const toolsStartIndex = frontmatter.indexOf(blockMatch[0]) + blockMatch[0].length;
|
|
412
|
+
const remaining = frontmatter.slice(toolsStartIndex);
|
|
413
|
+
const lines = remaining.split(/\r?\n/);
|
|
414
|
+
const tools = [];
|
|
415
|
+
for (const line2 of lines) {
|
|
416
|
+
const itemMatch = line2.match(LIST_ITEM_REGEX);
|
|
417
|
+
if (itemMatch?.[1]) {
|
|
418
|
+
const tool = itemMatch[1].trim();
|
|
419
|
+
tools.push({ tool, riskLevel: TOOL_RISK_MAP[tool] ?? "medium" });
|
|
420
|
+
} else if (line2.trim() !== "" && !line2.startsWith(" ") && !line2.startsWith(" ")) {
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return tools;
|
|
425
|
+
}
|
|
426
|
+
var TOOL_RISK_MAP, FRONTMATTER_REGEX, TOOLS_LINE_REGEX, TOOLS_INLINE_REGEX, LIST_ITEM_REGEX;
|
|
427
|
+
var init_agent_permissions = __esm({
|
|
428
|
+
"../../packages/serviceme-core/src/permissions/agent-permissions.ts"() {
|
|
429
|
+
TOOL_RISK_MAP = {
|
|
430
|
+
shell: "high",
|
|
431
|
+
terminal: "high",
|
|
432
|
+
run_in_terminal: "high",
|
|
433
|
+
execution_subagent: "high",
|
|
434
|
+
filesystem: "medium",
|
|
435
|
+
fetch: "medium",
|
|
436
|
+
fetch_webpage: "medium",
|
|
437
|
+
create_file: "medium",
|
|
438
|
+
replace_string_in_file: "medium",
|
|
439
|
+
multi_replace_string_in_file: "medium",
|
|
440
|
+
read_file: "low",
|
|
441
|
+
search: "low",
|
|
442
|
+
grep_search: "low",
|
|
443
|
+
file_search: "low",
|
|
444
|
+
semantic_search: "low",
|
|
445
|
+
list_dir: "low"
|
|
446
|
+
};
|
|
447
|
+
FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
448
|
+
TOOLS_LINE_REGEX = /^tools:\s*$/m;
|
|
449
|
+
TOOLS_INLINE_REGEX = /^tools:\s*\[([^\]]*)\]/m;
|
|
450
|
+
LIST_ITEM_REGEX = /^\s*-\s+(.+)$/;
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
// ../../packages/serviceme-core/src/permissions/index.ts
|
|
455
|
+
var init_permissions = __esm({
|
|
456
|
+
"../../packages/serviceme-core/src/permissions/index.ts"() {
|
|
457
|
+
init_agent_permissions();
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// ../../packages/serviceme-core/src/agents/AgentReconciler.ts
|
|
462
|
+
var AgentReconciler;
|
|
463
|
+
var init_AgentReconciler = __esm({
|
|
464
|
+
"../../packages/serviceme-core/src/agents/AgentReconciler.ts"() {
|
|
465
|
+
init_permissions();
|
|
466
|
+
AgentReconciler = class {
|
|
467
|
+
constructor(deps) {
|
|
468
|
+
this.deps = deps;
|
|
469
|
+
}
|
|
470
|
+
async mutate(request) {
|
|
471
|
+
if (request.targetScope !== "workspace" && request.targetScope !== "user") {
|
|
472
|
+
throw new Error(`Invalid target scope: ${String(request.targetScope)}`);
|
|
473
|
+
}
|
|
474
|
+
if (request.action === "uninstall" || request.action === "move" || request.action === "removeExternal") {
|
|
475
|
+
return {
|
|
476
|
+
status: "success",
|
|
477
|
+
changed: true,
|
|
478
|
+
message: `Agent ${request.action} completed.`
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
if (request.action !== "install") {
|
|
482
|
+
return {
|
|
483
|
+
status: "blocked",
|
|
484
|
+
changed: false,
|
|
485
|
+
message: `Agent action is not supported by bridge reconciler: ${request.action}`
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
const catalog = await this.deps.catalogClient.getCatalog();
|
|
489
|
+
const remoteAgent = catalog.agents.find(
|
|
490
|
+
(agent) => this.deps.agentStore.normalizeRemoteAgentId(agent.id) === request.agentId
|
|
491
|
+
);
|
|
492
|
+
if (!remoteAgent) {
|
|
493
|
+
return {
|
|
494
|
+
status: "blocked",
|
|
495
|
+
changed: false,
|
|
496
|
+
message: "Agent not found in catalog."
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
if (!request.confirmed && this.hasHighRiskTool(remoteAgent.tools)) {
|
|
500
|
+
return {
|
|
501
|
+
status: "requires_confirmation",
|
|
502
|
+
changed: false,
|
|
503
|
+
message: "This agent uses high-risk tools that require confirmation.",
|
|
504
|
+
tools: remoteAgent.tools
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
status: "success",
|
|
509
|
+
changed: true,
|
|
510
|
+
message: "Agent installed."
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
getPermissionSummary(agentId, agentName, content) {
|
|
514
|
+
const tools = parseAgentToolPermissions(content);
|
|
515
|
+
return {
|
|
516
|
+
agentId,
|
|
517
|
+
agentName,
|
|
518
|
+
tools,
|
|
519
|
+
highRiskCount: tools.filter((tool) => tool.riskLevel === "high").length,
|
|
520
|
+
mediumRiskCount: tools.filter((tool) => tool.riskLevel === "medium").length,
|
|
521
|
+
lowRiskCount: tools.filter((tool) => tool.riskLevel === "low").length
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
hasHighRiskTool(tools) {
|
|
525
|
+
return tools.some((tool) => TOOL_RISK_MAP[tool] === "high");
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
function assertSafeLocalAgentId(agentId) {
|
|
531
|
+
if (typeof agentId !== "string" || agentId.length === 0 || agentId === "." || agentId === ".." || agentId.includes("/") || agentId.includes("\\") || !SAFE_LOCAL_ID_PATTERN.test(agentId)) {
|
|
532
|
+
throw new Error(`Invalid agent id: ${agentId}`);
|
|
533
|
+
}
|
|
534
|
+
return agentId;
|
|
535
|
+
}
|
|
536
|
+
var WORKSPACE_AGENTS_ROOT_RELATIVE, WORKSPACE_AGENTS_STATE_RELATIVE, SAFE_LOCAL_ID_PATTERN, AgentStore;
|
|
537
|
+
var init_AgentStore = __esm({
|
|
538
|
+
"../../packages/serviceme-core/src/agents/AgentStore.ts"() {
|
|
539
|
+
WORKSPACE_AGENTS_ROOT_RELATIVE = ".github/agents";
|
|
540
|
+
WORKSPACE_AGENTS_STATE_RELATIVE = ".github/.ms-devtools-agents.yml";
|
|
541
|
+
SAFE_LOCAL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
542
|
+
AgentStore = class {
|
|
543
|
+
constructor(options2) {
|
|
544
|
+
this.workspacePath = options2.workspacePath;
|
|
545
|
+
this.userAgentsRoot = options2.userAgentsRoot;
|
|
546
|
+
this.fileSystem = options2.fileSystem ?? fs12__namespace;
|
|
547
|
+
this.schemaVersion = options2.schemaVersion ?? 1;
|
|
548
|
+
}
|
|
549
|
+
normalizeRemoteAgentId(remoteId) {
|
|
550
|
+
if (remoteId.startsWith("official/")) {
|
|
551
|
+
return assertSafeLocalAgentId(remoteId.slice("official/".length));
|
|
552
|
+
}
|
|
553
|
+
if (remoteId.startsWith("community/")) {
|
|
554
|
+
const lastSlash = remoteId.lastIndexOf("/");
|
|
555
|
+
return assertSafeLocalAgentId(remoteId.slice(lastSlash + 1));
|
|
556
|
+
}
|
|
557
|
+
return assertSafeLocalAgentId(remoteId);
|
|
558
|
+
}
|
|
559
|
+
getWorkspaceAgentsRootPath() {
|
|
560
|
+
return WORKSPACE_AGENTS_ROOT_RELATIVE;
|
|
561
|
+
}
|
|
562
|
+
getWorkspaceStateFilePath() {
|
|
563
|
+
return WORKSPACE_AGENTS_STATE_RELATIVE;
|
|
564
|
+
}
|
|
565
|
+
getUserAgentsRootPath() {
|
|
566
|
+
return this.userAgentsRoot;
|
|
567
|
+
}
|
|
568
|
+
async listWorkspaceAgentIds() {
|
|
569
|
+
return this.listAgentIds(
|
|
570
|
+
path11__namespace.join(this.workspacePath, WORKSPACE_AGENTS_ROOT_RELATIVE)
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
async listUserAgentIds() {
|
|
574
|
+
return this.listAgentIds(this.userAgentsRoot);
|
|
575
|
+
}
|
|
576
|
+
async readState() {
|
|
577
|
+
try {
|
|
578
|
+
const raw = await this.fileSystem.readFile(
|
|
579
|
+
path11__namespace.join(this.workspacePath, WORKSPACE_AGENTS_STATE_RELATIVE),
|
|
580
|
+
"utf-8"
|
|
581
|
+
);
|
|
582
|
+
const parsed = JSON.parse(raw);
|
|
583
|
+
if (typeof parsed.schemaVersion !== "number" || !Array.isArray(parsed.installedAgents)) {
|
|
584
|
+
return null;
|
|
585
|
+
}
|
|
586
|
+
return parsed;
|
|
587
|
+
} catch {
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
async writeState(state) {
|
|
592
|
+
const statePath = path11__namespace.join(
|
|
593
|
+
this.workspacePath,
|
|
594
|
+
WORKSPACE_AGENTS_STATE_RELATIVE
|
|
595
|
+
);
|
|
596
|
+
await this.fileSystem.mkdir(path11__namespace.dirname(statePath), { recursive: true });
|
|
597
|
+
await this.fileSystem.writeFile(
|
|
598
|
+
statePath,
|
|
599
|
+
JSON.stringify(state, null, 2),
|
|
600
|
+
"utf-8"
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
async addInstalledAgent(entry) {
|
|
604
|
+
const state = await this.readState() ?? {
|
|
605
|
+
schemaVersion: this.schemaVersion,
|
|
606
|
+
installedAgents: []
|
|
607
|
+
};
|
|
608
|
+
state.installedAgents = state.installedAgents.filter(
|
|
609
|
+
(agent) => agent.id !== entry.id
|
|
610
|
+
);
|
|
611
|
+
state.installedAgents.push(entry);
|
|
612
|
+
await this.writeState(state);
|
|
613
|
+
}
|
|
614
|
+
async removeInstalledAgent(agentId) {
|
|
615
|
+
const state = await this.readState();
|
|
616
|
+
if (!state) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
state.installedAgents = state.installedAgents.filter(
|
|
620
|
+
(agent) => agent.id !== agentId
|
|
621
|
+
);
|
|
622
|
+
await this.writeState(state);
|
|
623
|
+
}
|
|
624
|
+
async writeAgentFiles(agentId, scope, files) {
|
|
625
|
+
const root2 = scope === "workspace" ? path11__namespace.join(this.workspacePath, WORKSPACE_AGENTS_ROOT_RELATIVE) : this.userAgentsRoot;
|
|
626
|
+
const firstFile = files[0];
|
|
627
|
+
const isSingleFlatFile = files.length === 1 && firstFile !== void 0 && firstFile.path === `${agentId}.agent.md` && !firstFile.path.includes("/");
|
|
628
|
+
const targetDir = isSingleFlatFile ? root2 : path11__namespace.join(root2, agentId);
|
|
629
|
+
await this.fileSystem.mkdir(targetDir, { recursive: true });
|
|
630
|
+
for (const file of files) {
|
|
631
|
+
const filePath = path11__namespace.join(targetDir, file.path);
|
|
632
|
+
await this.fileSystem.mkdir(path11__namespace.dirname(filePath), { recursive: true });
|
|
633
|
+
await this.fileSystem.writeFile(filePath, file.content, "utf-8");
|
|
634
|
+
if (file.executable) {
|
|
635
|
+
try {
|
|
636
|
+
await this.fileSystem.chmod(filePath, 493);
|
|
637
|
+
} catch {
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
async listAgentIds(dir) {
|
|
643
|
+
try {
|
|
644
|
+
const entries = await this.fileSystem.readdir(dir, {
|
|
645
|
+
withFileTypes: true
|
|
646
|
+
});
|
|
647
|
+
const ids = [];
|
|
648
|
+
for (const entry of entries) {
|
|
649
|
+
if (entry.name.startsWith(".")) {
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
if (entry.isDirectory()) {
|
|
653
|
+
ids.push(entry.name);
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
if (entry.isFile() && entry.name.endsWith(".agent.md")) {
|
|
657
|
+
ids.push(entry.name.replace(/\.agent\.md$/, ""));
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
return ids.sort();
|
|
661
|
+
} catch {
|
|
662
|
+
return [];
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
// ../../packages/serviceme-core/src/agents/types.ts
|
|
670
|
+
var init_types = __esm({
|
|
671
|
+
"../../packages/serviceme-core/src/agents/types.ts"() {
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// ../../packages/serviceme-core/src/agents/index.ts
|
|
676
|
+
var init_agents = __esm({
|
|
677
|
+
"../../packages/serviceme-core/src/agents/index.ts"() {
|
|
678
|
+
init_AgentCatalogClient();
|
|
679
|
+
init_AgentReconciler();
|
|
680
|
+
init_AgentStore();
|
|
681
|
+
init_types();
|
|
337
682
|
}
|
|
338
683
|
});
|
|
339
684
|
function terminateCommandProcess(child) {
|
|
@@ -585,13 +930,25 @@ var init_copilot2 = __esm({
|
|
|
585
930
|
});
|
|
586
931
|
|
|
587
932
|
// ../../packages/serviceme-core/src/env/environmentInspector.ts
|
|
588
|
-
var TOOL_CHECK_TIMEOUT_MS, ERROR_CODE_NOT_FOUND, EnvironmentInspector;
|
|
933
|
+
var DEFAULT_TOOL_CHECK_TIMEOUT_MS, TOOL_CHECK_TIMEOUT_MS, ERROR_CODE_NOT_FOUND, ERROR_CODE_TIMEOUT, EnvironmentInspector;
|
|
589
934
|
var init_environmentInspector = __esm({
|
|
590
935
|
"../../packages/serviceme-core/src/env/environmentInspector.ts"() {
|
|
591
936
|
init_src();
|
|
592
937
|
init_runCommand();
|
|
593
|
-
|
|
938
|
+
DEFAULT_TOOL_CHECK_TIMEOUT_MS = 5e3;
|
|
939
|
+
TOOL_CHECK_TIMEOUT_MS = {
|
|
940
|
+
nuget: 12e3,
|
|
941
|
+
nvm: 8e3,
|
|
942
|
+
dotnet: 8e3,
|
|
943
|
+
// nvm4w/npm shims and globally-installed .cmd tools (pnpm, nrm) are slow to
|
|
944
|
+
// resolve on cold PATHs. Give them extra headroom so the version probe
|
|
945
|
+
// doesn't fall through to the generic 5s default.
|
|
946
|
+
npm: 15e3,
|
|
947
|
+
pnpm: 15e3,
|
|
948
|
+
nrm: 15e3
|
|
949
|
+
};
|
|
594
950
|
ERROR_CODE_NOT_FOUND = 127;
|
|
951
|
+
ERROR_CODE_TIMEOUT = "ETIMEDOUT";
|
|
595
952
|
EnvironmentInspector = class {
|
|
596
953
|
async checkEnvironment() {
|
|
597
954
|
const results = await Promise.all(
|
|
@@ -628,19 +985,39 @@ var init_environmentInspector = __esm({
|
|
|
628
985
|
const isWindows = process.platform === "win32";
|
|
629
986
|
const result = await runCommand(isWindows ? "where" : "which", {
|
|
630
987
|
args: [toolName],
|
|
631
|
-
timeoutMs:
|
|
988
|
+
timeoutMs: this.getToolTimeout(toolName)
|
|
989
|
+
});
|
|
990
|
+
return result.stdout.split(/\r?\n/).map((line2) => line2.trim()).find((line2) => line2.length > 0);
|
|
991
|
+
} catch {
|
|
992
|
+
return void 0;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* On Windows, prefer the `.cmd` shim for npm/pnpm/nrm. nvm4w registers
|
|
997
|
+
* BOTH an extensionless entry (pointing to node.exe) and a `<tool>.cmd`
|
|
998
|
+
* wrapper; `where` returns them in that order, and the extensionless one
|
|
999
|
+
* would just print node's own version.
|
|
1000
|
+
*/
|
|
1001
|
+
async getToolShimPath(toolName) {
|
|
1002
|
+
try {
|
|
1003
|
+
const result = await runCommand("where", {
|
|
1004
|
+
args: [toolName],
|
|
1005
|
+
timeoutMs: this.getToolTimeout(toolName)
|
|
632
1006
|
});
|
|
633
|
-
|
|
1007
|
+
const candidates = result.stdout.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2.length > 0);
|
|
1008
|
+
const cmdShim = candidates.find(
|
|
1009
|
+
(line2) => line2.toLowerCase().endsWith(".cmd")
|
|
1010
|
+
);
|
|
1011
|
+
return cmdShim ?? candidates[0];
|
|
634
1012
|
} catch {
|
|
635
1013
|
return void 0;
|
|
636
1014
|
}
|
|
637
1015
|
}
|
|
638
1016
|
async getToolVersion(toolName) {
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
timeoutMs: TOOL_CHECK_TIMEOUT_MS
|
|
1017
|
+
const invocation = await this.getVersionInvocation(toolName);
|
|
1018
|
+
const result = await runCommand(invocation.command, {
|
|
1019
|
+
args: invocation.args,
|
|
1020
|
+
timeoutMs: this.getToolTimeout(toolName)
|
|
644
1021
|
});
|
|
645
1022
|
return this.parseVersion(toolName, result.stdout || result.stderr);
|
|
646
1023
|
}
|
|
@@ -649,7 +1026,7 @@ var init_environmentInspector = __esm({
|
|
|
649
1026
|
try {
|
|
650
1027
|
const result = await runCommand("cmd.exe", {
|
|
651
1028
|
args: ["/c", "nvm version"],
|
|
652
|
-
timeoutMs:
|
|
1029
|
+
timeoutMs: this.getToolTimeout("nvm")
|
|
653
1030
|
});
|
|
654
1031
|
return {
|
|
655
1032
|
installed: true,
|
|
@@ -669,7 +1046,7 @@ var init_environmentInspector = __esm({
|
|
|
669
1046
|
"-lc",
|
|
670
1047
|
'export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; nvm --version'
|
|
671
1048
|
],
|
|
672
|
-
timeoutMs:
|
|
1049
|
+
timeoutMs: this.getToolTimeout("nvm")
|
|
673
1050
|
});
|
|
674
1051
|
return {
|
|
675
1052
|
installed: true,
|
|
@@ -694,7 +1071,7 @@ var init_environmentInspector = __esm({
|
|
|
694
1071
|
try {
|
|
695
1072
|
const result = await runCommand("dotnet", {
|
|
696
1073
|
args: ["nuget", "list", "source"],
|
|
697
|
-
timeoutMs:
|
|
1074
|
+
timeoutMs: this.getToolTimeout("nuget")
|
|
698
1075
|
});
|
|
699
1076
|
const privateSourceUrl = "http://192.168.20.209:10010/nuget";
|
|
700
1077
|
if (result.stdout.includes(privateSourceUrl)) {
|
|
@@ -712,17 +1089,35 @@ var init_environmentInspector = __esm({
|
|
|
712
1089
|
return this.handleToolCheckError(error);
|
|
713
1090
|
}
|
|
714
1091
|
}
|
|
715
|
-
|
|
1092
|
+
async getVersionInvocation(toolName) {
|
|
1093
|
+
const isWindows = process.platform === "win32";
|
|
1094
|
+
if (isWindows && ["npm", "pnpm", "nrm"].includes(toolName)) {
|
|
1095
|
+
const shim = await this.getToolShimPath(toolName);
|
|
1096
|
+
if (shim) {
|
|
1097
|
+
return {
|
|
1098
|
+
command: "cmd.exe",
|
|
1099
|
+
args: ["/c", shim, "--version"]
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
return {
|
|
1103
|
+
command: "cmd.exe",
|
|
1104
|
+
args: ["/c", toolName, "--version"]
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
716
1107
|
const commands = {
|
|
717
|
-
git: "git --version",
|
|
718
|
-
node: "node --version",
|
|
719
|
-
npm: "npm --version",
|
|
720
|
-
pnpm: "pnpm --version",
|
|
721
|
-
nvm: "nvm --version",
|
|
722
|
-
nrm: "nrm --version",
|
|
723
|
-
|
|
1108
|
+
git: { command: "git", args: ["--version"] },
|
|
1109
|
+
node: { command: "node", args: ["--version"] },
|
|
1110
|
+
npm: { command: "npm", args: ["--version"] },
|
|
1111
|
+
pnpm: { command: "pnpm", args: ["--version"] },
|
|
1112
|
+
nvm: { command: "nvm", args: ["--version"] },
|
|
1113
|
+
nrm: { command: "nrm", args: ["--version"] },
|
|
1114
|
+
rtk: { command: "rtk", args: ["--version"] },
|
|
1115
|
+
dotnet: { command: "dotnet", args: ["--version"] }
|
|
724
1116
|
};
|
|
725
|
-
return commands[toolName] ||
|
|
1117
|
+
return commands[toolName] || { command: toolName, args: ["--version"] };
|
|
1118
|
+
}
|
|
1119
|
+
getToolTimeout(toolName) {
|
|
1120
|
+
return TOOL_CHECK_TIMEOUT_MS[toolName] ?? DEFAULT_TOOL_CHECK_TIMEOUT_MS;
|
|
726
1121
|
}
|
|
727
1122
|
parseVersion(toolName, output) {
|
|
728
1123
|
const cleaned = output.trim();
|
|
@@ -749,10 +1144,11 @@ var init_environmentInspector = __esm({
|
|
|
749
1144
|
const execError = error;
|
|
750
1145
|
const message = execError.message || String(error);
|
|
751
1146
|
const code = execError.code;
|
|
752
|
-
const isNotFound = message.includes("command not found") || message.includes("not recognized") || code === ERROR_CODE_NOT_FOUND;
|
|
1147
|
+
const isNotFound = message.includes("command not found") || message.includes("not recognized") || message.includes("ENOENT") || code === "ENOENT" || code === ERROR_CODE_NOT_FOUND;
|
|
1148
|
+
const isTimeout = code === ERROR_CODE_TIMEOUT || message.toLowerCase().includes("timed out");
|
|
753
1149
|
return {
|
|
754
1150
|
installed: false,
|
|
755
|
-
error: isNotFound ? "Not installed" : message
|
|
1151
|
+
error: isNotFound ? "Not installed" : isTimeout ? "Check timed out" : message
|
|
756
1152
|
};
|
|
757
1153
|
}
|
|
758
1154
|
};
|
|
@@ -784,7 +1180,7 @@ var init_imageTools = __esm({
|
|
|
784
1180
|
if (!await this.pathExists(filePath)) {
|
|
785
1181
|
return { valid: false };
|
|
786
1182
|
}
|
|
787
|
-
if (!SUPPORTED_FORMATS.includes(
|
|
1183
|
+
if (!SUPPORTED_FORMATS.includes(path11__namespace.extname(filePath).toLowerCase())) {
|
|
788
1184
|
return { valid: false };
|
|
789
1185
|
}
|
|
790
1186
|
await this.getInfo(filePath, sharpModulePath);
|
|
@@ -796,7 +1192,7 @@ var init_imageTools = __esm({
|
|
|
796
1192
|
async getInfo(imagePath, sharpModulePath) {
|
|
797
1193
|
const sharp = this.loadSharp(sharpModulePath);
|
|
798
1194
|
const metadata = await sharp(imagePath).metadata();
|
|
799
|
-
const stats = await
|
|
1195
|
+
const stats = await fs12__namespace.stat(imagePath);
|
|
800
1196
|
return {
|
|
801
1197
|
width: metadata.width ?? 0,
|
|
802
1198
|
height: metadata.height ?? 0,
|
|
@@ -813,7 +1209,7 @@ var init_imageTools = __esm({
|
|
|
813
1209
|
`Invalid image file: ${imagePath}`
|
|
814
1210
|
);
|
|
815
1211
|
}
|
|
816
|
-
const originalStats = await
|
|
1212
|
+
const originalStats = await fs12__namespace.stat(imagePath);
|
|
817
1213
|
const originalSize = originalStats.size;
|
|
818
1214
|
const outputPath = this.getOutputPath(imagePath, options2);
|
|
819
1215
|
const compressedBuffer = await this.compressWithSharp(imagePath, options2);
|
|
@@ -828,7 +1224,7 @@ var init_imageTools = __esm({
|
|
|
828
1224
|
outputPath: imagePath
|
|
829
1225
|
};
|
|
830
1226
|
}
|
|
831
|
-
await
|
|
1227
|
+
await fs12__namespace.writeFile(outputPath, compressedBuffer);
|
|
832
1228
|
return {
|
|
833
1229
|
originalSize,
|
|
834
1230
|
compressedSize,
|
|
@@ -839,7 +1235,7 @@ var init_imageTools = __esm({
|
|
|
839
1235
|
async compressWithSharp(imagePath, options2) {
|
|
840
1236
|
const sharp = this.loadSharp(options2.sharpModulePath);
|
|
841
1237
|
let pipeline = sharp(imagePath);
|
|
842
|
-
switch (options2.format ??
|
|
1238
|
+
switch (options2.format ?? path11__namespace.extname(imagePath).toLowerCase().slice(1)) {
|
|
843
1239
|
case "jpg":
|
|
844
1240
|
case "jpeg":
|
|
845
1241
|
pipeline = pipeline.jpeg({ quality: options2.quality });
|
|
@@ -865,14 +1261,14 @@ var init_imageTools = __esm({
|
|
|
865
1261
|
if (options2.replaceOriginImage) {
|
|
866
1262
|
return inputPath;
|
|
867
1263
|
}
|
|
868
|
-
const dir =
|
|
869
|
-
const ext =
|
|
870
|
-
const name =
|
|
871
|
-
return
|
|
1264
|
+
const dir = path11__namespace.dirname(inputPath);
|
|
1265
|
+
const ext = path11__namespace.extname(inputPath);
|
|
1266
|
+
const name = path11__namespace.basename(inputPath, ext);
|
|
1267
|
+
return path11__namespace.join(dir, `${name}_compressed${ext}`);
|
|
872
1268
|
}
|
|
873
1269
|
async pathExists(targetPath) {
|
|
874
1270
|
try {
|
|
875
|
-
await
|
|
1271
|
+
await fs12__namespace.access(targetPath);
|
|
876
1272
|
return true;
|
|
877
1273
|
} catch {
|
|
878
1274
|
return false;
|
|
@@ -1379,8 +1775,8 @@ var require_esprima = __commonJS({
|
|
|
1379
1775
|
return result;
|
|
1380
1776
|
};
|
|
1381
1777
|
JSXParser2.prototype.lexJSX = function() {
|
|
1382
|
-
var
|
|
1383
|
-
if (
|
|
1778
|
+
var cp5 = this.scanner.source.charCodeAt(this.scanner.index);
|
|
1779
|
+
if (cp5 === 60 || cp5 === 62 || cp5 === 47 || cp5 === 58 || cp5 === 61 || cp5 === 123 || cp5 === 125) {
|
|
1384
1780
|
var value = this.scanner.source[this.scanner.index++];
|
|
1385
1781
|
return {
|
|
1386
1782
|
type: 7,
|
|
@@ -1391,7 +1787,7 @@ var require_esprima = __commonJS({
|
|
|
1391
1787
|
end: this.scanner.index
|
|
1392
1788
|
};
|
|
1393
1789
|
}
|
|
1394
|
-
if (
|
|
1790
|
+
if (cp5 === 34 || cp5 === 39) {
|
|
1395
1791
|
var start = this.scanner.index;
|
|
1396
1792
|
var quote = this.scanner.source[this.scanner.index++];
|
|
1397
1793
|
var str = "";
|
|
@@ -1414,7 +1810,7 @@ var require_esprima = __commonJS({
|
|
|
1414
1810
|
end: this.scanner.index
|
|
1415
1811
|
};
|
|
1416
1812
|
}
|
|
1417
|
-
if (
|
|
1813
|
+
if (cp5 === 46) {
|
|
1418
1814
|
var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1);
|
|
1419
1815
|
var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2);
|
|
1420
1816
|
var value = n1 === 46 && n2 === 46 ? "..." : ".";
|
|
@@ -1429,7 +1825,7 @@ var require_esprima = __commonJS({
|
|
|
1429
1825
|
end: this.scanner.index
|
|
1430
1826
|
};
|
|
1431
1827
|
}
|
|
1432
|
-
if (
|
|
1828
|
+
if (cp5 === 96) {
|
|
1433
1829
|
return {
|
|
1434
1830
|
type: 10,
|
|
1435
1831
|
value: "",
|
|
@@ -1439,7 +1835,7 @@ var require_esprima = __commonJS({
|
|
|
1439
1835
|
end: this.scanner.index
|
|
1440
1836
|
};
|
|
1441
1837
|
}
|
|
1442
|
-
if (character_1.Character.isIdentifierStart(
|
|
1838
|
+
if (character_1.Character.isIdentifierStart(cp5) && cp5 !== 92) {
|
|
1443
1839
|
var start = this.scanner.index;
|
|
1444
1840
|
++this.scanner.index;
|
|
1445
1841
|
while (!this.scanner.eof()) {
|
|
@@ -1768,33 +2164,33 @@ var require_esprima = __commonJS({
|
|
|
1768
2164
|
};
|
|
1769
2165
|
exports2.Character = {
|
|
1770
2166
|
/* tslint:disable:no-bitwise */
|
|
1771
|
-
fromCodePoint: function(
|
|
1772
|
-
return
|
|
2167
|
+
fromCodePoint: function(cp5) {
|
|
2168
|
+
return cp5 < 65536 ? String.fromCharCode(cp5) : String.fromCharCode(55296 + (cp5 - 65536 >> 10)) + String.fromCharCode(56320 + (cp5 - 65536 & 1023));
|
|
1773
2169
|
},
|
|
1774
2170
|
// https://tc39.github.io/ecma262/#sec-white-space
|
|
1775
|
-
isWhiteSpace: function(
|
|
1776
|
-
return
|
|
2171
|
+
isWhiteSpace: function(cp5) {
|
|
2172
|
+
return cp5 === 32 || cp5 === 9 || cp5 === 11 || cp5 === 12 || cp5 === 160 || cp5 >= 5760 && [5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279].indexOf(cp5) >= 0;
|
|
1777
2173
|
},
|
|
1778
2174
|
// https://tc39.github.io/ecma262/#sec-line-terminators
|
|
1779
|
-
isLineTerminator: function(
|
|
1780
|
-
return
|
|
2175
|
+
isLineTerminator: function(cp5) {
|
|
2176
|
+
return cp5 === 10 || cp5 === 13 || cp5 === 8232 || cp5 === 8233;
|
|
1781
2177
|
},
|
|
1782
2178
|
// https://tc39.github.io/ecma262/#sec-names-and-keywords
|
|
1783
|
-
isIdentifierStart: function(
|
|
1784
|
-
return
|
|
2179
|
+
isIdentifierStart: function(cp5) {
|
|
2180
|
+
return cp5 === 36 || cp5 === 95 || cp5 >= 65 && cp5 <= 90 || cp5 >= 97 && cp5 <= 122 || cp5 === 92 || cp5 >= 128 && Regex.NonAsciiIdentifierStart.test(exports2.Character.fromCodePoint(cp5));
|
|
1785
2181
|
},
|
|
1786
|
-
isIdentifierPart: function(
|
|
1787
|
-
return
|
|
2182
|
+
isIdentifierPart: function(cp5) {
|
|
2183
|
+
return cp5 === 36 || cp5 === 95 || cp5 >= 65 && cp5 <= 90 || cp5 >= 97 && cp5 <= 122 || cp5 >= 48 && cp5 <= 57 || cp5 === 92 || cp5 >= 128 && Regex.NonAsciiIdentifierPart.test(exports2.Character.fromCodePoint(cp5));
|
|
1788
2184
|
},
|
|
1789
2185
|
// https://tc39.github.io/ecma262/#sec-literals-numeric-literals
|
|
1790
|
-
isDecimalDigit: function(
|
|
1791
|
-
return
|
|
2186
|
+
isDecimalDigit: function(cp5) {
|
|
2187
|
+
return cp5 >= 48 && cp5 <= 57;
|
|
1792
2188
|
},
|
|
1793
|
-
isHexDigit: function(
|
|
1794
|
-
return
|
|
2189
|
+
isHexDigit: function(cp5) {
|
|
2190
|
+
return cp5 >= 48 && cp5 <= 57 || cp5 >= 65 && cp5 <= 70 || cp5 >= 97 && cp5 <= 102;
|
|
1795
2191
|
},
|
|
1796
|
-
isOctalDigit: function(
|
|
1797
|
-
return
|
|
2192
|
+
isOctalDigit: function(cp5) {
|
|
2193
|
+
return cp5 >= 48 && cp5 <= 55;
|
|
1798
2194
|
}
|
|
1799
2195
|
};
|
|
1800
2196
|
},
|
|
@@ -5844,15 +6240,15 @@ var require_esprima = __commonJS({
|
|
|
5844
6240
|
}
|
|
5845
6241
|
};
|
|
5846
6242
|
Scanner2.prototype.codePointAt = function(i) {
|
|
5847
|
-
var
|
|
5848
|
-
if (
|
|
6243
|
+
var cp5 = this.source.charCodeAt(i);
|
|
6244
|
+
if (cp5 >= 55296 && cp5 <= 56319) {
|
|
5849
6245
|
var second = this.source.charCodeAt(i + 1);
|
|
5850
6246
|
if (second >= 56320 && second <= 57343) {
|
|
5851
|
-
var first =
|
|
5852
|
-
|
|
6247
|
+
var first = cp5;
|
|
6248
|
+
cp5 = (first - 55296) * 1024 + second - 56320 + 65536;
|
|
5853
6249
|
}
|
|
5854
6250
|
}
|
|
5855
|
-
return
|
|
6251
|
+
return cp5;
|
|
5856
6252
|
};
|
|
5857
6253
|
Scanner2.prototype.scanHexEscape = function(prefix) {
|
|
5858
6254
|
var len = prefix === "u" ? 4 : 2;
|
|
@@ -5904,11 +6300,11 @@ var require_esprima = __commonJS({
|
|
|
5904
6300
|
return this.source.slice(start, this.index);
|
|
5905
6301
|
};
|
|
5906
6302
|
Scanner2.prototype.getComplexIdentifier = function() {
|
|
5907
|
-
var
|
|
5908
|
-
var id = character_1.Character.fromCodePoint(
|
|
6303
|
+
var cp5 = this.codePointAt(this.index);
|
|
6304
|
+
var id = character_1.Character.fromCodePoint(cp5);
|
|
5909
6305
|
this.index += id.length;
|
|
5910
6306
|
var ch;
|
|
5911
|
-
if (
|
|
6307
|
+
if (cp5 === 92) {
|
|
5912
6308
|
if (this.source.charCodeAt(this.index) !== 117) {
|
|
5913
6309
|
this.throwUnexpectedToken();
|
|
5914
6310
|
}
|
|
@@ -5925,14 +6321,14 @@ var require_esprima = __commonJS({
|
|
|
5925
6321
|
id = ch;
|
|
5926
6322
|
}
|
|
5927
6323
|
while (!this.eof()) {
|
|
5928
|
-
|
|
5929
|
-
if (!character_1.Character.isIdentifierPart(
|
|
6324
|
+
cp5 = this.codePointAt(this.index);
|
|
6325
|
+
if (!character_1.Character.isIdentifierPart(cp5)) {
|
|
5930
6326
|
break;
|
|
5931
6327
|
}
|
|
5932
|
-
ch = character_1.Character.fromCodePoint(
|
|
6328
|
+
ch = character_1.Character.fromCodePoint(cp5);
|
|
5933
6329
|
id += ch;
|
|
5934
6330
|
this.index += ch.length;
|
|
5935
|
-
if (
|
|
6331
|
+
if (cp5 === 92) {
|
|
5936
6332
|
id = id.substr(0, id.length - 1);
|
|
5937
6333
|
if (this.source.charCodeAt(this.index) !== 117) {
|
|
5938
6334
|
this.throwUnexpectedToken();
|
|
@@ -6558,29 +6954,29 @@ var require_esprima = __commonJS({
|
|
|
6558
6954
|
end: this.index
|
|
6559
6955
|
};
|
|
6560
6956
|
}
|
|
6561
|
-
var
|
|
6562
|
-
if (character_1.Character.isIdentifierStart(
|
|
6957
|
+
var cp5 = this.source.charCodeAt(this.index);
|
|
6958
|
+
if (character_1.Character.isIdentifierStart(cp5)) {
|
|
6563
6959
|
return this.scanIdentifier();
|
|
6564
6960
|
}
|
|
6565
|
-
if (
|
|
6961
|
+
if (cp5 === 40 || cp5 === 41 || cp5 === 59) {
|
|
6566
6962
|
return this.scanPunctuator();
|
|
6567
6963
|
}
|
|
6568
|
-
if (
|
|
6964
|
+
if (cp5 === 39 || cp5 === 34) {
|
|
6569
6965
|
return this.scanStringLiteral();
|
|
6570
6966
|
}
|
|
6571
|
-
if (
|
|
6967
|
+
if (cp5 === 46) {
|
|
6572
6968
|
if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) {
|
|
6573
6969
|
return this.scanNumericLiteral();
|
|
6574
6970
|
}
|
|
6575
6971
|
return this.scanPunctuator();
|
|
6576
6972
|
}
|
|
6577
|
-
if (character_1.Character.isDecimalDigit(
|
|
6973
|
+
if (character_1.Character.isDecimalDigit(cp5)) {
|
|
6578
6974
|
return this.scanNumericLiteral();
|
|
6579
6975
|
}
|
|
6580
|
-
if (
|
|
6976
|
+
if (cp5 === 96 || cp5 === 125 && this.curlyStack[this.curlyStack.length - 1] === "${") {
|
|
6581
6977
|
return this.scanTemplate();
|
|
6582
6978
|
}
|
|
6583
|
-
if (
|
|
6979
|
+
if (cp5 >= 55296 && cp5 < 57343) {
|
|
6584
6980
|
if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) {
|
|
6585
6981
|
return this.scanIdentifier();
|
|
6586
6982
|
}
|
|
@@ -8758,10 +9154,10 @@ var require_stringify = __commonJS({
|
|
|
8758
9154
|
replacer = null;
|
|
8759
9155
|
indent = EMPTY;
|
|
8760
9156
|
};
|
|
8761
|
-
var
|
|
9157
|
+
var join15 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + LF + gap : two ? two.trimRight() + LF + gap : EMPTY;
|
|
8762
9158
|
var join_content = (inside, value, gap) => {
|
|
8763
9159
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
8764
|
-
return
|
|
9160
|
+
return join15(comment, inside, gap);
|
|
8765
9161
|
};
|
|
8766
9162
|
var array_stringify = (value, gap) => {
|
|
8767
9163
|
const deeper_gap = gap + indent;
|
|
@@ -8772,7 +9168,7 @@ var require_stringify = __commonJS({
|
|
|
8772
9168
|
if (i !== 0) {
|
|
8773
9169
|
inside += COMMA;
|
|
8774
9170
|
}
|
|
8775
|
-
const before =
|
|
9171
|
+
const before = join15(
|
|
8776
9172
|
after_comma,
|
|
8777
9173
|
process_comments(value, BEFORE(i), deeper_gap),
|
|
8778
9174
|
deeper_gap
|
|
@@ -8782,7 +9178,7 @@ var require_stringify = __commonJS({
|
|
|
8782
9178
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
8783
9179
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
8784
9180
|
}
|
|
8785
|
-
inside +=
|
|
9181
|
+
inside += join15(
|
|
8786
9182
|
after_comma,
|
|
8787
9183
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
8788
9184
|
deeper_gap
|
|
@@ -8807,7 +9203,7 @@ var require_stringify = __commonJS({
|
|
|
8807
9203
|
inside += COMMA;
|
|
8808
9204
|
}
|
|
8809
9205
|
first = false;
|
|
8810
|
-
const before =
|
|
9206
|
+
const before = join15(
|
|
8811
9207
|
after_comma,
|
|
8812
9208
|
process_comments(value, BEFORE(key2), deeper_gap),
|
|
8813
9209
|
deeper_gap
|
|
@@ -8817,7 +9213,7 @@ var require_stringify = __commonJS({
|
|
|
8817
9213
|
after_comma = process_comments(value, AFTER(key2), deeper_gap);
|
|
8818
9214
|
};
|
|
8819
9215
|
keys.forEach(iteratee);
|
|
8820
|
-
inside +=
|
|
9216
|
+
inside += join15(
|
|
8821
9217
|
after_comma,
|
|
8822
9218
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
8823
9219
|
deeper_gap
|
|
@@ -10195,7 +10591,7 @@ var require_pend = __commonJS({
|
|
|
10195
10591
|
// ../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/fd-slicer.js
|
|
10196
10592
|
var require_fd_slicer = __commonJS({
|
|
10197
10593
|
"../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/fd-slicer.js"(exports$1) {
|
|
10198
|
-
var
|
|
10594
|
+
var fs19 = __require("fs");
|
|
10199
10595
|
var util2 = __require("util");
|
|
10200
10596
|
var stream = __require("stream");
|
|
10201
10597
|
var Readable = stream.Readable;
|
|
@@ -10220,7 +10616,7 @@ var require_fd_slicer = __commonJS({
|
|
|
10220
10616
|
FdSlicer.prototype.read = function(buffer2, offset, length, position, callback) {
|
|
10221
10617
|
var self = this;
|
|
10222
10618
|
self.pend.go(function(cb) {
|
|
10223
|
-
|
|
10619
|
+
fs19.read(self.fd, buffer2, offset, length, position, function(err, bytesRead, buffer3) {
|
|
10224
10620
|
cb();
|
|
10225
10621
|
callback(err, bytesRead, buffer3);
|
|
10226
10622
|
});
|
|
@@ -10229,7 +10625,7 @@ var require_fd_slicer = __commonJS({
|
|
|
10229
10625
|
FdSlicer.prototype.write = function(buffer2, offset, length, position, callback) {
|
|
10230
10626
|
var self = this;
|
|
10231
10627
|
self.pend.go(function(cb) {
|
|
10232
|
-
|
|
10628
|
+
fs19.write(self.fd, buffer2, offset, length, position, function(err, written, buffer3) {
|
|
10233
10629
|
cb();
|
|
10234
10630
|
callback(err, written, buffer3);
|
|
10235
10631
|
});
|
|
@@ -10250,7 +10646,7 @@ var require_fd_slicer = __commonJS({
|
|
|
10250
10646
|
if (self.refCount > 0) return;
|
|
10251
10647
|
if (self.refCount < 0) throw new Error("invalid unref");
|
|
10252
10648
|
if (self.autoClose) {
|
|
10253
|
-
|
|
10649
|
+
fs19.close(self.fd, onCloseDone);
|
|
10254
10650
|
}
|
|
10255
10651
|
function onCloseDone(err) {
|
|
10256
10652
|
if (err) {
|
|
@@ -10287,7 +10683,7 @@ var require_fd_slicer = __commonJS({
|
|
|
10287
10683
|
self.context.pend.go(function(cb) {
|
|
10288
10684
|
if (self.destroyed) return cb();
|
|
10289
10685
|
var buffer2 = Buffer.allocUnsafe(toRead);
|
|
10290
|
-
|
|
10686
|
+
fs19.read(self.context.fd, buffer2, 0, toRead, self.pos, function(err, bytesRead) {
|
|
10291
10687
|
if (err) {
|
|
10292
10688
|
self.destroy(err);
|
|
10293
10689
|
} else if (bytesRead === 0) {
|
|
@@ -10334,7 +10730,7 @@ var require_fd_slicer = __commonJS({
|
|
|
10334
10730
|
}
|
|
10335
10731
|
self.context.pend.go(function(cb) {
|
|
10336
10732
|
if (self.destroyed) return cb();
|
|
10337
|
-
|
|
10733
|
+
fs19.write(self.context.fd, buffer2, 0, buffer2.length, self.pos, function(err2, bytes) {
|
|
10338
10734
|
if (err2) {
|
|
10339
10735
|
self.destroy();
|
|
10340
10736
|
cb();
|
|
@@ -10772,7 +11168,7 @@ var require_buffer_crc32 = __commonJS({
|
|
|
10772
11168
|
// ../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/index.js
|
|
10773
11169
|
var require_yauzl = __commonJS({
|
|
10774
11170
|
"../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/index.js"(exports$1) {
|
|
10775
|
-
var
|
|
11171
|
+
var fs19 = __require("fs");
|
|
10776
11172
|
var zlib = __require("zlib");
|
|
10777
11173
|
var fd_slicer = require_fd_slicer();
|
|
10778
11174
|
var crc32 = require_buffer_crc32();
|
|
@@ -10793,7 +11189,7 @@ var require_yauzl = __commonJS({
|
|
|
10793
11189
|
exports$1.Entry = Entry;
|
|
10794
11190
|
exports$1.LocalFileHeader = LocalFileHeader;
|
|
10795
11191
|
exports$1.RandomAccessReader = RandomAccessReader;
|
|
10796
|
-
function open2(
|
|
11192
|
+
function open2(path15, options2, callback) {
|
|
10797
11193
|
if (typeof options2 === "function") {
|
|
10798
11194
|
callback = options2;
|
|
10799
11195
|
options2 = null;
|
|
@@ -10805,10 +11201,10 @@ var require_yauzl = __commonJS({
|
|
|
10805
11201
|
if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
|
|
10806
11202
|
if (options2.strictFileNames == null) options2.strictFileNames = false;
|
|
10807
11203
|
if (callback == null) callback = defaultCallback;
|
|
10808
|
-
|
|
11204
|
+
fs19.open(path15, "r", function(err, fd) {
|
|
10809
11205
|
if (err) return callback(err);
|
|
10810
11206
|
fromFd(fd, options2, function(err2, zipfile) {
|
|
10811
|
-
if (err2)
|
|
11207
|
+
if (err2) fs19.close(fd, defaultCallback);
|
|
10812
11208
|
callback(err2, zipfile);
|
|
10813
11209
|
});
|
|
10814
11210
|
});
|
|
@@ -10825,7 +11221,7 @@ var require_yauzl = __commonJS({
|
|
|
10825
11221
|
if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
|
|
10826
11222
|
if (options2.strictFileNames == null) options2.strictFileNames = false;
|
|
10827
11223
|
if (callback == null) callback = defaultCallback;
|
|
10828
|
-
|
|
11224
|
+
fs19.fstat(fd, function(err, stats) {
|
|
10829
11225
|
if (err) return callback(err);
|
|
10830
11226
|
var reader = fd_slicer.createFromFd(fd, { autoClose: true });
|
|
10831
11227
|
fromRandomAccessReader(reader, stats.size, options2, callback);
|
|
@@ -11523,12 +11919,12 @@ var init_fileUtils = __esm({
|
|
|
11523
11919
|
zipfile.readEntry();
|
|
11524
11920
|
zipfile.on("entry", (entry) => {
|
|
11525
11921
|
if (/\/$/.test(entry.fileName)) {
|
|
11526
|
-
void
|
|
11922
|
+
void fs12.mkdir(path11.join(dest, entry.fileName), { recursive: true }).then(() => {
|
|
11527
11923
|
zipfile.readEntry();
|
|
11528
11924
|
}).catch(reject);
|
|
11529
11925
|
} else {
|
|
11530
|
-
const outputPath =
|
|
11531
|
-
void
|
|
11926
|
+
const outputPath = path11.join(dest, entry.fileName);
|
|
11927
|
+
void fs12.mkdir(path11.dirname(outputPath), { recursive: true }).then(() => {
|
|
11532
11928
|
zipfile.openReadStream(
|
|
11533
11929
|
entry,
|
|
11534
11930
|
(streamError, readStream) => {
|
|
@@ -11537,7 +11933,7 @@ var init_fileUtils = __esm({
|
|
|
11537
11933
|
return reject(
|
|
11538
11934
|
new Error("Failed to open zip entry stream.")
|
|
11539
11935
|
);
|
|
11540
|
-
const writeStream =
|
|
11936
|
+
const writeStream = fs9.createWriteStream(outputPath);
|
|
11541
11937
|
readStream.on("error", reject);
|
|
11542
11938
|
writeStream.on("error", reject);
|
|
11543
11939
|
writeStream.on("close", () => {
|
|
@@ -11561,58 +11957,58 @@ var init_fileUtils = __esm({
|
|
|
11561
11957
|
};
|
|
11562
11958
|
tryLstat = async (targetPath) => {
|
|
11563
11959
|
try {
|
|
11564
|
-
return await
|
|
11960
|
+
return await fs12.lstat(targetPath);
|
|
11565
11961
|
} catch {
|
|
11566
11962
|
return null;
|
|
11567
11963
|
}
|
|
11568
11964
|
};
|
|
11569
11965
|
mergeEntry = async (sourcePath, destPath, overwrite) => {
|
|
11570
|
-
const sourceStat = await
|
|
11966
|
+
const sourceStat = await fs12.lstat(sourcePath);
|
|
11571
11967
|
const destStat = await tryLstat(destPath);
|
|
11572
11968
|
if (sourceStat.isDirectory()) {
|
|
11573
11969
|
if (destStat && !destStat.isDirectory()) {
|
|
11574
11970
|
if (!overwrite) {
|
|
11575
|
-
await
|
|
11971
|
+
await fs12.rm(sourcePath, { recursive: true, force: true });
|
|
11576
11972
|
return;
|
|
11577
11973
|
}
|
|
11578
|
-
await
|
|
11974
|
+
await fs12.rm(destPath, { recursive: true, force: true });
|
|
11579
11975
|
}
|
|
11580
|
-
await
|
|
11581
|
-
const children = await
|
|
11976
|
+
await fs12.mkdir(destPath, { recursive: true });
|
|
11977
|
+
const children = await fs12.readdir(sourcePath);
|
|
11582
11978
|
for (const child of children) {
|
|
11583
11979
|
await mergeEntry(
|
|
11584
|
-
|
|
11585
|
-
|
|
11980
|
+
path11.join(sourcePath, child),
|
|
11981
|
+
path11.join(destPath, child),
|
|
11586
11982
|
overwrite
|
|
11587
11983
|
);
|
|
11588
11984
|
}
|
|
11589
|
-
await
|
|
11985
|
+
await fs12.rm(sourcePath, { recursive: true, force: true });
|
|
11590
11986
|
return;
|
|
11591
11987
|
}
|
|
11592
11988
|
if (destStat) {
|
|
11593
11989
|
if (!overwrite) {
|
|
11594
|
-
await
|
|
11990
|
+
await fs12.rm(sourcePath, { recursive: true, force: true });
|
|
11595
11991
|
return;
|
|
11596
11992
|
}
|
|
11597
|
-
await
|
|
11993
|
+
await fs12.rm(destPath, { recursive: true, force: true });
|
|
11598
11994
|
}
|
|
11599
11995
|
try {
|
|
11600
|
-
await
|
|
11996
|
+
await fs12.rename(sourcePath, destPath);
|
|
11601
11997
|
} catch {
|
|
11602
|
-
await
|
|
11603
|
-
await
|
|
11998
|
+
await fs12.copyFile(sourcePath, destPath);
|
|
11999
|
+
await fs12.rm(sourcePath, { recursive: true, force: true });
|
|
11604
12000
|
}
|
|
11605
12001
|
};
|
|
11606
12002
|
moveFiles = async (sourceDir, destDir, overwrite = false) => {
|
|
11607
|
-
await
|
|
11608
|
-
const files = await
|
|
12003
|
+
await fs12.mkdir(destDir, { recursive: true });
|
|
12004
|
+
const files = await fs12.readdir(sourceDir);
|
|
11609
12005
|
for (const file of files) {
|
|
11610
|
-
const sourceFile =
|
|
11611
|
-
const destFile =
|
|
12006
|
+
const sourceFile = path11.join(sourceDir, file);
|
|
12007
|
+
const destFile = path11.join(destDir, file);
|
|
11612
12008
|
if (!overwrite) {
|
|
11613
12009
|
try {
|
|
11614
|
-
await
|
|
11615
|
-
await
|
|
12010
|
+
await fs12.access(destFile, fs9.constants.F_OK);
|
|
12011
|
+
await fs12.rm(sourceFile, { recursive: true, force: true });
|
|
11616
12012
|
continue;
|
|
11617
12013
|
} catch {
|
|
11618
12014
|
}
|
|
@@ -11634,10 +12030,10 @@ var init_projectTools = __esm({
|
|
|
11634
12030
|
ProjectTools = class {
|
|
11635
12031
|
async extractTemplate(zipPath, workspacePath, tempExtractDir, input) {
|
|
11636
12032
|
await unzipFile(zipPath, tempExtractDir);
|
|
11637
|
-
let sourceDir =
|
|
12033
|
+
let sourceDir = path11__namespace.join(tempExtractDir, input.extractedDirName);
|
|
11638
12034
|
let actualDirName = input.extractedDirName;
|
|
11639
12035
|
if (!await this.pathExists(sourceDir)) {
|
|
11640
|
-
const entries = await
|
|
12036
|
+
const entries = await fs12__namespace.readdir(tempExtractDir, { withFileTypes: true });
|
|
11641
12037
|
const directories = entries.filter(
|
|
11642
12038
|
(entry) => entry.isDirectory() && !entry.name.startsWith(".")
|
|
11643
12039
|
);
|
|
@@ -11649,7 +12045,7 @@ var init_projectTools = __esm({
|
|
|
11649
12045
|
);
|
|
11650
12046
|
if (selectedDirectory) {
|
|
11651
12047
|
actualDirName = selectedDirectory;
|
|
11652
|
-
sourceDir =
|
|
12048
|
+
sourceDir = path11__namespace.join(tempExtractDir, actualDirName);
|
|
11653
12049
|
} else if (directories.length === 0) {
|
|
11654
12050
|
throw new Error(
|
|
11655
12051
|
`No directory found after extraction. Expected directory: ${input.extractedDirName}`
|
|
@@ -11707,7 +12103,7 @@ var init_projectTools = __esm({
|
|
|
11707
12103
|
} else {
|
|
11708
12104
|
for (const scriptPath of scripts) {
|
|
11709
12105
|
try {
|
|
11710
|
-
await
|
|
12106
|
+
await fs12__namespace.chmod(scriptPath, 493);
|
|
11711
12107
|
updatedCount += 1;
|
|
11712
12108
|
} catch {
|
|
11713
12109
|
}
|
|
@@ -11755,12 +12151,12 @@ var init_projectTools = __esm({
|
|
|
11755
12151
|
const results = [];
|
|
11756
12152
|
let entries;
|
|
11757
12153
|
try {
|
|
11758
|
-
entries = await
|
|
12154
|
+
entries = await fs12__namespace.readdir(dir, { withFileTypes: true });
|
|
11759
12155
|
} catch {
|
|
11760
12156
|
return results;
|
|
11761
12157
|
}
|
|
11762
12158
|
for (const entry of entries) {
|
|
11763
|
-
const fullPath =
|
|
12159
|
+
const fullPath = path11__namespace.join(dir, entry.name);
|
|
11764
12160
|
if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) {
|
|
11765
12161
|
results.push(...await this.findScripts(fullPath, extensions));
|
|
11766
12162
|
} else if (entry.isFile() && extensions.some((ext) => entry.name.endsWith(ext))) {
|
|
@@ -11771,7 +12167,7 @@ var init_projectTools = __esm({
|
|
|
11771
12167
|
}
|
|
11772
12168
|
async pathExists(targetPath) {
|
|
11773
12169
|
try {
|
|
11774
|
-
await
|
|
12170
|
+
await fs12__namespace.access(targetPath);
|
|
11775
12171
|
return true;
|
|
11776
12172
|
} catch {
|
|
11777
12173
|
return false;
|
|
@@ -11790,7 +12186,7 @@ var init_projectTools = __esm({
|
|
|
11790
12186
|
const matches = [];
|
|
11791
12187
|
for (const directoryName of directoryNames) {
|
|
11792
12188
|
if (await this.directoryMatchesProjectPattern(
|
|
11793
|
-
|
|
12189
|
+
path11__namespace.join(tempExtractDir, directoryName),
|
|
11794
12190
|
projectFilePattern
|
|
11795
12191
|
)) {
|
|
11796
12192
|
matches.push(directoryName);
|
|
@@ -11802,7 +12198,7 @@ var init_projectTools = __esm({
|
|
|
11802
12198
|
return null;
|
|
11803
12199
|
}
|
|
11804
12200
|
async directoryMatchesProjectPattern(directoryPath, projectFilePattern) {
|
|
11805
|
-
const entries = await
|
|
12201
|
+
const entries = await fs12__namespace.readdir(directoryPath);
|
|
11806
12202
|
if (projectFilePattern.includes("*")) {
|
|
11807
12203
|
const regex = new RegExp(`^${projectFilePattern.replace("*", ".*")}$`);
|
|
11808
12204
|
return entries.some((entry) => regex.test(entry));
|
|
@@ -11820,10 +12216,10 @@ var init_DaemonLogger = __esm({
|
|
|
11820
12216
|
MAX_LOG_SIZE = 1024 * 1024;
|
|
11821
12217
|
DaemonLogger = class {
|
|
11822
12218
|
constructor(workspacePath) {
|
|
11823
|
-
this.logPath =
|
|
11824
|
-
const dir =
|
|
11825
|
-
if (!
|
|
11826
|
-
|
|
12219
|
+
this.logPath = path11__namespace.join(workspacePath, CONFIG_DIR, LOG_FILE);
|
|
12220
|
+
const dir = path11__namespace.dirname(this.logPath);
|
|
12221
|
+
if (!fs9__namespace.existsSync(dir)) {
|
|
12222
|
+
fs9__namespace.mkdirSync(dir, { recursive: true });
|
|
11827
12223
|
}
|
|
11828
12224
|
}
|
|
11829
12225
|
getLogPath() {
|
|
@@ -11834,16 +12230,16 @@ var init_DaemonLogger = __esm({
|
|
|
11834
12230
|
const line2 = `[${ts}] [${level.toUpperCase()}] ${message}
|
|
11835
12231
|
`;
|
|
11836
12232
|
this.rotateIfNeeded();
|
|
11837
|
-
|
|
12233
|
+
fs9__namespace.appendFileSync(this.logPath, line2, "utf-8");
|
|
11838
12234
|
}
|
|
11839
12235
|
rotateIfNeeded() {
|
|
11840
12236
|
try {
|
|
11841
|
-
const stats =
|
|
12237
|
+
const stats = fs9__namespace.statSync(this.logPath);
|
|
11842
12238
|
if (stats.size > MAX_LOG_SIZE) {
|
|
11843
|
-
const content =
|
|
12239
|
+
const content = fs9__namespace.readFileSync(this.logPath, "utf-8");
|
|
11844
12240
|
const halfIdx = content.indexOf("\n", Math.floor(content.length / 2));
|
|
11845
12241
|
if (halfIdx > 0) {
|
|
11846
|
-
|
|
12242
|
+
fs9__namespace.writeFileSync(this.logPath, content.slice(halfIdx + 1), "utf-8");
|
|
11847
12243
|
}
|
|
11848
12244
|
}
|
|
11849
12245
|
} catch {
|
|
@@ -11859,27 +12255,27 @@ var init_PidManager = __esm({
|
|
|
11859
12255
|
PID_FILE = "scheduler.pid";
|
|
11860
12256
|
PidManager = class {
|
|
11861
12257
|
constructor(workspacePath) {
|
|
11862
|
-
this.pidPath =
|
|
12258
|
+
this.pidPath = path11__namespace.join(workspacePath, CONFIG_DIR2, PID_FILE);
|
|
11863
12259
|
}
|
|
11864
12260
|
getPidPath() {
|
|
11865
12261
|
return this.pidPath;
|
|
11866
12262
|
}
|
|
11867
12263
|
writePid(pid) {
|
|
11868
|
-
const dir =
|
|
11869
|
-
if (!
|
|
11870
|
-
|
|
12264
|
+
const dir = path11__namespace.dirname(this.pidPath);
|
|
12265
|
+
if (!fs9__namespace.existsSync(dir)) {
|
|
12266
|
+
fs9__namespace.mkdirSync(dir, { recursive: true });
|
|
11871
12267
|
}
|
|
11872
|
-
|
|
12268
|
+
fs9__namespace.writeFileSync(this.pidPath, String(pid), "utf-8");
|
|
11873
12269
|
}
|
|
11874
12270
|
readPid() {
|
|
11875
|
-
if (!
|
|
11876
|
-
const raw =
|
|
12271
|
+
if (!fs9__namespace.existsSync(this.pidPath)) return null;
|
|
12272
|
+
const raw = fs9__namespace.readFileSync(this.pidPath, "utf-8").trim();
|
|
11877
12273
|
const pid = Number.parseInt(raw, 10);
|
|
11878
12274
|
return Number.isNaN(pid) ? null : pid;
|
|
11879
12275
|
}
|
|
11880
12276
|
removePid() {
|
|
11881
|
-
if (
|
|
11882
|
-
|
|
12277
|
+
if (fs9__namespace.existsSync(this.pidPath)) {
|
|
12278
|
+
fs9__namespace.unlinkSync(this.pidPath);
|
|
11883
12279
|
}
|
|
11884
12280
|
}
|
|
11885
12281
|
isProcessRunning(pid) {
|
|
@@ -11934,11 +12330,35 @@ function redactArgs(args) {
|
|
|
11934
12330
|
function writeDiagnostic(message) {
|
|
11935
12331
|
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
11936
12332
|
if (logPath) {
|
|
11937
|
-
|
|
12333
|
+
fs9__namespace.appendFileSync(logPath, message);
|
|
11938
12334
|
return;
|
|
11939
12335
|
}
|
|
11940
12336
|
process.stderr.write(message);
|
|
11941
12337
|
}
|
|
12338
|
+
function resolveGithubCopilotCliExecution(payload) {
|
|
12339
|
+
const args = ["copilot", "prompt", "--prompt", payload.prompt];
|
|
12340
|
+
if (payload.autopilot) {
|
|
12341
|
+
args.push("--autopilot");
|
|
12342
|
+
}
|
|
12343
|
+
if (payload.allowTools && payload.allowTools.length > 0) {
|
|
12344
|
+
args.push("--allow-tools", payload.allowTools.join(","));
|
|
12345
|
+
}
|
|
12346
|
+
if (payload.model) {
|
|
12347
|
+
args.push("--model", payload.model);
|
|
12348
|
+
}
|
|
12349
|
+
if (payload.agent) {
|
|
12350
|
+
args.push("--agent", payload.agent);
|
|
12351
|
+
}
|
|
12352
|
+
args.push("--timeout", String(payload.timeout ?? 0));
|
|
12353
|
+
return {
|
|
12354
|
+
command: "serviceme",
|
|
12355
|
+
args,
|
|
12356
|
+
cwd: payload.workspace,
|
|
12357
|
+
timeoutMs: resolveConfiguredTimeoutMs(payload.timeout, DEFAULT_TIMEOUT_MS2),
|
|
12358
|
+
diagnosticArgs: redactArgs(args),
|
|
12359
|
+
promptLen: payload.prompt.length
|
|
12360
|
+
};
|
|
12361
|
+
}
|
|
11942
12362
|
var MAX_OUTPUT_BYTES, DEFAULT_TIMEOUT_MS2, GithubCopilotCliExecutor;
|
|
11943
12363
|
var init_GithubCopilotCliExecutor = __esm({
|
|
11944
12364
|
"../../packages/serviceme-core/src/scheduled-tasks/executors/GithubCopilotCliExecutor.ts"() {
|
|
@@ -11968,7 +12388,7 @@ var init_GithubCopilotCliExecutor = __esm({
|
|
|
11968
12388
|
}
|
|
11969
12389
|
executeStreaming(payload, onOutput, abortSignal) {
|
|
11970
12390
|
const p = payload;
|
|
11971
|
-
const
|
|
12391
|
+
const execution = resolveGithubCopilotCliExecution(p);
|
|
11972
12392
|
let resolve;
|
|
11973
12393
|
const resultPromise = new Promise((r) => {
|
|
11974
12394
|
resolve = r;
|
|
@@ -11990,26 +12410,12 @@ var init_GithubCopilotCliExecutor = __esm({
|
|
|
11990
12410
|
}
|
|
11991
12411
|
};
|
|
11992
12412
|
}
|
|
11993
|
-
const args = ["copilot", "prompt", "--prompt", p.prompt];
|
|
11994
|
-
if (p.autopilot) {
|
|
11995
|
-
args.push("--autopilot");
|
|
11996
|
-
}
|
|
11997
|
-
if (p.allowTools && p.allowTools.length > 0) {
|
|
11998
|
-
args.push("--allow-tools", p.allowTools.join(","));
|
|
11999
|
-
}
|
|
12000
|
-
if (p.model) {
|
|
12001
|
-
args.push("--model", p.model);
|
|
12002
|
-
}
|
|
12003
|
-
if (p.agent) {
|
|
12004
|
-
args.push("--agent", p.agent);
|
|
12005
|
-
}
|
|
12006
|
-
args.push("--timeout", String(p.timeout ?? 0));
|
|
12007
12413
|
writeDiagnostic(
|
|
12008
|
-
`[GithubCopilotCliExecutor] spawn: command
|
|
12414
|
+
`[GithubCopilotCliExecutor] spawn: command=${execution.command}, args=${JSON.stringify(execution.diagnosticArgs)}, promptLen=${execution.promptLen}, cwd=${execution.cwd ?? "(default)"}, platform=${process.platform}, windowsHide=true, pid=${process.pid}
|
|
12009
12415
|
`
|
|
12010
12416
|
);
|
|
12011
|
-
const child = child_process.spawn(
|
|
12012
|
-
cwd:
|
|
12417
|
+
const child = child_process.spawn(execution.command, execution.args, {
|
|
12418
|
+
cwd: execution.cwd,
|
|
12013
12419
|
stdio: ["ignore", "pipe", "pipe"],
|
|
12014
12420
|
windowsHide: true
|
|
12015
12421
|
});
|
|
@@ -12019,6 +12425,7 @@ var init_GithubCopilotCliExecutor = __esm({
|
|
|
12019
12425
|
`
|
|
12020
12426
|
);
|
|
12021
12427
|
}
|
|
12428
|
+
const timeoutMs = execution.timeoutMs;
|
|
12022
12429
|
const timer = timeoutMs != null ? setTimeout(() => {
|
|
12023
12430
|
child.kill("SIGTERM");
|
|
12024
12431
|
setTimeout(() => {
|
|
@@ -12148,7 +12555,7 @@ ${body}`.trim()
|
|
|
12148
12555
|
function resolveShellExecution(script, options2 = {}) {
|
|
12149
12556
|
const platform = options2.platform ?? process.platform;
|
|
12150
12557
|
const env = options2.env ?? process.env;
|
|
12151
|
-
const fileExists = options2.fileExists ??
|
|
12558
|
+
const fileExists = options2.fileExists ?? fs9__namespace.existsSync;
|
|
12152
12559
|
if (platform === "win32") {
|
|
12153
12560
|
const posixShell = usesPosixShellSyntax(script) ? findWindowsPosixShell(env, fileExists) : null;
|
|
12154
12561
|
if (posixShell) {
|
|
@@ -12193,10 +12600,10 @@ function findWindowsPosixShell(env, fileExists) {
|
|
|
12193
12600
|
if (fileExists(candidate)) return candidate;
|
|
12194
12601
|
}
|
|
12195
12602
|
const pathValue = env.Path ?? env.PATH ?? "";
|
|
12196
|
-
for (const dir of pathValue.split(
|
|
12603
|
+
for (const dir of pathValue.split(path11__namespace.win32.delimiter)) {
|
|
12197
12604
|
if (!dir) continue;
|
|
12198
12605
|
for (const executable of POSIX_SHELL_CANDIDATES) {
|
|
12199
|
-
const candidate =
|
|
12606
|
+
const candidate = path11__namespace.win32.join(dir, executable);
|
|
12200
12607
|
if (fileExists(candidate) && !isWindowsWslLauncher(candidate)) {
|
|
12201
12608
|
return candidate;
|
|
12202
12609
|
}
|
|
@@ -12205,13 +12612,13 @@ function findWindowsPosixShell(env, fileExists) {
|
|
|
12205
12612
|
return null;
|
|
12206
12613
|
}
|
|
12207
12614
|
function isWindowsWslLauncher(candidate) {
|
|
12208
|
-
const normalized =
|
|
12615
|
+
const normalized = path11__namespace.win32.normalize(candidate).toLowerCase();
|
|
12209
12616
|
return normalized.endsWith("\\windows\\system32\\bash.exe") || normalized.endsWith("\\windows\\syswow64\\bash.exe");
|
|
12210
12617
|
}
|
|
12211
12618
|
function writeDiagnostic2(message) {
|
|
12212
12619
|
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
12213
12620
|
if (logPath) {
|
|
12214
|
-
|
|
12621
|
+
fs9__namespace.appendFileSync(logPath, message);
|
|
12215
12622
|
return;
|
|
12216
12623
|
}
|
|
12217
12624
|
process.stderr.write(message);
|
|
@@ -12350,7 +12757,7 @@ var init_ShellExecutor = __esm({
|
|
|
12350
12757
|
function isStreamingTaskExecutor(executor) {
|
|
12351
12758
|
return "executeStreaming" in executor && typeof executor.executeStreaming === "function";
|
|
12352
12759
|
}
|
|
12353
|
-
var
|
|
12760
|
+
var init_types2 = __esm({
|
|
12354
12761
|
"../../packages/serviceme-core/src/scheduled-tasks/executors/types.ts"() {
|
|
12355
12762
|
}
|
|
12356
12763
|
});
|
|
@@ -12369,7 +12776,7 @@ var init_executors = __esm({
|
|
|
12369
12776
|
init_GithubCopilotCliExecutor();
|
|
12370
12777
|
init_HttpRequestExecutor();
|
|
12371
12778
|
init_ShellExecutor();
|
|
12372
|
-
|
|
12779
|
+
init_types2();
|
|
12373
12780
|
executors = {
|
|
12374
12781
|
shell: new ShellExecutor(),
|
|
12375
12782
|
http_request: new HttpRequestExecutor(),
|
|
@@ -12416,27 +12823,27 @@ var init_TaskConfigManager = __esm({
|
|
|
12416
12823
|
CONFIG_FILE = "scheduled-tasks.json";
|
|
12417
12824
|
TaskConfigManager = class {
|
|
12418
12825
|
constructor(workspacePath) {
|
|
12419
|
-
this.configPath =
|
|
12826
|
+
this.configPath = path11__namespace.join(workspacePath, CONFIG_DIR3, CONFIG_FILE);
|
|
12420
12827
|
}
|
|
12421
12828
|
getConfigPath() {
|
|
12422
12829
|
return this.configPath;
|
|
12423
12830
|
}
|
|
12424
12831
|
readConfig() {
|
|
12425
|
-
if (!
|
|
12832
|
+
if (!fs9__namespace.existsSync(this.configPath)) {
|
|
12426
12833
|
return emptyConfig();
|
|
12427
12834
|
}
|
|
12428
|
-
const raw =
|
|
12835
|
+
const raw = fs9__namespace.readFileSync(this.configPath, "utf-8");
|
|
12429
12836
|
const parsed = JSON.parse(raw);
|
|
12430
12837
|
return parsed;
|
|
12431
12838
|
}
|
|
12432
12839
|
writeConfig(config) {
|
|
12433
|
-
const dir =
|
|
12434
|
-
if (!
|
|
12435
|
-
|
|
12840
|
+
const dir = path11__namespace.dirname(this.configPath);
|
|
12841
|
+
if (!fs9__namespace.existsSync(dir)) {
|
|
12842
|
+
fs9__namespace.mkdirSync(dir, { recursive: true });
|
|
12436
12843
|
}
|
|
12437
12844
|
const tmp = `${this.configPath}.tmp`;
|
|
12438
|
-
|
|
12439
|
-
|
|
12845
|
+
fs9__namespace.writeFileSync(tmp, JSON.stringify(config, null, " "), "utf-8");
|
|
12846
|
+
fs9__namespace.renameSync(tmp, this.configPath);
|
|
12440
12847
|
}
|
|
12441
12848
|
listTasks() {
|
|
12442
12849
|
return this.readConfig().tasks;
|
|
@@ -12547,7 +12954,7 @@ function resolveTaskExecutionPayload(taskType, payload, workspacePath) {
|
|
|
12547
12954
|
var TaskExecutionEngine;
|
|
12548
12955
|
var init_TaskExecutionEngine = __esm({
|
|
12549
12956
|
"../../packages/serviceme-core/src/scheduled-tasks/TaskExecutionEngine.ts"() {
|
|
12550
|
-
|
|
12957
|
+
init_types2();
|
|
12551
12958
|
init_TaskConfigManager();
|
|
12552
12959
|
TaskExecutionEngine = class {
|
|
12553
12960
|
constructor(getExecutor2) {
|
|
@@ -12740,17 +13147,17 @@ var init_TaskLogManager = __esm({
|
|
|
12740
13147
|
MAX_LOGS = 200;
|
|
12741
13148
|
TaskLogManager = class {
|
|
12742
13149
|
constructor(workspacePath) {
|
|
12743
|
-
this.logPath =
|
|
13150
|
+
this.logPath = path11__namespace.join(workspacePath, CONFIG_DIR4, LOG_FILE2);
|
|
12744
13151
|
}
|
|
12745
13152
|
getLogPath() {
|
|
12746
13153
|
return this.logPath;
|
|
12747
13154
|
}
|
|
12748
13155
|
readLogFile() {
|
|
12749
|
-
if (!
|
|
13156
|
+
if (!fs9__namespace.existsSync(this.logPath)) {
|
|
12750
13157
|
return emptyLogFile();
|
|
12751
13158
|
}
|
|
12752
13159
|
try {
|
|
12753
|
-
const raw =
|
|
13160
|
+
const raw = fs9__namespace.readFileSync(this.logPath, "utf-8");
|
|
12754
13161
|
const parsed = JSON.parse(raw);
|
|
12755
13162
|
const file = validateAndRepairLogFile(parsed);
|
|
12756
13163
|
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.logs) || parsed.logs.length !== file.logs.length) {
|
|
@@ -12766,21 +13173,21 @@ var init_TaskLogManager = __esm({
|
|
|
12766
13173
|
}
|
|
12767
13174
|
backupCorruptedFile() {
|
|
12768
13175
|
try {
|
|
12769
|
-
if (
|
|
13176
|
+
if (fs9__namespace.existsSync(this.logPath)) {
|
|
12770
13177
|
const backupPath = `${this.logPath}.corrupted.${Date.now()}`;
|
|
12771
|
-
|
|
13178
|
+
fs9__namespace.copyFileSync(this.logPath, backupPath);
|
|
12772
13179
|
}
|
|
12773
13180
|
} catch {
|
|
12774
13181
|
}
|
|
12775
13182
|
}
|
|
12776
13183
|
writeLogFile(file) {
|
|
12777
|
-
const dir =
|
|
12778
|
-
if (!
|
|
12779
|
-
|
|
13184
|
+
const dir = path11__namespace.dirname(this.logPath);
|
|
13185
|
+
if (!fs9__namespace.existsSync(dir)) {
|
|
13186
|
+
fs9__namespace.mkdirSync(dir, { recursive: true });
|
|
12780
13187
|
}
|
|
12781
13188
|
const tmp = `${this.logPath}.tmp`;
|
|
12782
|
-
|
|
12783
|
-
|
|
13189
|
+
fs9__namespace.writeFileSync(tmp, JSON.stringify(file, null, " "), "utf-8");
|
|
13190
|
+
fs9__namespace.renameSync(tmp, this.logPath);
|
|
12784
13191
|
}
|
|
12785
13192
|
appendLog(input) {
|
|
12786
13193
|
const file = this.readLogFile();
|
|
@@ -12939,8 +13346,8 @@ var init_SchedulerDaemon = __esm({
|
|
|
12939
13346
|
const configPath = this.configManager.getConfigPath();
|
|
12940
13347
|
const dir = configPath.substring(0, configPath.lastIndexOf("/"));
|
|
12941
13348
|
try {
|
|
12942
|
-
if (
|
|
12943
|
-
this.watcher =
|
|
13349
|
+
if (fs9__namespace.existsSync(dir)) {
|
|
13350
|
+
this.watcher = fs9__namespace.watch(dir, (_eventType, filename) => {
|
|
12944
13351
|
if (filename === "scheduled-tasks.json") {
|
|
12945
13352
|
this.logger.log("info", "Config file changed, reconciling...");
|
|
12946
13353
|
}
|
|
@@ -13076,9 +13483,202 @@ var init_scheduled_tasks2 = __esm({
|
|
|
13076
13483
|
}
|
|
13077
13484
|
});
|
|
13078
13485
|
|
|
13486
|
+
// ../../packages/serviceme-core/src/skills/SkillCatalogClient.ts
|
|
13487
|
+
var SkillCatalogClient;
|
|
13488
|
+
var init_SkillCatalogClient = __esm({
|
|
13489
|
+
"../../packages/serviceme-core/src/skills/SkillCatalogClient.ts"() {
|
|
13490
|
+
SkillCatalogClient = class {
|
|
13491
|
+
constructor(options2 = {}) {
|
|
13492
|
+
this.fetchImpl = options2.fetchImpl ?? fetch;
|
|
13493
|
+
this.baseUrl = options2.baseUrl;
|
|
13494
|
+
}
|
|
13495
|
+
async getCatalog() {
|
|
13496
|
+
if (!this.baseUrl) {
|
|
13497
|
+
return {
|
|
13498
|
+
skills: [],
|
|
13499
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13500
|
+
};
|
|
13501
|
+
}
|
|
13502
|
+
const response = await this.fetchImpl(
|
|
13503
|
+
`${this.baseUrl}/api/v1/marketplace/skills`
|
|
13504
|
+
);
|
|
13505
|
+
if (!response.ok) {
|
|
13506
|
+
throw new Error(`Failed to fetch skills catalog: ${response.status}`);
|
|
13507
|
+
}
|
|
13508
|
+
const data = await response.json();
|
|
13509
|
+
return {
|
|
13510
|
+
skills: data.skills ?? [],
|
|
13511
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13512
|
+
};
|
|
13513
|
+
}
|
|
13514
|
+
};
|
|
13515
|
+
}
|
|
13516
|
+
});
|
|
13517
|
+
|
|
13518
|
+
// ../../packages/serviceme-core/src/skills/SkillReconciler.ts
|
|
13519
|
+
var SkillReconciler;
|
|
13520
|
+
var init_SkillReconciler = __esm({
|
|
13521
|
+
"../../packages/serviceme-core/src/skills/SkillReconciler.ts"() {
|
|
13522
|
+
SkillReconciler = class {
|
|
13523
|
+
constructor(deps) {
|
|
13524
|
+
this.deps = deps;
|
|
13525
|
+
}
|
|
13526
|
+
async mutate(request) {
|
|
13527
|
+
if (request.targetScope !== "workspace" && request.targetScope !== "user") {
|
|
13528
|
+
throw new Error(`Invalid target scope: ${String(request.targetScope)}`);
|
|
13529
|
+
}
|
|
13530
|
+
if (request.action === "uninstall" || request.action === "move" || request.action === "removeExternal") {
|
|
13531
|
+
return {
|
|
13532
|
+
status: "success",
|
|
13533
|
+
changed: true,
|
|
13534
|
+
message: `Skill ${request.action} completed.`
|
|
13535
|
+
};
|
|
13536
|
+
}
|
|
13537
|
+
if (request.action !== "install") {
|
|
13538
|
+
return {
|
|
13539
|
+
status: "blocked",
|
|
13540
|
+
changed: false,
|
|
13541
|
+
message: `Skill action is not supported by bridge reconciler: ${request.action}`
|
|
13542
|
+
};
|
|
13543
|
+
}
|
|
13544
|
+
const catalog = await this.deps.catalogClient.getCatalog();
|
|
13545
|
+
const remoteSkill = catalog.skills.find(
|
|
13546
|
+
(skill) => this.deps.skillStore.normalizeRemoteSkillId(skill.id) === request.skillId
|
|
13547
|
+
);
|
|
13548
|
+
if (!remoteSkill) {
|
|
13549
|
+
return {
|
|
13550
|
+
status: "blocked",
|
|
13551
|
+
changed: false,
|
|
13552
|
+
message: "Skill not found in catalog."
|
|
13553
|
+
};
|
|
13554
|
+
}
|
|
13555
|
+
if (!request.confirmed && (remoteSkill.hasScripts || remoteSkill.hasHooks)) {
|
|
13556
|
+
return {
|
|
13557
|
+
status: "requires_confirmation",
|
|
13558
|
+
changed: false,
|
|
13559
|
+
hasScripts: Boolean(remoteSkill.hasScripts),
|
|
13560
|
+
hasHooks: Boolean(remoteSkill.hasHooks),
|
|
13561
|
+
message: "This skill contains executable scripts that require confirmation."
|
|
13562
|
+
};
|
|
13563
|
+
}
|
|
13564
|
+
return {
|
|
13565
|
+
status: "success",
|
|
13566
|
+
changed: true,
|
|
13567
|
+
message: "Skill installed."
|
|
13568
|
+
};
|
|
13569
|
+
}
|
|
13570
|
+
};
|
|
13571
|
+
}
|
|
13572
|
+
});
|
|
13573
|
+
function assertSafeLocalSkillId(skillId) {
|
|
13574
|
+
if (typeof skillId !== "string" || skillId.length === 0 || skillId === "." || skillId === ".." || skillId.includes("/") || skillId.includes("\\") || !SAFE_LOCAL_ID_PATTERN2.test(skillId)) {
|
|
13575
|
+
throw new Error(`Invalid skill id: ${skillId}`);
|
|
13576
|
+
}
|
|
13577
|
+
return skillId;
|
|
13578
|
+
}
|
|
13579
|
+
var USER_SKILL_MARKER_FILE, WORKSPACE_SKILLS_ROOT_RELATIVE, WORKSPACE_SKILLS_MARKER_RELATIVE, SAFE_LOCAL_ID_PATTERN2, SkillStore;
|
|
13580
|
+
var init_SkillStore = __esm({
|
|
13581
|
+
"../../packages/serviceme-core/src/skills/SkillStore.ts"() {
|
|
13582
|
+
USER_SKILL_MARKER_FILE = ".ms-devtools-skill.json";
|
|
13583
|
+
WORKSPACE_SKILLS_ROOT_RELATIVE = ".github/skills";
|
|
13584
|
+
WORKSPACE_SKILLS_MARKER_RELATIVE = ".github/.ms-devtools-skills.yml";
|
|
13585
|
+
SAFE_LOCAL_ID_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
13586
|
+
SkillStore = class {
|
|
13587
|
+
constructor(options2) {
|
|
13588
|
+
this.workspacePath = options2.workspacePath;
|
|
13589
|
+
this.userSkillsRoot = options2.userSkillsRoot;
|
|
13590
|
+
this.fileSystem = options2.fileSystem ?? fs12__namespace;
|
|
13591
|
+
}
|
|
13592
|
+
normalizeRemoteSkillId(remoteId) {
|
|
13593
|
+
if (remoteId.startsWith("official/")) {
|
|
13594
|
+
return assertSafeLocalSkillId(remoteId.slice("official/".length));
|
|
13595
|
+
}
|
|
13596
|
+
if (remoteId.startsWith("community/")) {
|
|
13597
|
+
const lastSlash = remoteId.lastIndexOf("/");
|
|
13598
|
+
return assertSafeLocalSkillId(remoteId.slice(lastSlash + 1));
|
|
13599
|
+
}
|
|
13600
|
+
return assertSafeLocalSkillId(remoteId);
|
|
13601
|
+
}
|
|
13602
|
+
getWorkspaceSkillPath(skillId) {
|
|
13603
|
+
return `${WORKSPACE_SKILLS_ROOT_RELATIVE}/${skillId}`;
|
|
13604
|
+
}
|
|
13605
|
+
getWorkspaceMarkerPath() {
|
|
13606
|
+
return WORKSPACE_SKILLS_MARKER_RELATIVE;
|
|
13607
|
+
}
|
|
13608
|
+
getUserSkillPath(skillId) {
|
|
13609
|
+
return path11__namespace.join(this.userSkillsRoot, skillId);
|
|
13610
|
+
}
|
|
13611
|
+
async listWorkspaceSkillIds() {
|
|
13612
|
+
const skillsRootPath = path11__namespace.join(
|
|
13613
|
+
this.workspacePath,
|
|
13614
|
+
WORKSPACE_SKILLS_ROOT_RELATIVE
|
|
13615
|
+
);
|
|
13616
|
+
try {
|
|
13617
|
+
const entries = await this.fileSystem.readdir(skillsRootPath, {
|
|
13618
|
+
withFileTypes: true
|
|
13619
|
+
});
|
|
13620
|
+
return entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name).sort();
|
|
13621
|
+
} catch {
|
|
13622
|
+
return [];
|
|
13623
|
+
}
|
|
13624
|
+
}
|
|
13625
|
+
async listUserSkillIds() {
|
|
13626
|
+
try {
|
|
13627
|
+
const entries = await this.fileSystem.readdir(this.userSkillsRoot, {
|
|
13628
|
+
withFileTypes: true
|
|
13629
|
+
});
|
|
13630
|
+
return entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name).sort();
|
|
13631
|
+
} catch {
|
|
13632
|
+
return [];
|
|
13633
|
+
}
|
|
13634
|
+
}
|
|
13635
|
+
async writeManagedUserSkillMarker(skillId) {
|
|
13636
|
+
const targetDir = this.getUserSkillPath(skillId);
|
|
13637
|
+
await this.fileSystem.mkdir(targetDir, { recursive: true });
|
|
13638
|
+
await this.fileSystem.writeFile(
|
|
13639
|
+
path11__namespace.join(targetDir, USER_SKILL_MARKER_FILE),
|
|
13640
|
+
JSON.stringify({ skillId, installedBy: "ms-devtools" }, null, 2),
|
|
13641
|
+
"utf-8"
|
|
13642
|
+
);
|
|
13643
|
+
}
|
|
13644
|
+
async isManagedUserSkill(skillId) {
|
|
13645
|
+
try {
|
|
13646
|
+
const marker = await this.fileSystem.readFile(
|
|
13647
|
+
path11__namespace.join(this.getUserSkillPath(skillId), USER_SKILL_MARKER_FILE),
|
|
13648
|
+
"utf-8"
|
|
13649
|
+
);
|
|
13650
|
+
const parsed = JSON.parse(marker);
|
|
13651
|
+
return parsed.skillId === skillId;
|
|
13652
|
+
} catch {
|
|
13653
|
+
return false;
|
|
13654
|
+
}
|
|
13655
|
+
}
|
|
13656
|
+
};
|
|
13657
|
+
}
|
|
13658
|
+
});
|
|
13659
|
+
|
|
13660
|
+
// ../../packages/serviceme-core/src/skills/types.ts
|
|
13661
|
+
var init_types3 = __esm({
|
|
13662
|
+
"../../packages/serviceme-core/src/skills/types.ts"() {
|
|
13663
|
+
}
|
|
13664
|
+
});
|
|
13665
|
+
|
|
13666
|
+
// ../../packages/serviceme-core/src/skills/index.ts
|
|
13667
|
+
var init_skills = __esm({
|
|
13668
|
+
"../../packages/serviceme-core/src/skills/index.ts"() {
|
|
13669
|
+
init_SkillCatalogClient();
|
|
13670
|
+
init_SkillReconciler();
|
|
13671
|
+
init_SkillStore();
|
|
13672
|
+
init_types3();
|
|
13673
|
+
}
|
|
13674
|
+
});
|
|
13675
|
+
|
|
13079
13676
|
// ../../packages/serviceme-core/src/index.ts
|
|
13080
13677
|
var src_exports = {};
|
|
13081
13678
|
__export(src_exports, {
|
|
13679
|
+
AgentCatalogClient: () => AgentCatalogClient,
|
|
13680
|
+
AgentReconciler: () => AgentReconciler,
|
|
13681
|
+
AgentStore: () => AgentStore,
|
|
13082
13682
|
DaemonLogger: () => DaemonLogger,
|
|
13083
13683
|
EnvironmentInspector: () => EnvironmentInspector,
|
|
13084
13684
|
GithubCopilotCliExecutor: () => GithubCopilotCliExecutor,
|
|
@@ -13088,6 +13688,10 @@ __export(src_exports, {
|
|
|
13088
13688
|
ProjectTools: () => ProjectTools,
|
|
13089
13689
|
SchedulerDaemon: () => SchedulerDaemon,
|
|
13090
13690
|
ShellExecutor: () => ShellExecutor,
|
|
13691
|
+
SkillCatalogClient: () => SkillCatalogClient,
|
|
13692
|
+
SkillReconciler: () => SkillReconciler,
|
|
13693
|
+
SkillStore: () => SkillStore,
|
|
13694
|
+
TOOL_RISK_MAP: () => TOOL_RISK_MAP,
|
|
13091
13695
|
TaskConfigManager: () => TaskConfigManager,
|
|
13092
13696
|
TaskExecutionEngine: () => TaskExecutionEngine,
|
|
13093
13697
|
TaskLogManager: () => TaskLogManager,
|
|
@@ -13105,6 +13709,7 @@ __export(src_exports, {
|
|
|
13105
13709
|
matchesCron: () => matchesCron,
|
|
13106
13710
|
moveFiles: () => moveFiles,
|
|
13107
13711
|
noopLogger: () => noopLogger,
|
|
13712
|
+
parseAgentToolPermissions: () => parseAgentToolPermissions,
|
|
13108
13713
|
parseIntervalMs: () => parseIntervalMs,
|
|
13109
13714
|
resolveTaskExecutionPayload: () => resolveTaskExecutionPayload,
|
|
13110
13715
|
unzipFile: () => unzipFile,
|
|
@@ -13112,13 +13717,16 @@ __export(src_exports, {
|
|
|
13112
13717
|
});
|
|
13113
13718
|
var init_src2 = __esm({
|
|
13114
13719
|
"../../packages/serviceme-core/src/index.ts"() {
|
|
13720
|
+
init_agents();
|
|
13115
13721
|
init_copilot2();
|
|
13116
13722
|
init_environmentInspector();
|
|
13117
13723
|
init_imageTools();
|
|
13118
13724
|
init_jsonTools();
|
|
13119
13725
|
init_logger();
|
|
13726
|
+
init_permissions();
|
|
13120
13727
|
init_projectTools();
|
|
13121
13728
|
init_scheduled_tasks2();
|
|
13729
|
+
init_skills();
|
|
13122
13730
|
init_fileUtils();
|
|
13123
13731
|
}
|
|
13124
13732
|
});
|
|
@@ -13169,39 +13777,945 @@ function getStringFlag(parsed, name) {
|
|
|
13169
13777
|
return typeof value === "string" ? value : void 0;
|
|
13170
13778
|
}
|
|
13171
13779
|
|
|
13172
|
-
// src/commands/
|
|
13780
|
+
// src/commands/agent.ts
|
|
13173
13781
|
init_src2();
|
|
13174
|
-
|
|
13175
|
-
// src/bridge/BridgeServer.ts
|
|
13176
13782
|
init_src();
|
|
13177
13783
|
|
|
13178
|
-
// src/
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
// src/bridge/ndjson.ts
|
|
13183
|
-
function writeBridgeMessage(message) {
|
|
13184
|
-
process.stdout.write(`${JSON.stringify(message)}
|
|
13784
|
+
// src/output.ts
|
|
13785
|
+
init_src();
|
|
13786
|
+
function writeJson(value) {
|
|
13787
|
+
process.stdout.write(`${JSON.stringify(value)}
|
|
13185
13788
|
`);
|
|
13186
13789
|
}
|
|
13790
|
+
function writeSuccess(data) {
|
|
13791
|
+
writeJson(createCliSuccess(data));
|
|
13792
|
+
}
|
|
13793
|
+
function writeFailure(error) {
|
|
13794
|
+
writeJson(createCliFailure(normalizeServicemeError(error)));
|
|
13795
|
+
}
|
|
13187
13796
|
|
|
13188
|
-
// src/
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
}
|
|
13797
|
+
// src/commands/agent.ts
|
|
13798
|
+
function normalizeAgentIdOrThrow(store, remoteId) {
|
|
13799
|
+
try {
|
|
13800
|
+
return store.normalizeRemoteAgentId(remoteId);
|
|
13801
|
+
} catch {
|
|
13802
|
+
throw createServicemeError("invalid_params", `Invalid agent id: ${remoteId}`);
|
|
13803
|
+
}
|
|
13804
|
+
}
|
|
13805
|
+
async function runAgentCommand(parsed) {
|
|
13806
|
+
const action = parsed.positionals[1];
|
|
13807
|
+
const workspacePath = getStringFlag(parsed, "workspacePath");
|
|
13808
|
+
if (!workspacePath) {
|
|
13809
|
+
throw createServicemeError(
|
|
13810
|
+
"invalid_params",
|
|
13811
|
+
"Expected --workspacePath <path>."
|
|
13812
|
+
);
|
|
13813
|
+
}
|
|
13814
|
+
const store = new AgentStore({
|
|
13815
|
+
workspacePath,
|
|
13816
|
+
userAgentsRoot: path11__namespace.join(os__namespace.homedir(), ".copilot", "agents")
|
|
13817
|
+
});
|
|
13818
|
+
const catalogClient = new AgentCatalogClient({
|
|
13819
|
+
baseUrl: getStringFlag(parsed, "baseUrl")
|
|
13820
|
+
});
|
|
13821
|
+
const reconciler = new AgentReconciler({
|
|
13822
|
+
agentStore: store,
|
|
13823
|
+
catalogClient
|
|
13824
|
+
});
|
|
13825
|
+
switch (action) {
|
|
13826
|
+
case "list":
|
|
13827
|
+
writeSuccess(await handleList(store));
|
|
13828
|
+
return;
|
|
13829
|
+
case "install":
|
|
13830
|
+
writeSuccess(await handleInstall(store, parsed));
|
|
13831
|
+
return;
|
|
13832
|
+
case "uninstall":
|
|
13833
|
+
writeSuccess(await handleUninstall(store, workspacePath, parsed));
|
|
13834
|
+
return;
|
|
13835
|
+
case "move":
|
|
13836
|
+
writeSuccess(await handleMove(store, workspacePath, parsed));
|
|
13837
|
+
return;
|
|
13838
|
+
case "marketplace":
|
|
13839
|
+
writeSuccess(await handleMarketplace(store, catalogClient));
|
|
13840
|
+
return;
|
|
13841
|
+
case "permissions":
|
|
13842
|
+
writeSuccess(
|
|
13843
|
+
await handlePermissions(store, reconciler, workspacePath, parsed)
|
|
13844
|
+
);
|
|
13845
|
+
return;
|
|
13846
|
+
default:
|
|
13847
|
+
throw new Error(
|
|
13848
|
+
"Unsupported agent command. Use list, install, uninstall, move, marketplace, or permissions."
|
|
13849
|
+
);
|
|
13850
|
+
}
|
|
13851
|
+
}
|
|
13852
|
+
async function handleList(store) {
|
|
13853
|
+
const workspaceAgents = await store.listWorkspaceAgentIds();
|
|
13854
|
+
const userAgents = await store.listUserAgentIds();
|
|
13855
|
+
return {
|
|
13856
|
+
agents: [
|
|
13857
|
+
...workspaceAgents.map((id) => ({ id, scope: "workspace" })),
|
|
13858
|
+
...userAgents.map((id) => ({ id, scope: "user" }))
|
|
13859
|
+
]
|
|
13860
|
+
};
|
|
13861
|
+
}
|
|
13862
|
+
async function handleInstall(store, parsed) {
|
|
13863
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
13864
|
+
if (!remoteId) {
|
|
13865
|
+
throw createServicemeError(
|
|
13866
|
+
"invalid_params",
|
|
13867
|
+
"Expected --id <remoteAgentId>."
|
|
13868
|
+
);
|
|
13869
|
+
}
|
|
13870
|
+
const agentId = normalizeAgentIdOrThrow(store, remoteId);
|
|
13871
|
+
if (!getBooleanFlag(parsed, "confirmed")) {
|
|
13872
|
+
return {
|
|
13873
|
+
changed: false,
|
|
13874
|
+
scope: "workspace",
|
|
13875
|
+
agentId,
|
|
13876
|
+
status: "requires_confirmation",
|
|
13877
|
+
message: "Install requires --confirmed."
|
|
13878
|
+
};
|
|
13879
|
+
}
|
|
13880
|
+
const content = `---
|
|
13881
|
+
name: ${agentId}
|
|
13882
|
+
tools:
|
|
13883
|
+
- run_in_terminal
|
|
13884
|
+
- read_file
|
|
13885
|
+
---
|
|
13886
|
+
|
|
13887
|
+
# ${agentId}
|
|
13888
|
+
`;
|
|
13889
|
+
await store.writeAgentFiles(agentId, "workspace", [
|
|
13890
|
+
{
|
|
13891
|
+
path: `${agentId}.agent.md`,
|
|
13892
|
+
content
|
|
13893
|
+
}
|
|
13894
|
+
]);
|
|
13895
|
+
await store.addInstalledAgent({
|
|
13896
|
+
id: remoteId,
|
|
13897
|
+
name: agentId,
|
|
13898
|
+
scope: "workspace",
|
|
13899
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13900
|
+
});
|
|
13901
|
+
return {
|
|
13902
|
+
changed: true,
|
|
13903
|
+
scope: "workspace",
|
|
13904
|
+
agentId,
|
|
13905
|
+
status: "success"
|
|
13906
|
+
};
|
|
13907
|
+
}
|
|
13908
|
+
async function handleUninstall(store, workspacePath, parsed) {
|
|
13909
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
13910
|
+
if (!remoteId) {
|
|
13911
|
+
throw createServicemeError(
|
|
13912
|
+
"invalid_params",
|
|
13913
|
+
"Expected --id <remoteAgentId>."
|
|
13914
|
+
);
|
|
13915
|
+
}
|
|
13916
|
+
const agentId = normalizeAgentIdOrThrow(store, remoteId);
|
|
13917
|
+
await fs12__namespace.rm(
|
|
13918
|
+
path11__namespace.join(workspacePath, ".github", "agents", `${agentId}.agent.md`),
|
|
13919
|
+
{
|
|
13920
|
+
recursive: true,
|
|
13921
|
+
force: true
|
|
13922
|
+
}
|
|
13923
|
+
);
|
|
13924
|
+
await fs12__namespace.rm(path11__namespace.join(workspacePath, ".github", "agents", agentId), {
|
|
13925
|
+
recursive: true,
|
|
13926
|
+
force: true
|
|
13927
|
+
});
|
|
13928
|
+
await fs12__namespace.rm(path11__namespace.join(store.getUserAgentsRootPath(), `${agentId}.agent.md`), {
|
|
13929
|
+
recursive: true,
|
|
13930
|
+
force: true
|
|
13931
|
+
});
|
|
13932
|
+
await fs12__namespace.rm(path11__namespace.join(store.getUserAgentsRootPath(), agentId), {
|
|
13933
|
+
recursive: true,
|
|
13934
|
+
force: true
|
|
13935
|
+
});
|
|
13936
|
+
await store.removeInstalledAgent(remoteId);
|
|
13937
|
+
return {
|
|
13938
|
+
changed: true,
|
|
13939
|
+
agentId
|
|
13940
|
+
};
|
|
13941
|
+
}
|
|
13942
|
+
async function handleMove(store, workspacePath, parsed) {
|
|
13943
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
13944
|
+
const to = getStringFlag(parsed, "to");
|
|
13945
|
+
if (!remoteId || !to) {
|
|
13946
|
+
throw createServicemeError(
|
|
13947
|
+
"invalid_params",
|
|
13948
|
+
"Expected --id <remoteAgentId> and --to <workspace|user>."
|
|
13949
|
+
);
|
|
13950
|
+
}
|
|
13951
|
+
if (to !== "workspace" && to !== "user") {
|
|
13952
|
+
throw createServicemeError(
|
|
13953
|
+
"invalid_params",
|
|
13954
|
+
"Expected --to value to be workspace or user."
|
|
13955
|
+
);
|
|
13956
|
+
}
|
|
13957
|
+
const agentId = normalizeAgentIdOrThrow(store, remoteId);
|
|
13958
|
+
const workspaceFlatPath = path11__namespace.join(
|
|
13959
|
+
workspacePath,
|
|
13960
|
+
".github",
|
|
13961
|
+
"agents",
|
|
13962
|
+
`${agentId}.agent.md`
|
|
13963
|
+
);
|
|
13964
|
+
const userFlatPath = path11__namespace.join(
|
|
13965
|
+
store.getUserAgentsRootPath(),
|
|
13966
|
+
`${agentId}.agent.md`
|
|
13967
|
+
);
|
|
13968
|
+
if (to === "user") {
|
|
13969
|
+
await moveEntry(workspaceFlatPath, userFlatPath);
|
|
13970
|
+
return {
|
|
13971
|
+
changed: true,
|
|
13972
|
+
fromScope: "workspace",
|
|
13973
|
+
toScope: "user",
|
|
13974
|
+
agentId
|
|
13975
|
+
};
|
|
13976
|
+
}
|
|
13977
|
+
await moveEntry(userFlatPath, workspaceFlatPath);
|
|
13978
|
+
return {
|
|
13979
|
+
changed: true,
|
|
13980
|
+
fromScope: "user",
|
|
13981
|
+
toScope: "workspace",
|
|
13982
|
+
agentId
|
|
13983
|
+
};
|
|
13984
|
+
}
|
|
13985
|
+
async function handleMarketplace(store, catalogClient) {
|
|
13986
|
+
const [catalog, workspaceAgentIds, userAgentIds] = await Promise.all([
|
|
13987
|
+
catalogClient.getCatalog(),
|
|
13988
|
+
store.listWorkspaceAgentIds(),
|
|
13989
|
+
store.listUserAgentIds()
|
|
13990
|
+
]);
|
|
13991
|
+
const scopesById = /* @__PURE__ */ new Map();
|
|
13992
|
+
for (const agentId of workspaceAgentIds) {
|
|
13993
|
+
scopesById.set(agentId, ["workspace"]);
|
|
13994
|
+
}
|
|
13995
|
+
for (const agentId of userAgentIds) {
|
|
13996
|
+
const existing = scopesById.get(agentId);
|
|
13997
|
+
if (existing) {
|
|
13998
|
+
existing.push("user");
|
|
13999
|
+
} else {
|
|
14000
|
+
scopesById.set(agentId, ["user"]);
|
|
14001
|
+
}
|
|
14002
|
+
}
|
|
14003
|
+
const merged = /* @__PURE__ */ new Map();
|
|
14004
|
+
for (const agent of catalog.agents) {
|
|
14005
|
+
const normalizedId = normalizeAgentIdOrThrow(store, agent.id);
|
|
14006
|
+
merged.set(normalizedId, {
|
|
14007
|
+
id: normalizedId,
|
|
14008
|
+
displayName: agent.displayName,
|
|
14009
|
+
description: agent.description,
|
|
14010
|
+
source: "catalog",
|
|
14011
|
+
scopes: scopesById.get(normalizedId) ?? []
|
|
14012
|
+
});
|
|
14013
|
+
}
|
|
14014
|
+
for (const [agentId, scopes] of scopesById) {
|
|
14015
|
+
if (merged.has(agentId)) {
|
|
14016
|
+
continue;
|
|
14017
|
+
}
|
|
14018
|
+
merged.set(agentId, {
|
|
14019
|
+
id: agentId,
|
|
14020
|
+
displayName: agentId,
|
|
14021
|
+
description: "Local installed agent",
|
|
14022
|
+
source: "local",
|
|
14023
|
+
scopes
|
|
14024
|
+
});
|
|
14025
|
+
}
|
|
14026
|
+
return {
|
|
14027
|
+
agents: [...merged.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
14028
|
+
fetchedAt: catalog.fetchedAt
|
|
14029
|
+
};
|
|
14030
|
+
}
|
|
14031
|
+
async function handlePermissions(store, reconciler, workspacePath, parsed) {
|
|
14032
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
14033
|
+
const scopeFlag = getStringFlag(parsed, "scope");
|
|
14034
|
+
if (!remoteId) {
|
|
14035
|
+
throw createServicemeError(
|
|
14036
|
+
"invalid_params",
|
|
14037
|
+
"Expected --id <remoteAgentId>."
|
|
14038
|
+
);
|
|
14039
|
+
}
|
|
14040
|
+
if (scopeFlag !== void 0 && scopeFlag !== "workspace" && scopeFlag !== "user") {
|
|
14041
|
+
throw createServicemeError(
|
|
14042
|
+
"invalid_params",
|
|
14043
|
+
"Expected --scope value to be workspace or user."
|
|
14044
|
+
);
|
|
14045
|
+
}
|
|
14046
|
+
const agentId = normalizeAgentIdOrThrow(store, remoteId);
|
|
14047
|
+
const requestedScope = scopeFlag ?? "workspace";
|
|
14048
|
+
const scope = requestedScope;
|
|
14049
|
+
const content = await readAgentContent(store, workspacePath, agentId, scope);
|
|
14050
|
+
const summary = reconciler.getPermissionSummary(agentId, agentId, content);
|
|
14051
|
+
return {
|
|
14052
|
+
agentId,
|
|
14053
|
+
scope,
|
|
14054
|
+
summary
|
|
14055
|
+
};
|
|
14056
|
+
}
|
|
14057
|
+
async function moveEntry(fromPath, toPath) {
|
|
14058
|
+
await fs12__namespace.mkdir(path11__namespace.dirname(toPath), { recursive: true });
|
|
14059
|
+
try {
|
|
14060
|
+
await fs12__namespace.rename(fromPath, toPath);
|
|
14061
|
+
} catch {
|
|
14062
|
+
await fs12__namespace.cp(fromPath, toPath, { recursive: true });
|
|
14063
|
+
await fs12__namespace.rm(fromPath, { recursive: true, force: true });
|
|
14064
|
+
}
|
|
14065
|
+
}
|
|
14066
|
+
async function readAgentContent(store, workspacePath, agentId, scope) {
|
|
14067
|
+
const root2 = scope === "workspace" ? path11__namespace.join(workspacePath, store.getWorkspaceAgentsRootPath()) : store.getUserAgentsRootPath();
|
|
14068
|
+
const candidates = [
|
|
14069
|
+
path11__namespace.join(root2, `${agentId}.agent.md`),
|
|
14070
|
+
path11__namespace.join(root2, agentId, `${agentId}.agent.md`)
|
|
14071
|
+
];
|
|
14072
|
+
for (const candidate of candidates) {
|
|
14073
|
+
try {
|
|
14074
|
+
return await fs12__namespace.readFile(candidate, "utf8");
|
|
14075
|
+
} catch {
|
|
14076
|
+
}
|
|
14077
|
+
}
|
|
14078
|
+
throw createServicemeError(
|
|
14079
|
+
"not_found",
|
|
14080
|
+
`Agent file not found for ${agentId} in ${scope} scope.`
|
|
14081
|
+
);
|
|
14082
|
+
}
|
|
14083
|
+
|
|
14084
|
+
// src/commands/bridge.ts
|
|
14085
|
+
init_src2();
|
|
14086
|
+
|
|
14087
|
+
// src/bridge/BridgeServer.ts
|
|
14088
|
+
init_src();
|
|
14089
|
+
|
|
14090
|
+
// src/version.ts
|
|
14091
|
+
var SERVICEME_CLI_NAME = "serviceme";
|
|
14092
|
+
var SERVICEME_CLI_VERSION = "0.1.6";
|
|
14093
|
+
|
|
14094
|
+
// src/bridge/AgentBridgeHandler.ts
|
|
14095
|
+
init_src2();
|
|
14096
|
+
init_src();
|
|
14097
|
+
function normalizeAgentIdOrThrow2(store, remoteId) {
|
|
14098
|
+
try {
|
|
14099
|
+
return store.normalizeRemoteAgentId(remoteId);
|
|
14100
|
+
} catch {
|
|
14101
|
+
throw createServicemeError("invalid_params", `Invalid agent id: ${remoteId}`);
|
|
14102
|
+
}
|
|
14103
|
+
}
|
|
14104
|
+
var AgentBridgeHandler = class {
|
|
14105
|
+
async getMarketplaceState(params) {
|
|
14106
|
+
const context = this.createContext(params.workspacePath);
|
|
14107
|
+
const [catalog, workspaceAgentIds, userAgentIds] = await Promise.all([
|
|
14108
|
+
context.catalogClient.getCatalog(),
|
|
14109
|
+
context.store.listWorkspaceAgentIds(),
|
|
14110
|
+
context.store.listUserAgentIds()
|
|
14111
|
+
]);
|
|
14112
|
+
const workspaceSet = new Set(workspaceAgentIds);
|
|
14113
|
+
const userSet = new Set(userAgentIds);
|
|
14114
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14115
|
+
const byId = /* @__PURE__ */ new Map();
|
|
14116
|
+
for (const agent of catalog.agents) {
|
|
14117
|
+
const agentId = normalizeAgentIdOrThrow2(context.store, agent.id);
|
|
14118
|
+
const workspaceInstalled = workspaceSet.has(agentId);
|
|
14119
|
+
const userInstalled = userSet.has(agentId);
|
|
14120
|
+
byId.set(agentId, {
|
|
14121
|
+
id: agentId,
|
|
14122
|
+
displayName: agent.displayName,
|
|
14123
|
+
description: agent.description,
|
|
14124
|
+
version: agent.version,
|
|
14125
|
+
updatedAt: agent.updatedAt,
|
|
14126
|
+
categoryId: agent.categoryId,
|
|
14127
|
+
isCatalogAgent: true,
|
|
14128
|
+
recommended: agent.recommended,
|
|
14129
|
+
installCount: agent.installCount,
|
|
14130
|
+
ownerScope: agent.ownerScope,
|
|
14131
|
+
ownerKind: agent.ownerKind,
|
|
14132
|
+
hasConflict: agent.hasConflict,
|
|
14133
|
+
tools: agent.tools,
|
|
14134
|
+
source: agent.source,
|
|
14135
|
+
localAgentPath: workspaceInstalled || userInstalled ? workspaceInstalled ? path11__namespace.join(
|
|
14136
|
+
context.workspacePath,
|
|
14137
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
14138
|
+
`${agentId}.agent.md`
|
|
14139
|
+
) : path11__namespace.join(
|
|
14140
|
+
context.store.getUserAgentsRootPath(),
|
|
14141
|
+
`${agentId}.agent.md`
|
|
14142
|
+
) : void 0,
|
|
14143
|
+
canPublish: agent.canPublish,
|
|
14144
|
+
workspaceState: this.makeScopeState(
|
|
14145
|
+
"workspace",
|
|
14146
|
+
workspaceInstalled,
|
|
14147
|
+
path11__namespace.join(
|
|
14148
|
+
context.workspacePath,
|
|
14149
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
14150
|
+
`${agentId}.agent.md`
|
|
14151
|
+
)
|
|
14152
|
+
),
|
|
14153
|
+
userState: this.makeScopeState(
|
|
14154
|
+
"user",
|
|
14155
|
+
userInstalled,
|
|
14156
|
+
path11__namespace.join(
|
|
14157
|
+
context.store.getUserAgentsRootPath(),
|
|
14158
|
+
`${agentId}.agent.md`
|
|
14159
|
+
)
|
|
14160
|
+
)
|
|
14161
|
+
});
|
|
14162
|
+
}
|
|
14163
|
+
for (const agentId of workspaceAgentIds) {
|
|
14164
|
+
if (byId.has(agentId)) {
|
|
14165
|
+
continue;
|
|
14166
|
+
}
|
|
14167
|
+
byId.set(agentId, {
|
|
14168
|
+
id: agentId,
|
|
14169
|
+
displayName: agentId,
|
|
14170
|
+
description: "Local installed agent",
|
|
14171
|
+
version: "0.0.0",
|
|
14172
|
+
updatedAt: now,
|
|
14173
|
+
isCatalogAgent: false,
|
|
14174
|
+
recommended: false,
|
|
14175
|
+
installCount: 0,
|
|
14176
|
+
hasConflict: false,
|
|
14177
|
+
tools: [],
|
|
14178
|
+
source: "local",
|
|
14179
|
+
localAgentPath: path11__namespace.join(
|
|
14180
|
+
context.workspacePath,
|
|
14181
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
14182
|
+
`${agentId}.agent.md`
|
|
14183
|
+
),
|
|
14184
|
+
workspaceState: this.makeScopeState(
|
|
14185
|
+
"workspace",
|
|
14186
|
+
true,
|
|
14187
|
+
path11__namespace.join(
|
|
14188
|
+
context.workspacePath,
|
|
14189
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
14190
|
+
`${agentId}.agent.md`
|
|
14191
|
+
)
|
|
14192
|
+
),
|
|
14193
|
+
userState: this.makeScopeState(
|
|
14194
|
+
"user",
|
|
14195
|
+
userSet.has(agentId),
|
|
14196
|
+
path11__namespace.join(
|
|
14197
|
+
context.store.getUserAgentsRootPath(),
|
|
14198
|
+
`${agentId}.agent.md`
|
|
14199
|
+
)
|
|
14200
|
+
)
|
|
14201
|
+
});
|
|
14202
|
+
}
|
|
14203
|
+
for (const agentId of userAgentIds) {
|
|
14204
|
+
if (byId.has(agentId)) {
|
|
14205
|
+
continue;
|
|
14206
|
+
}
|
|
14207
|
+
byId.set(agentId, {
|
|
14208
|
+
id: agentId,
|
|
14209
|
+
displayName: agentId,
|
|
14210
|
+
description: "Local installed agent",
|
|
14211
|
+
version: "0.0.0",
|
|
14212
|
+
updatedAt: now,
|
|
14213
|
+
isCatalogAgent: false,
|
|
14214
|
+
recommended: false,
|
|
14215
|
+
installCount: 0,
|
|
14216
|
+
hasConflict: false,
|
|
14217
|
+
tools: [],
|
|
14218
|
+
source: "local",
|
|
14219
|
+
localAgentPath: path11__namespace.join(
|
|
14220
|
+
context.store.getUserAgentsRootPath(),
|
|
14221
|
+
`${agentId}.agent.md`
|
|
14222
|
+
),
|
|
14223
|
+
workspaceState: this.makeScopeState(
|
|
14224
|
+
"workspace",
|
|
14225
|
+
workspaceSet.has(agentId),
|
|
14226
|
+
path11__namespace.join(
|
|
14227
|
+
context.workspacePath,
|
|
14228
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
14229
|
+
`${agentId}.agent.md`
|
|
14230
|
+
)
|
|
14231
|
+
),
|
|
14232
|
+
userState: this.makeScopeState(
|
|
14233
|
+
"user",
|
|
14234
|
+
true,
|
|
14235
|
+
path11__namespace.join(
|
|
14236
|
+
context.store.getUserAgentsRootPath(),
|
|
14237
|
+
`${agentId}.agent.md`
|
|
14238
|
+
)
|
|
14239
|
+
)
|
|
14240
|
+
});
|
|
14241
|
+
}
|
|
14242
|
+
return {
|
|
14243
|
+
configPath: path11__namespace.join(
|
|
14244
|
+
context.workspacePath,
|
|
14245
|
+
context.store.getWorkspaceStateFilePath()
|
|
14246
|
+
),
|
|
14247
|
+
userAgentsPath: context.userAgentsRoot,
|
|
14248
|
+
agents: [...byId.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
14249
|
+
installedAgentIds: [.../* @__PURE__ */ new Set([...workspaceAgentIds, ...userAgentIds])],
|
|
14250
|
+
workspaceOpen: true
|
|
14251
|
+
};
|
|
14252
|
+
}
|
|
14253
|
+
async mutate(request) {
|
|
14254
|
+
const context = this.createContext();
|
|
14255
|
+
const agentId = normalizeAgentIdOrThrow2(context.store, request.agentId);
|
|
14256
|
+
const mutateResult = await context.reconciler.mutate({
|
|
14257
|
+
...request,
|
|
14258
|
+
agentId
|
|
14259
|
+
});
|
|
14260
|
+
if (mutateResult.status === "success") {
|
|
14261
|
+
await this.applyMutationSideEffect(context, {
|
|
14262
|
+
...request,
|
|
14263
|
+
agentId
|
|
14264
|
+
});
|
|
14265
|
+
}
|
|
14266
|
+
return {
|
|
14267
|
+
state: await this.getMarketplaceState({
|
|
14268
|
+
workspacePath: context.workspacePath
|
|
14269
|
+
}),
|
|
14270
|
+
agentId,
|
|
14271
|
+
targetScope: request.targetScope,
|
|
14272
|
+
action: request.action,
|
|
14273
|
+
changed: mutateResult.changed,
|
|
14274
|
+
status: mutateResult.status,
|
|
14275
|
+
message: mutateResult.message,
|
|
14276
|
+
tools: mutateResult.tools
|
|
14277
|
+
};
|
|
14278
|
+
}
|
|
14279
|
+
async permissions(params) {
|
|
14280
|
+
const context = this.createContext();
|
|
14281
|
+
const agentId = normalizeAgentIdOrThrow2(context.store, params.agentId);
|
|
14282
|
+
const scope = params.scope ?? "workspace";
|
|
14283
|
+
const content = await this.readAgentContent(context, agentId, scope);
|
|
14284
|
+
return context.reconciler.getPermissionSummary(agentId, agentId, content);
|
|
14285
|
+
}
|
|
14286
|
+
createContext(workspacePath) {
|
|
14287
|
+
const resolvedWorkspacePath = workspacePath ?? process.cwd();
|
|
14288
|
+
const userAgentsRoot = path11__namespace.join(os__namespace.homedir(), ".copilot", "agents");
|
|
14289
|
+
const store = new AgentStore({
|
|
14290
|
+
workspacePath: resolvedWorkspacePath,
|
|
14291
|
+
userAgentsRoot
|
|
14292
|
+
});
|
|
14293
|
+
const catalogClient = new AgentCatalogClient();
|
|
14294
|
+
const reconciler = new AgentReconciler({
|
|
14295
|
+
agentStore: store,
|
|
14296
|
+
catalogClient
|
|
14297
|
+
});
|
|
14298
|
+
return {
|
|
14299
|
+
workspacePath: resolvedWorkspacePath,
|
|
14300
|
+
userAgentsRoot,
|
|
14301
|
+
store,
|
|
14302
|
+
catalogClient,
|
|
14303
|
+
reconciler
|
|
14304
|
+
};
|
|
14305
|
+
}
|
|
14306
|
+
makeScopeState(scope, installed, agentPath) {
|
|
14307
|
+
if (installed) {
|
|
14308
|
+
return {
|
|
14309
|
+
scope,
|
|
14310
|
+
status: "installed",
|
|
14311
|
+
path: agentPath,
|
|
14312
|
+
isInstalled: true,
|
|
14313
|
+
canInstall: false,
|
|
14314
|
+
canUninstall: true,
|
|
14315
|
+
canRemove: false,
|
|
14316
|
+
canMoveHere: false
|
|
14317
|
+
};
|
|
14318
|
+
}
|
|
14319
|
+
return {
|
|
14320
|
+
scope,
|
|
14321
|
+
status: "absent",
|
|
14322
|
+
isInstalled: false,
|
|
14323
|
+
canInstall: true,
|
|
14324
|
+
canUninstall: false,
|
|
14325
|
+
canRemove: false,
|
|
14326
|
+
canMoveHere: true
|
|
14327
|
+
};
|
|
14328
|
+
}
|
|
14329
|
+
async applyMutationSideEffect(context, request) {
|
|
14330
|
+
const workspaceFlatPath = path11__namespace.join(
|
|
14331
|
+
context.workspacePath,
|
|
14332
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
14333
|
+
`${request.agentId}.agent.md`
|
|
14334
|
+
);
|
|
14335
|
+
const userFlatPath = path11__namespace.join(
|
|
14336
|
+
context.store.getUserAgentsRootPath(),
|
|
14337
|
+
`${request.agentId}.agent.md`
|
|
14338
|
+
);
|
|
14339
|
+
switch (request.action) {
|
|
14340
|
+
case "install":
|
|
14341
|
+
if (request.targetScope === "workspace") {
|
|
14342
|
+
await this.writeDefaultAgentFile(workspaceFlatPath, request.agentId);
|
|
14343
|
+
} else {
|
|
14344
|
+
await this.writeDefaultAgentFile(userFlatPath, request.agentId);
|
|
14345
|
+
}
|
|
14346
|
+
return;
|
|
14347
|
+
case "uninstall":
|
|
14348
|
+
if (request.targetScope === "workspace") {
|
|
14349
|
+
await fs12__namespace.rm(workspaceFlatPath, { recursive: true, force: true });
|
|
14350
|
+
} else {
|
|
14351
|
+
await fs12__namespace.rm(userFlatPath, { recursive: true, force: true });
|
|
14352
|
+
}
|
|
14353
|
+
return;
|
|
14354
|
+
case "move":
|
|
14355
|
+
if (request.targetScope === "workspace") {
|
|
14356
|
+
await this.moveEntry(userFlatPath, workspaceFlatPath);
|
|
14357
|
+
} else {
|
|
14358
|
+
await this.moveEntry(workspaceFlatPath, userFlatPath);
|
|
14359
|
+
}
|
|
14360
|
+
return;
|
|
14361
|
+
default:
|
|
14362
|
+
return;
|
|
14363
|
+
}
|
|
14364
|
+
}
|
|
14365
|
+
async moveEntry(fromPath, toPath) {
|
|
14366
|
+
await fs12__namespace.mkdir(path11__namespace.dirname(toPath), { recursive: true });
|
|
14367
|
+
try {
|
|
14368
|
+
await fs12__namespace.rename(fromPath, toPath);
|
|
14369
|
+
} catch {
|
|
14370
|
+
await fs12__namespace.cp(fromPath, toPath, { recursive: true });
|
|
14371
|
+
await fs12__namespace.rm(fromPath, { recursive: true, force: true });
|
|
14372
|
+
}
|
|
14373
|
+
}
|
|
14374
|
+
async writeDefaultAgentFile(targetPath, agentId) {
|
|
14375
|
+
await fs12__namespace.mkdir(path11__namespace.dirname(targetPath), { recursive: true });
|
|
14376
|
+
await fs12__namespace.writeFile(
|
|
14377
|
+
targetPath,
|
|
14378
|
+
`---
|
|
14379
|
+
name: ${agentId}
|
|
14380
|
+
tools:
|
|
14381
|
+
- run_in_terminal
|
|
14382
|
+
- read_file
|
|
14383
|
+
---
|
|
14384
|
+
|
|
14385
|
+
# ${agentId}
|
|
14386
|
+
`,
|
|
14387
|
+
"utf8"
|
|
14388
|
+
);
|
|
14389
|
+
}
|
|
14390
|
+
async readAgentContent(context, agentId, scope) {
|
|
14391
|
+
const root2 = scope === "workspace" ? path11__namespace.join(
|
|
14392
|
+
context.workspacePath,
|
|
14393
|
+
context.store.getWorkspaceAgentsRootPath()
|
|
14394
|
+
) : context.store.getUserAgentsRootPath();
|
|
14395
|
+
const candidates = [
|
|
14396
|
+
path11__namespace.join(root2, `${agentId}.agent.md`),
|
|
14397
|
+
path11__namespace.join(root2, agentId, `${agentId}.agent.md`)
|
|
14398
|
+
];
|
|
14399
|
+
for (const candidate of candidates) {
|
|
14400
|
+
try {
|
|
14401
|
+
return await fs12__namespace.readFile(candidate, "utf8");
|
|
14402
|
+
} catch {
|
|
14403
|
+
}
|
|
14404
|
+
}
|
|
14405
|
+
throw createServicemeError(
|
|
14406
|
+
"not_found",
|
|
14407
|
+
`Agent file not found for ${agentId} in ${scope} scope.`
|
|
14408
|
+
);
|
|
14409
|
+
}
|
|
14410
|
+
};
|
|
14411
|
+
|
|
14412
|
+
// src/bridge/ndjson.ts
|
|
14413
|
+
function writeBridgeMessage(message) {
|
|
14414
|
+
process.stdout.write(`${JSON.stringify(message)}
|
|
14415
|
+
`);
|
|
14416
|
+
}
|
|
14417
|
+
|
|
14418
|
+
// src/bridge/SkillBridgeHandler.ts
|
|
14419
|
+
init_src2();
|
|
14420
|
+
init_src();
|
|
14421
|
+
function normalizeSkillIdOrThrow(store, remoteId) {
|
|
14422
|
+
try {
|
|
14423
|
+
return store.normalizeRemoteSkillId(remoteId);
|
|
14424
|
+
} catch {
|
|
14425
|
+
throw createServicemeError("invalid_params", `Invalid skill id: ${remoteId}`);
|
|
14426
|
+
}
|
|
14427
|
+
}
|
|
14428
|
+
var SkillBridgeHandler = class {
|
|
14429
|
+
async getMarketplaceState(params) {
|
|
14430
|
+
const context = this.createContext(params.workspacePath);
|
|
14431
|
+
const [catalog, workspaceSkillIds, userSkillIds] = await Promise.all([
|
|
14432
|
+
context.catalogClient.getCatalog(),
|
|
14433
|
+
context.store.listWorkspaceSkillIds(),
|
|
14434
|
+
context.store.listUserSkillIds()
|
|
14435
|
+
]);
|
|
14436
|
+
const workspaceSet = new Set(workspaceSkillIds);
|
|
14437
|
+
const userSet = new Set(userSkillIds);
|
|
14438
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14439
|
+
const byId = /* @__PURE__ */ new Map();
|
|
14440
|
+
for (const skill of catalog.skills) {
|
|
14441
|
+
const skillId = normalizeSkillIdOrThrow(context.store, skill.id);
|
|
14442
|
+
const workspaceInstalled = workspaceSet.has(skillId);
|
|
14443
|
+
const userInstalled = userSet.has(skillId);
|
|
14444
|
+
byId.set(skillId, {
|
|
14445
|
+
id: skillId,
|
|
14446
|
+
displayName: skill.displayName,
|
|
14447
|
+
description: skill.description,
|
|
14448
|
+
version: skill.version,
|
|
14449
|
+
updatedAt: skill.updatedAt,
|
|
14450
|
+
categoryId: skill.categoryId,
|
|
14451
|
+
enabled: skill.enabled,
|
|
14452
|
+
isCatalogSkill: true,
|
|
14453
|
+
recommended: skill.recommended,
|
|
14454
|
+
installCount: skill.installCount,
|
|
14455
|
+
requiresSetup: skill.requiresSetup,
|
|
14456
|
+
setupHint: skill.setupHint,
|
|
14457
|
+
homepage: skill.homepage,
|
|
14458
|
+
ownerScope: skill.ownerScope,
|
|
14459
|
+
ownerKind: skill.ownerKind,
|
|
14460
|
+
hasConflict: skill.hasConflict,
|
|
14461
|
+
hasScripts: skill.hasScripts,
|
|
14462
|
+
hasHooks: skill.hasHooks,
|
|
14463
|
+
source: skill.source,
|
|
14464
|
+
localSkillPath: workspaceInstalled || userInstalled ? workspaceInstalled ? path11__namespace.join(
|
|
14465
|
+
context.workspacePath,
|
|
14466
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
14467
|
+
) : context.store.getUserSkillPath(skillId) : void 0,
|
|
14468
|
+
canPublish: skill.canPublish,
|
|
14469
|
+
workspaceState: this.makeScopeState(
|
|
14470
|
+
"workspace",
|
|
14471
|
+
workspaceInstalled,
|
|
14472
|
+
path11__namespace.join(
|
|
14473
|
+
context.workspacePath,
|
|
14474
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
14475
|
+
)
|
|
14476
|
+
),
|
|
14477
|
+
userState: this.makeScopeState(
|
|
14478
|
+
"user",
|
|
14479
|
+
userInstalled,
|
|
14480
|
+
context.store.getUserSkillPath(skillId)
|
|
14481
|
+
)
|
|
14482
|
+
});
|
|
14483
|
+
}
|
|
14484
|
+
for (const skillId of workspaceSkillIds) {
|
|
14485
|
+
if (byId.has(skillId)) {
|
|
14486
|
+
continue;
|
|
14487
|
+
}
|
|
14488
|
+
byId.set(skillId, {
|
|
14489
|
+
id: skillId,
|
|
14490
|
+
displayName: skillId,
|
|
14491
|
+
description: "Local installed skill",
|
|
14492
|
+
version: "0.0.0",
|
|
14493
|
+
updatedAt: now,
|
|
14494
|
+
isCatalogSkill: false,
|
|
14495
|
+
recommended: false,
|
|
14496
|
+
installCount: 0,
|
|
14497
|
+
hasConflict: false,
|
|
14498
|
+
source: "local",
|
|
14499
|
+
localSkillPath: path11__namespace.join(
|
|
14500
|
+
context.workspacePath,
|
|
14501
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
14502
|
+
),
|
|
14503
|
+
workspaceState: this.makeScopeState(
|
|
14504
|
+
"workspace",
|
|
14505
|
+
true,
|
|
14506
|
+
path11__namespace.join(
|
|
14507
|
+
context.workspacePath,
|
|
14508
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
14509
|
+
)
|
|
14510
|
+
),
|
|
14511
|
+
userState: this.makeScopeState(
|
|
14512
|
+
"user",
|
|
14513
|
+
userSet.has(skillId),
|
|
14514
|
+
context.store.getUserSkillPath(skillId)
|
|
14515
|
+
)
|
|
14516
|
+
});
|
|
14517
|
+
}
|
|
14518
|
+
for (const skillId of userSkillIds) {
|
|
14519
|
+
if (byId.has(skillId)) {
|
|
14520
|
+
continue;
|
|
14521
|
+
}
|
|
14522
|
+
byId.set(skillId, {
|
|
14523
|
+
id: skillId,
|
|
14524
|
+
displayName: skillId,
|
|
14525
|
+
description: "Local installed skill",
|
|
14526
|
+
version: "0.0.0",
|
|
14527
|
+
updatedAt: now,
|
|
14528
|
+
isCatalogSkill: false,
|
|
14529
|
+
recommended: false,
|
|
14530
|
+
installCount: 0,
|
|
14531
|
+
hasConflict: false,
|
|
14532
|
+
source: "local",
|
|
14533
|
+
localSkillPath: context.store.getUserSkillPath(skillId),
|
|
14534
|
+
workspaceState: this.makeScopeState(
|
|
14535
|
+
"workspace",
|
|
14536
|
+
workspaceSet.has(skillId),
|
|
14537
|
+
path11__namespace.join(
|
|
14538
|
+
context.workspacePath,
|
|
14539
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
14540
|
+
)
|
|
14541
|
+
),
|
|
14542
|
+
userState: this.makeScopeState(
|
|
14543
|
+
"user",
|
|
14544
|
+
true,
|
|
14545
|
+
context.store.getUserSkillPath(skillId)
|
|
14546
|
+
)
|
|
14547
|
+
});
|
|
14548
|
+
}
|
|
14549
|
+
return {
|
|
14550
|
+
configPath: path11__namespace.join(
|
|
14551
|
+
context.workspacePath,
|
|
14552
|
+
context.store.getWorkspaceMarkerPath()
|
|
14553
|
+
),
|
|
14554
|
+
userSkillsPath: context.userSkillsRoot,
|
|
14555
|
+
skills: [...byId.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
14556
|
+
enabledSkillIds: [],
|
|
14557
|
+
recommendedSkillIds: catalog.skills.filter((skill) => skill.recommended).map((skill) => context.store.normalizeRemoteSkillId(skill.id)),
|
|
14558
|
+
onboardingRequired: false,
|
|
14559
|
+
hasPersistedSelection: false,
|
|
14560
|
+
workspaceOpen: true
|
|
14561
|
+
};
|
|
14562
|
+
}
|
|
14563
|
+
async mutate(request) {
|
|
14564
|
+
const context = this.createContext();
|
|
14565
|
+
const skillId = normalizeSkillIdOrThrow(context.store, request.skillId);
|
|
14566
|
+
const mutateResult = await context.reconciler.mutate({
|
|
14567
|
+
...request,
|
|
14568
|
+
skillId
|
|
14569
|
+
});
|
|
14570
|
+
if (mutateResult.status === "success") {
|
|
14571
|
+
await this.applyMutationSideEffect(context, {
|
|
14572
|
+
...request,
|
|
14573
|
+
skillId
|
|
14574
|
+
});
|
|
14575
|
+
}
|
|
14576
|
+
return {
|
|
14577
|
+
state: await this.getMarketplaceState({
|
|
14578
|
+
workspacePath: context.workspacePath
|
|
14579
|
+
}),
|
|
14580
|
+
skillId,
|
|
14581
|
+
targetScope: request.targetScope,
|
|
14582
|
+
action: request.action,
|
|
14583
|
+
changed: mutateResult.changed,
|
|
14584
|
+
status: mutateResult.status,
|
|
14585
|
+
message: mutateResult.message,
|
|
14586
|
+
hasScripts: mutateResult.hasScripts,
|
|
14587
|
+
hasHooks: mutateResult.hasHooks
|
|
14588
|
+
};
|
|
14589
|
+
}
|
|
14590
|
+
async reconcile(params) {
|
|
14591
|
+
const state = await this.getMarketplaceState({
|
|
14592
|
+
workspacePath: params.workspacePath,
|
|
14593
|
+
forceRefresh: params.force
|
|
14594
|
+
});
|
|
14595
|
+
return {
|
|
14596
|
+
state,
|
|
14597
|
+
changed: false
|
|
14598
|
+
};
|
|
14599
|
+
}
|
|
14600
|
+
async publishable(params) {
|
|
14601
|
+
const context = this.createContext(params.workspacePath);
|
|
14602
|
+
const workspaceSkillIds = await context.store.listWorkspaceSkillIds();
|
|
14603
|
+
return {
|
|
14604
|
+
skills: workspaceSkillIds.map((skillId) => ({
|
|
14605
|
+
id: skillId,
|
|
14606
|
+
displayName: skillId,
|
|
14607
|
+
path: path11__namespace.join(
|
|
14608
|
+
context.workspacePath,
|
|
14609
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
14610
|
+
)
|
|
14611
|
+
}))
|
|
14612
|
+
};
|
|
14613
|
+
}
|
|
14614
|
+
createContext(workspacePath) {
|
|
14615
|
+
const resolvedWorkspacePath = workspacePath ?? process.cwd();
|
|
14616
|
+
const userSkillsRoot = path11__namespace.join(os__namespace.homedir(), ".agents", "skills");
|
|
14617
|
+
const store = new SkillStore({
|
|
14618
|
+
workspacePath: resolvedWorkspacePath,
|
|
14619
|
+
userSkillsRoot
|
|
14620
|
+
});
|
|
14621
|
+
const catalogClient = new SkillCatalogClient();
|
|
14622
|
+
const reconciler = new SkillReconciler({
|
|
14623
|
+
skillStore: store,
|
|
14624
|
+
catalogClient
|
|
14625
|
+
});
|
|
14626
|
+
return {
|
|
14627
|
+
workspacePath: resolvedWorkspacePath,
|
|
14628
|
+
userSkillsRoot,
|
|
14629
|
+
store,
|
|
14630
|
+
catalogClient,
|
|
14631
|
+
reconciler
|
|
14632
|
+
};
|
|
14633
|
+
}
|
|
14634
|
+
makeScopeState(scope, installed, skillPath) {
|
|
14635
|
+
if (installed) {
|
|
14636
|
+
return {
|
|
14637
|
+
scope,
|
|
14638
|
+
status: "installed",
|
|
14639
|
+
path: skillPath,
|
|
14640
|
+
isInstalled: true,
|
|
14641
|
+
canInstall: false,
|
|
14642
|
+
canUninstall: true,
|
|
14643
|
+
canRemove: false,
|
|
14644
|
+
canMoveHere: false
|
|
14645
|
+
};
|
|
14646
|
+
}
|
|
14647
|
+
return {
|
|
14648
|
+
scope,
|
|
14649
|
+
status: "absent",
|
|
14650
|
+
isInstalled: false,
|
|
14651
|
+
canInstall: true,
|
|
14652
|
+
canUninstall: false,
|
|
14653
|
+
canRemove: false,
|
|
14654
|
+
canMoveHere: true
|
|
14655
|
+
};
|
|
14656
|
+
}
|
|
14657
|
+
async applyMutationSideEffect(context, request) {
|
|
14658
|
+
const workspaceSkillPath = path11__namespace.join(
|
|
14659
|
+
context.workspacePath,
|
|
14660
|
+
context.store.getWorkspaceSkillPath(request.skillId)
|
|
14661
|
+
);
|
|
14662
|
+
const userSkillPath = context.store.getUserSkillPath(request.skillId);
|
|
14663
|
+
switch (request.action) {
|
|
14664
|
+
case "install":
|
|
14665
|
+
if (request.targetScope === "workspace") {
|
|
14666
|
+
await fs12__namespace.mkdir(workspaceSkillPath, { recursive: true });
|
|
14667
|
+
} else {
|
|
14668
|
+
await fs12__namespace.mkdir(userSkillPath, { recursive: true });
|
|
14669
|
+
await context.store.writeManagedUserSkillMarker(request.skillId);
|
|
14670
|
+
}
|
|
14671
|
+
return;
|
|
14672
|
+
case "uninstall":
|
|
14673
|
+
if (request.targetScope === "workspace") {
|
|
14674
|
+
await fs12__namespace.rm(workspaceSkillPath, { recursive: true, force: true });
|
|
14675
|
+
} else {
|
|
14676
|
+
await fs12__namespace.rm(userSkillPath, { recursive: true, force: true });
|
|
14677
|
+
}
|
|
14678
|
+
return;
|
|
14679
|
+
case "move":
|
|
14680
|
+
if (request.targetScope === "workspace") {
|
|
14681
|
+
await this.moveDirectory(userSkillPath, workspaceSkillPath);
|
|
14682
|
+
} else {
|
|
14683
|
+
await this.moveDirectory(workspaceSkillPath, userSkillPath);
|
|
14684
|
+
await context.store.writeManagedUserSkillMarker(request.skillId);
|
|
14685
|
+
}
|
|
14686
|
+
return;
|
|
14687
|
+
default:
|
|
14688
|
+
return;
|
|
14689
|
+
}
|
|
14690
|
+
}
|
|
14691
|
+
async moveDirectory(fromPath, toPath) {
|
|
14692
|
+
await fs12__namespace.mkdir(path11__namespace.dirname(toPath), { recursive: true });
|
|
14693
|
+
try {
|
|
14694
|
+
await fs12__namespace.rename(fromPath, toPath);
|
|
14695
|
+
} catch {
|
|
14696
|
+
await fs12__namespace.cp(fromPath, toPath, { recursive: true });
|
|
14697
|
+
await fs12__namespace.rm(fromPath, { recursive: true, force: true });
|
|
14698
|
+
}
|
|
14699
|
+
}
|
|
14700
|
+
};
|
|
14701
|
+
|
|
14702
|
+
// src/bridge/TaskBridgeHandler.ts
|
|
14703
|
+
init_src2();
|
|
14704
|
+
var TaskBridgeHandler = class {
|
|
14705
|
+
constructor(logger, emitEvent) {
|
|
14706
|
+
this.logger = logger;
|
|
14707
|
+
this.emitEvent = emitEvent;
|
|
14708
|
+
this.engine = new TaskExecutionEngine(
|
|
14709
|
+
(taskType) => getExecutor(taskType)
|
|
14710
|
+
);
|
|
14711
|
+
this.engine.setListener({
|
|
14712
|
+
onStarted: (params) => this.emitEvent("task.started", params),
|
|
14713
|
+
onOutput: (params) => this.emitEvent("task.output", params),
|
|
14714
|
+
onCompleted: (params) => this.emitEvent("task.completed", params),
|
|
14715
|
+
onFailed: (params) => this.emitEvent("task.failed", params),
|
|
14716
|
+
onCancelled: (params) => this.emitEvent("task.cancelled", params)
|
|
14717
|
+
});
|
|
14718
|
+
}
|
|
13205
14719
|
async execute(snapshot) {
|
|
13206
14720
|
let earlyError;
|
|
13207
14721
|
const executePromise = this.engine.execute(snapshot).catch((err) => {
|
|
@@ -13233,7 +14747,9 @@ var CAPABILITIES = {
|
|
|
13233
14747
|
bridge: true,
|
|
13234
14748
|
json: 1,
|
|
13235
14749
|
env: 1,
|
|
13236
|
-
tasks: 1
|
|
14750
|
+
tasks: 1,
|
|
14751
|
+
skills: 1,
|
|
14752
|
+
agents: 1
|
|
13237
14753
|
};
|
|
13238
14754
|
var BridgeServer = class {
|
|
13239
14755
|
constructor(logger) {
|
|
@@ -13242,6 +14758,8 @@ var BridgeServer = class {
|
|
|
13242
14758
|
this.taskHandler = new TaskBridgeHandler(logger, (event, params) => {
|
|
13243
14759
|
this.writeEvent(event, params);
|
|
13244
14760
|
});
|
|
14761
|
+
this.skillHandler = new SkillBridgeHandler();
|
|
14762
|
+
this.agentHandler = new AgentBridgeHandler();
|
|
13245
14763
|
}
|
|
13246
14764
|
async run() {
|
|
13247
14765
|
const reader = readline__namespace.createInterface({
|
|
@@ -13347,6 +14865,56 @@ var BridgeServer = class {
|
|
|
13347
14865
|
this.writeSuccess(request.id, result);
|
|
13348
14866
|
return;
|
|
13349
14867
|
}
|
|
14868
|
+
case "skill.marketplace-state": {
|
|
14869
|
+
const skillRequest = request;
|
|
14870
|
+
const result = await this.skillHandler.getMarketplaceState(
|
|
14871
|
+
skillRequest.params
|
|
14872
|
+
);
|
|
14873
|
+
this.writeSuccess(request.id, result);
|
|
14874
|
+
return;
|
|
14875
|
+
}
|
|
14876
|
+
case "skill.mutate": {
|
|
14877
|
+
const skillRequest = request;
|
|
14878
|
+
const result = await this.skillHandler.mutate(skillRequest.params);
|
|
14879
|
+
this.writeSuccess(request.id, result);
|
|
14880
|
+
return;
|
|
14881
|
+
}
|
|
14882
|
+
case "skill.reconcile": {
|
|
14883
|
+
const skillRequest = request;
|
|
14884
|
+
const result = await this.skillHandler.reconcile(skillRequest.params);
|
|
14885
|
+
this.writeSuccess(request.id, result);
|
|
14886
|
+
return;
|
|
14887
|
+
}
|
|
14888
|
+
case "skill.publishable": {
|
|
14889
|
+
const skillRequest = request;
|
|
14890
|
+
const result = await this.skillHandler.publishable(
|
|
14891
|
+
skillRequest.params
|
|
14892
|
+
);
|
|
14893
|
+
this.writeSuccess(request.id, result);
|
|
14894
|
+
return;
|
|
14895
|
+
}
|
|
14896
|
+
case "agent.marketplace-state": {
|
|
14897
|
+
const agentRequest = request;
|
|
14898
|
+
const result = await this.agentHandler.getMarketplaceState(
|
|
14899
|
+
agentRequest.params
|
|
14900
|
+
);
|
|
14901
|
+
this.writeSuccess(request.id, result);
|
|
14902
|
+
return;
|
|
14903
|
+
}
|
|
14904
|
+
case "agent.mutate": {
|
|
14905
|
+
const agentRequest = request;
|
|
14906
|
+
const result = await this.agentHandler.mutate(agentRequest.params);
|
|
14907
|
+
this.writeSuccess(request.id, result);
|
|
14908
|
+
return;
|
|
14909
|
+
}
|
|
14910
|
+
case "agent.permissions": {
|
|
14911
|
+
const agentRequest = request;
|
|
14912
|
+
const result = await this.agentHandler.permissions(
|
|
14913
|
+
agentRequest.params
|
|
14914
|
+
);
|
|
14915
|
+
this.writeSuccess(request.id, result);
|
|
14916
|
+
return;
|
|
14917
|
+
}
|
|
13350
14918
|
default:
|
|
13351
14919
|
this.writeError(
|
|
13352
14920
|
request.id,
|
|
@@ -13396,21 +14964,6 @@ async function runBridgeCommand() {
|
|
|
13396
14964
|
|
|
13397
14965
|
// src/commands/copilot.ts
|
|
13398
14966
|
init_src2();
|
|
13399
|
-
|
|
13400
|
-
// src/output.ts
|
|
13401
|
-
init_src();
|
|
13402
|
-
function writeJson(value) {
|
|
13403
|
-
process.stdout.write(`${JSON.stringify(value)}
|
|
13404
|
-
`);
|
|
13405
|
-
}
|
|
13406
|
-
function writeSuccess(data) {
|
|
13407
|
-
writeJson(createCliSuccess(data));
|
|
13408
|
-
}
|
|
13409
|
-
function writeFailure(error) {
|
|
13410
|
-
writeJson(createCliFailure(normalizeServicemeError(error)));
|
|
13411
|
-
}
|
|
13412
|
-
|
|
13413
|
-
// src/commands/copilot.ts
|
|
13414
14967
|
async function runCopilotCommand(parsed) {
|
|
13415
14968
|
const action = parsed.positionals[1];
|
|
13416
14969
|
switch (action) {
|
|
@@ -13530,7 +15083,7 @@ async function runImageCommand(parsed) {
|
|
|
13530
15083
|
init_src2();
|
|
13531
15084
|
async function readCommandInput(options2) {
|
|
13532
15085
|
if (options2.filePath) {
|
|
13533
|
-
return
|
|
15086
|
+
return fs12__namespace.readFile(options2.filePath, "utf8");
|
|
13534
15087
|
}
|
|
13535
15088
|
if (options2.stdin) {
|
|
13536
15089
|
return readStdin();
|
|
@@ -13669,7 +15222,7 @@ async function runScheduleCommand(parsed) {
|
|
|
13669
15222
|
await handleCreate(parsed);
|
|
13670
15223
|
return;
|
|
13671
15224
|
case "list":
|
|
13672
|
-
|
|
15225
|
+
handleList2(parsed);
|
|
13673
15226
|
return;
|
|
13674
15227
|
case "get":
|
|
13675
15228
|
handleGet(parsed);
|
|
@@ -13704,7 +15257,7 @@ function requireWorkspace(parsed) {
|
|
|
13704
15257
|
"Missing required flag: --workspacePath"
|
|
13705
15258
|
);
|
|
13706
15259
|
}
|
|
13707
|
-
if (!
|
|
15260
|
+
if (!fs9__namespace.existsSync(wp)) {
|
|
13708
15261
|
throw createServicemeError(
|
|
13709
15262
|
"workspace_not_found",
|
|
13710
15263
|
`Workspace path does not exist: ${wp}`
|
|
@@ -13901,7 +15454,7 @@ async function handleCreate(parsed) {
|
|
|
13901
15454
|
const task = mgr.createTask(input);
|
|
13902
15455
|
writeSuccess({ task });
|
|
13903
15456
|
}
|
|
13904
|
-
function
|
|
15457
|
+
function handleList2(parsed) {
|
|
13905
15458
|
const wp = requireWorkspace(parsed);
|
|
13906
15459
|
const mgr = new TaskConfigManager(wp);
|
|
13907
15460
|
const tasks = mgr.listTasks();
|
|
@@ -14273,7 +15826,7 @@ function requireWorkspace2(parsed) {
|
|
|
14273
15826
|
"Missing required flag: --workspacePath"
|
|
14274
15827
|
);
|
|
14275
15828
|
}
|
|
14276
|
-
if (!
|
|
15829
|
+
if (!fs9__namespace.existsSync(wp)) {
|
|
14277
15830
|
throw createServicemeError(
|
|
14278
15831
|
"workspace_not_found",
|
|
14279
15832
|
`Workspace path does not exist: ${wp}`
|
|
@@ -14300,10 +15853,10 @@ function handleStart(parsed) {
|
|
|
14300
15853
|
"Cannot determine CLI path for daemon spawn"
|
|
14301
15854
|
);
|
|
14302
15855
|
}
|
|
14303
|
-
const logPath =
|
|
14304
|
-
const logDir =
|
|
14305
|
-
if (!
|
|
14306
|
-
|
|
15856
|
+
const logPath = path11__namespace.join(wp, ".serviceme", "scheduler.log");
|
|
15857
|
+
const logDir = path11__namespace.dirname(logPath);
|
|
15858
|
+
if (!fs9__namespace.existsSync(logDir)) {
|
|
15859
|
+
fs9__namespace.mkdirSync(logDir, { recursive: true });
|
|
14307
15860
|
}
|
|
14308
15861
|
const spawnCmd = process.execPath;
|
|
14309
15862
|
const spawnArgs = [
|
|
@@ -14316,7 +15869,7 @@ function handleStart(parsed) {
|
|
|
14316
15869
|
logPath
|
|
14317
15870
|
];
|
|
14318
15871
|
if (process.platform === "win32") {
|
|
14319
|
-
|
|
15872
|
+
fs9__namespace.appendFileSync(
|
|
14320
15873
|
logPath,
|
|
14321
15874
|
`[scheduler:start] spawning daemon via hidden PowerShell Start-Process: cmd=${spawnCmd}, args=${JSON.stringify(spawnArgs)}, platform=${process.platform}, windowsHide=true
|
|
14322
15875
|
`
|
|
@@ -14326,9 +15879,9 @@ function handleStart(parsed) {
|
|
|
14326
15879
|
writeSuccess({ pid: pid2, status: "started", workspacePath: wp });
|
|
14327
15880
|
return;
|
|
14328
15881
|
}
|
|
14329
|
-
const out =
|
|
14330
|
-
const err =
|
|
14331
|
-
|
|
15882
|
+
const out = fs9__namespace.openSync(logPath, "a");
|
|
15883
|
+
const err = fs9__namespace.openSync(logPath, "a");
|
|
15884
|
+
fs9__namespace.appendFileSync(
|
|
14332
15885
|
logPath,
|
|
14333
15886
|
`[scheduler:start] spawning daemon: cmd=${spawnCmd}, args=${JSON.stringify(spawnArgs)}, platform=${process.platform}, detached=true, windowsHide=true
|
|
14334
15887
|
`
|
|
@@ -14439,7 +15992,7 @@ function handleStatus(parsed) {
|
|
|
14439
15992
|
let uptimeSeconds = null;
|
|
14440
15993
|
if (pid !== null) {
|
|
14441
15994
|
try {
|
|
14442
|
-
const stat2 =
|
|
15995
|
+
const stat2 = fs9__namespace.statSync(pidMgr.getPidPath());
|
|
14443
15996
|
uptimeSeconds = Math.floor((Date.now() - stat2.mtimeMs) / 1e3);
|
|
14444
15997
|
} catch {
|
|
14445
15998
|
uptimeSeconds = null;
|
|
@@ -14510,6 +16063,279 @@ function writeDescribe2(action) {
|
|
|
14510
16063
|
}
|
|
14511
16064
|
}
|
|
14512
16065
|
|
|
16066
|
+
// src/commands/skill.ts
|
|
16067
|
+
init_src2();
|
|
16068
|
+
init_src();
|
|
16069
|
+
function normalizeSkillIdOrThrow2(store, remoteId) {
|
|
16070
|
+
try {
|
|
16071
|
+
return store.normalizeRemoteSkillId(remoteId);
|
|
16072
|
+
} catch {
|
|
16073
|
+
throw createServicemeError("invalid_params", `Invalid skill id: ${remoteId}`);
|
|
16074
|
+
}
|
|
16075
|
+
}
|
|
16076
|
+
async function runSkillCommand(parsed) {
|
|
16077
|
+
const action = parsed.positionals[1];
|
|
16078
|
+
const workspacePath = getStringFlag(parsed, "workspacePath");
|
|
16079
|
+
if (!workspacePath) {
|
|
16080
|
+
throw createServicemeError(
|
|
16081
|
+
"invalid_params",
|
|
16082
|
+
"Expected --workspacePath <path>."
|
|
16083
|
+
);
|
|
16084
|
+
}
|
|
16085
|
+
const store = new SkillStore({
|
|
16086
|
+
workspacePath,
|
|
16087
|
+
userSkillsRoot: path11__namespace.join(os__namespace.homedir(), ".agents", "skills")
|
|
16088
|
+
});
|
|
16089
|
+
const catalogClient = new SkillCatalogClient({
|
|
16090
|
+
baseUrl: getStringFlag(parsed, "baseUrl")
|
|
16091
|
+
});
|
|
16092
|
+
const reconciler = new SkillReconciler({
|
|
16093
|
+
skillStore: store,
|
|
16094
|
+
catalogClient
|
|
16095
|
+
});
|
|
16096
|
+
switch (action) {
|
|
16097
|
+
case "list":
|
|
16098
|
+
writeSuccess(await handleList3(store));
|
|
16099
|
+
return;
|
|
16100
|
+
case "install":
|
|
16101
|
+
writeSuccess(await handleInstall2(store, workspacePath, parsed));
|
|
16102
|
+
return;
|
|
16103
|
+
case "uninstall":
|
|
16104
|
+
writeSuccess(await handleUninstall2(store, workspacePath, parsed));
|
|
16105
|
+
return;
|
|
16106
|
+
case "move":
|
|
16107
|
+
writeSuccess(await handleMove2(store, workspacePath, parsed));
|
|
16108
|
+
return;
|
|
16109
|
+
case "marketplace":
|
|
16110
|
+
writeSuccess(await handleMarketplace2(store, catalogClient));
|
|
16111
|
+
return;
|
|
16112
|
+
case "find":
|
|
16113
|
+
writeSuccess(await handleFind(store, catalogClient, parsed));
|
|
16114
|
+
return;
|
|
16115
|
+
case "reconcile":
|
|
16116
|
+
writeSuccess(await handleReconcile(store, reconciler));
|
|
16117
|
+
return;
|
|
16118
|
+
case "publishable":
|
|
16119
|
+
writeSuccess(await handlePublishable(store, workspacePath));
|
|
16120
|
+
return;
|
|
16121
|
+
default:
|
|
16122
|
+
throw new Error(
|
|
16123
|
+
"Unsupported skill command. Use list, install, uninstall, move, marketplace, find, reconcile, or publishable."
|
|
16124
|
+
);
|
|
16125
|
+
}
|
|
16126
|
+
}
|
|
16127
|
+
async function handleList3(store) {
|
|
16128
|
+
const workspaceSkills = await store.listWorkspaceSkillIds();
|
|
16129
|
+
const userSkills = await store.listUserSkillIds();
|
|
16130
|
+
return {
|
|
16131
|
+
skills: [
|
|
16132
|
+
...workspaceSkills.map((id) => ({ id, scope: "workspace" })),
|
|
16133
|
+
...userSkills.map((id) => ({ id, scope: "user" }))
|
|
16134
|
+
]
|
|
16135
|
+
};
|
|
16136
|
+
}
|
|
16137
|
+
async function handleInstall2(store, workspacePath, parsed) {
|
|
16138
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
16139
|
+
if (!remoteId) {
|
|
16140
|
+
throw createServicemeError(
|
|
16141
|
+
"invalid_params",
|
|
16142
|
+
"Expected --id <remoteSkillId>."
|
|
16143
|
+
);
|
|
16144
|
+
}
|
|
16145
|
+
const skillId = normalizeSkillIdOrThrow2(store, remoteId);
|
|
16146
|
+
if (!getBooleanFlag(parsed, "confirmed")) {
|
|
16147
|
+
return {
|
|
16148
|
+
changed: false,
|
|
16149
|
+
scope: "workspace",
|
|
16150
|
+
skillId,
|
|
16151
|
+
status: "requires_confirmation",
|
|
16152
|
+
message: "Install requires --confirmed."
|
|
16153
|
+
};
|
|
16154
|
+
}
|
|
16155
|
+
const workspaceSkillDir = path11__namespace.join(
|
|
16156
|
+
workspacePath,
|
|
16157
|
+
store.getWorkspaceSkillPath(skillId)
|
|
16158
|
+
);
|
|
16159
|
+
await fs12__namespace.mkdir(workspaceSkillDir, { recursive: true });
|
|
16160
|
+
return {
|
|
16161
|
+
changed: true,
|
|
16162
|
+
scope: "workspace",
|
|
16163
|
+
skillId,
|
|
16164
|
+
status: "success"
|
|
16165
|
+
};
|
|
16166
|
+
}
|
|
16167
|
+
async function handleUninstall2(store, workspacePath, parsed) {
|
|
16168
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
16169
|
+
if (!remoteId) {
|
|
16170
|
+
throw createServicemeError(
|
|
16171
|
+
"invalid_params",
|
|
16172
|
+
"Expected --id <remoteSkillId>."
|
|
16173
|
+
);
|
|
16174
|
+
}
|
|
16175
|
+
const skillId = normalizeSkillIdOrThrow2(store, remoteId);
|
|
16176
|
+
await fs12__namespace.rm(path11__namespace.join(workspacePath, store.getWorkspaceSkillPath(skillId)), {
|
|
16177
|
+
recursive: true,
|
|
16178
|
+
force: true
|
|
16179
|
+
});
|
|
16180
|
+
await fs12__namespace.rm(store.getUserSkillPath(skillId), {
|
|
16181
|
+
recursive: true,
|
|
16182
|
+
force: true
|
|
16183
|
+
});
|
|
16184
|
+
return {
|
|
16185
|
+
changed: true,
|
|
16186
|
+
skillId
|
|
16187
|
+
};
|
|
16188
|
+
}
|
|
16189
|
+
async function handleMove2(store, workspacePath, parsed) {
|
|
16190
|
+
const remoteId = getStringFlag(parsed, "id");
|
|
16191
|
+
const to = getStringFlag(parsed, "to");
|
|
16192
|
+
if (!remoteId || !to) {
|
|
16193
|
+
throw createServicemeError(
|
|
16194
|
+
"invalid_params",
|
|
16195
|
+
"Expected --id <remoteSkillId> and --to <workspace|user>."
|
|
16196
|
+
);
|
|
16197
|
+
}
|
|
16198
|
+
if (to !== "workspace" && to !== "user") {
|
|
16199
|
+
throw createServicemeError(
|
|
16200
|
+
"invalid_params",
|
|
16201
|
+
"Expected --to value to be workspace or user."
|
|
16202
|
+
);
|
|
16203
|
+
}
|
|
16204
|
+
const skillId = normalizeSkillIdOrThrow2(store, remoteId);
|
|
16205
|
+
const workspacePathForSkill = path11__namespace.join(
|
|
16206
|
+
workspacePath,
|
|
16207
|
+
store.getWorkspaceSkillPath(skillId)
|
|
16208
|
+
);
|
|
16209
|
+
const userPathForSkill = store.getUserSkillPath(skillId);
|
|
16210
|
+
if (to === "user") {
|
|
16211
|
+
await moveDirectory(workspacePathForSkill, userPathForSkill);
|
|
16212
|
+
await store.writeManagedUserSkillMarker(skillId);
|
|
16213
|
+
return {
|
|
16214
|
+
changed: true,
|
|
16215
|
+
fromScope: "workspace",
|
|
16216
|
+
toScope: "user",
|
|
16217
|
+
skillId
|
|
16218
|
+
};
|
|
16219
|
+
}
|
|
16220
|
+
await moveDirectory(userPathForSkill, workspacePathForSkill);
|
|
16221
|
+
return {
|
|
16222
|
+
changed: true,
|
|
16223
|
+
fromScope: "user",
|
|
16224
|
+
toScope: "workspace",
|
|
16225
|
+
skillId
|
|
16226
|
+
};
|
|
16227
|
+
}
|
|
16228
|
+
async function moveDirectory(fromPath, toPath) {
|
|
16229
|
+
await fs12__namespace.mkdir(path11__namespace.dirname(toPath), { recursive: true });
|
|
16230
|
+
try {
|
|
16231
|
+
await fs12__namespace.rename(fromPath, toPath);
|
|
16232
|
+
} catch {
|
|
16233
|
+
await fs12__namespace.cp(fromPath, toPath, { recursive: true });
|
|
16234
|
+
await fs12__namespace.rm(fromPath, { recursive: true, force: true });
|
|
16235
|
+
}
|
|
16236
|
+
}
|
|
16237
|
+
async function handleMarketplace2(store, catalogClient) {
|
|
16238
|
+
const [catalog, workspaceSkillIds, userSkillIds] = await Promise.all([
|
|
16239
|
+
catalogClient.getCatalog(),
|
|
16240
|
+
store.listWorkspaceSkillIds(),
|
|
16241
|
+
store.listUserSkillIds()
|
|
16242
|
+
]);
|
|
16243
|
+
const scopesById = /* @__PURE__ */ new Map();
|
|
16244
|
+
for (const skillId of workspaceSkillIds) {
|
|
16245
|
+
scopesById.set(skillId, ["workspace"]);
|
|
16246
|
+
}
|
|
16247
|
+
for (const skillId of userSkillIds) {
|
|
16248
|
+
const existing = scopesById.get(skillId);
|
|
16249
|
+
if (existing) {
|
|
16250
|
+
existing.push("user");
|
|
16251
|
+
} else {
|
|
16252
|
+
scopesById.set(skillId, ["user"]);
|
|
16253
|
+
}
|
|
16254
|
+
}
|
|
16255
|
+
const merged = /* @__PURE__ */ new Map();
|
|
16256
|
+
for (const skill of catalog.skills) {
|
|
16257
|
+
const normalizedId = normalizeSkillIdOrThrow2(store, skill.id);
|
|
16258
|
+
merged.set(normalizedId, {
|
|
16259
|
+
id: normalizedId,
|
|
16260
|
+
displayName: skill.displayName,
|
|
16261
|
+
description: skill.description,
|
|
16262
|
+
source: "catalog",
|
|
16263
|
+
scopes: scopesById.get(normalizedId) ?? []
|
|
16264
|
+
});
|
|
16265
|
+
}
|
|
16266
|
+
for (const [skillId, scopes] of scopesById) {
|
|
16267
|
+
if (merged.has(skillId)) {
|
|
16268
|
+
continue;
|
|
16269
|
+
}
|
|
16270
|
+
merged.set(skillId, {
|
|
16271
|
+
id: skillId,
|
|
16272
|
+
displayName: skillId,
|
|
16273
|
+
description: "Local installed skill",
|
|
16274
|
+
source: "local",
|
|
16275
|
+
scopes
|
|
16276
|
+
});
|
|
16277
|
+
}
|
|
16278
|
+
return {
|
|
16279
|
+
skills: [...merged.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
16280
|
+
fetchedAt: catalog.fetchedAt
|
|
16281
|
+
};
|
|
16282
|
+
}
|
|
16283
|
+
async function handleFind(store, catalogClient, parsed) {
|
|
16284
|
+
const query = getStringFlag(parsed, "query") ?? getStringFlag(parsed, "q");
|
|
16285
|
+
if (!query) {
|
|
16286
|
+
throw createServicemeError(
|
|
16287
|
+
"invalid_params",
|
|
16288
|
+
"Expected --query <text> or --q <text>."
|
|
16289
|
+
);
|
|
16290
|
+
}
|
|
16291
|
+
const marketplace = await handleMarketplace2(store, catalogClient);
|
|
16292
|
+
const loweredQuery = query.toLowerCase();
|
|
16293
|
+
const skills = marketplace.skills.filter(
|
|
16294
|
+
(skill) => skill.id.toLowerCase().includes(loweredQuery) || skill.displayName.toLowerCase().includes(loweredQuery) || skill.description.toLowerCase().includes(loweredQuery)
|
|
16295
|
+
);
|
|
16296
|
+
return {
|
|
16297
|
+
query,
|
|
16298
|
+
skills,
|
|
16299
|
+
total: skills.length
|
|
16300
|
+
};
|
|
16301
|
+
}
|
|
16302
|
+
async function handleReconcile(store, reconciler) {
|
|
16303
|
+
const [workspaceSkillIds, userSkillIds] = await Promise.all([
|
|
16304
|
+
store.listWorkspaceSkillIds(),
|
|
16305
|
+
store.listUserSkillIds()
|
|
16306
|
+
]);
|
|
16307
|
+
if (workspaceSkillIds.length === 0) {
|
|
16308
|
+
return {
|
|
16309
|
+
changed: false,
|
|
16310
|
+
workspaceSkillIds,
|
|
16311
|
+
userSkillIds,
|
|
16312
|
+
installGate: "open"
|
|
16313
|
+
};
|
|
16314
|
+
}
|
|
16315
|
+
const gateCheck = await reconciler.mutate({
|
|
16316
|
+
skillId: workspaceSkillIds[0],
|
|
16317
|
+
targetScope: "workspace",
|
|
16318
|
+
action: "install",
|
|
16319
|
+
confirmed: false
|
|
16320
|
+
});
|
|
16321
|
+
return {
|
|
16322
|
+
changed: false,
|
|
16323
|
+
workspaceSkillIds,
|
|
16324
|
+
userSkillIds,
|
|
16325
|
+
installGate: gateCheck.status === "requires_confirmation" ? "requires_confirmation" : gateCheck.status === "blocked" ? "blocked" : "open"
|
|
16326
|
+
};
|
|
16327
|
+
}
|
|
16328
|
+
async function handlePublishable(store, workspacePath) {
|
|
16329
|
+
const workspaceSkillIds = await store.listWorkspaceSkillIds();
|
|
16330
|
+
return {
|
|
16331
|
+
skills: workspaceSkillIds.map((skillId) => ({
|
|
16332
|
+
id: skillId,
|
|
16333
|
+
displayName: skillId,
|
|
16334
|
+
path: path11__namespace.join(workspacePath, store.getWorkspaceSkillPath(skillId))
|
|
16335
|
+
}))
|
|
16336
|
+
};
|
|
16337
|
+
}
|
|
16338
|
+
|
|
14513
16339
|
// src/commands/version.ts
|
|
14514
16340
|
init_src();
|
|
14515
16341
|
async function runVersionCommand() {
|
|
@@ -14538,6 +16364,8 @@ function printUsage() {
|
|
|
14538
16364
|
" serviceme env check --json",
|
|
14539
16365
|
" serviceme copilot doctor --json",
|
|
14540
16366
|
" serviceme copilot prompt --prompt <text> [--workspace <path>] [--autopilot] [--allow-tool <tools>] [--timeout <ms>] --json",
|
|
16367
|
+
" serviceme skill <list|install|uninstall|move|marketplace|find|reconcile|publishable> --workspacePath <path> --json",
|
|
16368
|
+
" serviceme agent <list|install|uninstall|move|marketplace|permissions> --workspacePath <path> --json",
|
|
14541
16369
|
" serviceme schedule <create|list|get|edit|delete|toggle|trigger|logs> --workspacePath <path> --json",
|
|
14542
16370
|
" serviceme scheduler <start|stop|status> --workspacePath <path> --json"
|
|
14543
16371
|
].join("\n")}
|
|
@@ -14574,6 +16402,12 @@ async function main() {
|
|
|
14574
16402
|
case "copilot":
|
|
14575
16403
|
await runCopilotCommand(parsed);
|
|
14576
16404
|
return;
|
|
16405
|
+
case "skill":
|
|
16406
|
+
await runSkillCommand(parsed);
|
|
16407
|
+
return;
|
|
16408
|
+
case "agent":
|
|
16409
|
+
await runAgentCommand(parsed);
|
|
16410
|
+
return;
|
|
14577
16411
|
case "schedule":
|
|
14578
16412
|
await runScheduleCommand(parsed);
|
|
14579
16413
|
return;
|