@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/bridgeServer.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var readline = require('readline');
|
|
5
|
+
var fs12 = require('fs/promises');
|
|
6
|
+
var os2 = require('os');
|
|
7
|
+
var path10 = require('path');
|
|
5
8
|
var child_process = require('child_process');
|
|
6
|
-
require('fs
|
|
7
|
-
var path5 = require('path');
|
|
8
|
-
var fs6 = require('fs');
|
|
9
|
-
require('os');
|
|
9
|
+
var fs7 = require('fs');
|
|
10
10
|
require('crypto');
|
|
11
11
|
|
|
12
12
|
function _interopNamespace(e) {
|
|
@@ -28,8 +28,10 @@ function _interopNamespace(e) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
31
|
-
var
|
|
32
|
-
var
|
|
31
|
+
var fs12__namespace = /*#__PURE__*/_interopNamespace(fs12);
|
|
32
|
+
var os2__namespace = /*#__PURE__*/_interopNamespace(os2);
|
|
33
|
+
var path10__namespace = /*#__PURE__*/_interopNamespace(path10);
|
|
34
|
+
var fs7__namespace = /*#__PURE__*/_interopNamespace(fs7);
|
|
33
35
|
|
|
34
36
|
var __create = Object.create;
|
|
35
37
|
var __defProp = Object.defineProperty;
|
|
@@ -550,8 +552,8 @@ var require_esprima = __commonJS({
|
|
|
550
552
|
return result;
|
|
551
553
|
};
|
|
552
554
|
JSXParser2.prototype.lexJSX = function() {
|
|
553
|
-
var
|
|
554
|
-
if (
|
|
555
|
+
var cp3 = this.scanner.source.charCodeAt(this.scanner.index);
|
|
556
|
+
if (cp3 === 60 || cp3 === 62 || cp3 === 47 || cp3 === 58 || cp3 === 61 || cp3 === 123 || cp3 === 125) {
|
|
555
557
|
var value = this.scanner.source[this.scanner.index++];
|
|
556
558
|
return {
|
|
557
559
|
type: 7,
|
|
@@ -562,7 +564,7 @@ var require_esprima = __commonJS({
|
|
|
562
564
|
end: this.scanner.index
|
|
563
565
|
};
|
|
564
566
|
}
|
|
565
|
-
if (
|
|
567
|
+
if (cp3 === 34 || cp3 === 39) {
|
|
566
568
|
var start = this.scanner.index;
|
|
567
569
|
var quote = this.scanner.source[this.scanner.index++];
|
|
568
570
|
var str = "";
|
|
@@ -585,7 +587,7 @@ var require_esprima = __commonJS({
|
|
|
585
587
|
end: this.scanner.index
|
|
586
588
|
};
|
|
587
589
|
}
|
|
588
|
-
if (
|
|
590
|
+
if (cp3 === 46) {
|
|
589
591
|
var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1);
|
|
590
592
|
var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2);
|
|
591
593
|
var value = n1 === 46 && n2 === 46 ? "..." : ".";
|
|
@@ -600,7 +602,7 @@ var require_esprima = __commonJS({
|
|
|
600
602
|
end: this.scanner.index
|
|
601
603
|
};
|
|
602
604
|
}
|
|
603
|
-
if (
|
|
605
|
+
if (cp3 === 96) {
|
|
604
606
|
return {
|
|
605
607
|
type: 10,
|
|
606
608
|
value: "",
|
|
@@ -610,7 +612,7 @@ var require_esprima = __commonJS({
|
|
|
610
612
|
end: this.scanner.index
|
|
611
613
|
};
|
|
612
614
|
}
|
|
613
|
-
if (character_1.Character.isIdentifierStart(
|
|
615
|
+
if (character_1.Character.isIdentifierStart(cp3) && cp3 !== 92) {
|
|
614
616
|
var start = this.scanner.index;
|
|
615
617
|
++this.scanner.index;
|
|
616
618
|
while (!this.scanner.eof()) {
|
|
@@ -939,33 +941,33 @@ var require_esprima = __commonJS({
|
|
|
939
941
|
};
|
|
940
942
|
exports2.Character = {
|
|
941
943
|
/* tslint:disable:no-bitwise */
|
|
942
|
-
fromCodePoint: function(
|
|
943
|
-
return
|
|
944
|
+
fromCodePoint: function(cp3) {
|
|
945
|
+
return cp3 < 65536 ? String.fromCharCode(cp3) : String.fromCharCode(55296 + (cp3 - 65536 >> 10)) + String.fromCharCode(56320 + (cp3 - 65536 & 1023));
|
|
944
946
|
},
|
|
945
947
|
// https://tc39.github.io/ecma262/#sec-white-space
|
|
946
|
-
isWhiteSpace: function(
|
|
947
|
-
return
|
|
948
|
+
isWhiteSpace: function(cp3) {
|
|
949
|
+
return cp3 === 32 || cp3 === 9 || cp3 === 11 || cp3 === 12 || cp3 === 160 || cp3 >= 5760 && [5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279].indexOf(cp3) >= 0;
|
|
948
950
|
},
|
|
949
951
|
// https://tc39.github.io/ecma262/#sec-line-terminators
|
|
950
|
-
isLineTerminator: function(
|
|
951
|
-
return
|
|
952
|
+
isLineTerminator: function(cp3) {
|
|
953
|
+
return cp3 === 10 || cp3 === 13 || cp3 === 8232 || cp3 === 8233;
|
|
952
954
|
},
|
|
953
955
|
// https://tc39.github.io/ecma262/#sec-names-and-keywords
|
|
954
|
-
isIdentifierStart: function(
|
|
955
|
-
return
|
|
956
|
+
isIdentifierStart: function(cp3) {
|
|
957
|
+
return cp3 === 36 || cp3 === 95 || cp3 >= 65 && cp3 <= 90 || cp3 >= 97 && cp3 <= 122 || cp3 === 92 || cp3 >= 128 && Regex.NonAsciiIdentifierStart.test(exports2.Character.fromCodePoint(cp3));
|
|
956
958
|
},
|
|
957
|
-
isIdentifierPart: function(
|
|
958
|
-
return
|
|
959
|
+
isIdentifierPart: function(cp3) {
|
|
960
|
+
return cp3 === 36 || cp3 === 95 || cp3 >= 65 && cp3 <= 90 || cp3 >= 97 && cp3 <= 122 || cp3 >= 48 && cp3 <= 57 || cp3 === 92 || cp3 >= 128 && Regex.NonAsciiIdentifierPart.test(exports2.Character.fromCodePoint(cp3));
|
|
959
961
|
},
|
|
960
962
|
// https://tc39.github.io/ecma262/#sec-literals-numeric-literals
|
|
961
|
-
isDecimalDigit: function(
|
|
962
|
-
return
|
|
963
|
+
isDecimalDigit: function(cp3) {
|
|
964
|
+
return cp3 >= 48 && cp3 <= 57;
|
|
963
965
|
},
|
|
964
|
-
isHexDigit: function(
|
|
965
|
-
return
|
|
966
|
+
isHexDigit: function(cp3) {
|
|
967
|
+
return cp3 >= 48 && cp3 <= 57 || cp3 >= 65 && cp3 <= 70 || cp3 >= 97 && cp3 <= 102;
|
|
966
968
|
},
|
|
967
|
-
isOctalDigit: function(
|
|
968
|
-
return
|
|
969
|
+
isOctalDigit: function(cp3) {
|
|
970
|
+
return cp3 >= 48 && cp3 <= 55;
|
|
969
971
|
}
|
|
970
972
|
};
|
|
971
973
|
},
|
|
@@ -5015,15 +5017,15 @@ var require_esprima = __commonJS({
|
|
|
5015
5017
|
}
|
|
5016
5018
|
};
|
|
5017
5019
|
Scanner2.prototype.codePointAt = function(i) {
|
|
5018
|
-
var
|
|
5019
|
-
if (
|
|
5020
|
+
var cp3 = this.source.charCodeAt(i);
|
|
5021
|
+
if (cp3 >= 55296 && cp3 <= 56319) {
|
|
5020
5022
|
var second = this.source.charCodeAt(i + 1);
|
|
5021
5023
|
if (second >= 56320 && second <= 57343) {
|
|
5022
|
-
var first =
|
|
5023
|
-
|
|
5024
|
+
var first = cp3;
|
|
5025
|
+
cp3 = (first - 55296) * 1024 + second - 56320 + 65536;
|
|
5024
5026
|
}
|
|
5025
5027
|
}
|
|
5026
|
-
return
|
|
5028
|
+
return cp3;
|
|
5027
5029
|
};
|
|
5028
5030
|
Scanner2.prototype.scanHexEscape = function(prefix) {
|
|
5029
5031
|
var len = prefix === "u" ? 4 : 2;
|
|
@@ -5075,11 +5077,11 @@ var require_esprima = __commonJS({
|
|
|
5075
5077
|
return this.source.slice(start, this.index);
|
|
5076
5078
|
};
|
|
5077
5079
|
Scanner2.prototype.getComplexIdentifier = function() {
|
|
5078
|
-
var
|
|
5079
|
-
var id = character_1.Character.fromCodePoint(
|
|
5080
|
+
var cp3 = this.codePointAt(this.index);
|
|
5081
|
+
var id = character_1.Character.fromCodePoint(cp3);
|
|
5080
5082
|
this.index += id.length;
|
|
5081
5083
|
var ch;
|
|
5082
|
-
if (
|
|
5084
|
+
if (cp3 === 92) {
|
|
5083
5085
|
if (this.source.charCodeAt(this.index) !== 117) {
|
|
5084
5086
|
this.throwUnexpectedToken();
|
|
5085
5087
|
}
|
|
@@ -5096,14 +5098,14 @@ var require_esprima = __commonJS({
|
|
|
5096
5098
|
id = ch;
|
|
5097
5099
|
}
|
|
5098
5100
|
while (!this.eof()) {
|
|
5099
|
-
|
|
5100
|
-
if (!character_1.Character.isIdentifierPart(
|
|
5101
|
+
cp3 = this.codePointAt(this.index);
|
|
5102
|
+
if (!character_1.Character.isIdentifierPart(cp3)) {
|
|
5101
5103
|
break;
|
|
5102
5104
|
}
|
|
5103
|
-
ch = character_1.Character.fromCodePoint(
|
|
5105
|
+
ch = character_1.Character.fromCodePoint(cp3);
|
|
5104
5106
|
id += ch;
|
|
5105
5107
|
this.index += ch.length;
|
|
5106
|
-
if (
|
|
5108
|
+
if (cp3 === 92) {
|
|
5107
5109
|
id = id.substr(0, id.length - 1);
|
|
5108
5110
|
if (this.source.charCodeAt(this.index) !== 117) {
|
|
5109
5111
|
this.throwUnexpectedToken();
|
|
@@ -5729,29 +5731,29 @@ var require_esprima = __commonJS({
|
|
|
5729
5731
|
end: this.index
|
|
5730
5732
|
};
|
|
5731
5733
|
}
|
|
5732
|
-
var
|
|
5733
|
-
if (character_1.Character.isIdentifierStart(
|
|
5734
|
+
var cp3 = this.source.charCodeAt(this.index);
|
|
5735
|
+
if (character_1.Character.isIdentifierStart(cp3)) {
|
|
5734
5736
|
return this.scanIdentifier();
|
|
5735
5737
|
}
|
|
5736
|
-
if (
|
|
5738
|
+
if (cp3 === 40 || cp3 === 41 || cp3 === 59) {
|
|
5737
5739
|
return this.scanPunctuator();
|
|
5738
5740
|
}
|
|
5739
|
-
if (
|
|
5741
|
+
if (cp3 === 39 || cp3 === 34) {
|
|
5740
5742
|
return this.scanStringLiteral();
|
|
5741
5743
|
}
|
|
5742
|
-
if (
|
|
5744
|
+
if (cp3 === 46) {
|
|
5743
5745
|
if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) {
|
|
5744
5746
|
return this.scanNumericLiteral();
|
|
5745
5747
|
}
|
|
5746
5748
|
return this.scanPunctuator();
|
|
5747
5749
|
}
|
|
5748
|
-
if (character_1.Character.isDecimalDigit(
|
|
5750
|
+
if (character_1.Character.isDecimalDigit(cp3)) {
|
|
5749
5751
|
return this.scanNumericLiteral();
|
|
5750
5752
|
}
|
|
5751
|
-
if (
|
|
5753
|
+
if (cp3 === 96 || cp3 === 125 && this.curlyStack[this.curlyStack.length - 1] === "${") {
|
|
5752
5754
|
return this.scanTemplate();
|
|
5753
5755
|
}
|
|
5754
|
-
if (
|
|
5756
|
+
if (cp3 >= 55296 && cp3 < 57343) {
|
|
5755
5757
|
if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) {
|
|
5756
5758
|
return this.scanIdentifier();
|
|
5757
5759
|
}
|
|
@@ -7929,10 +7931,10 @@ var require_stringify = __commonJS({
|
|
|
7929
7931
|
replacer = null;
|
|
7930
7932
|
indent = EMPTY;
|
|
7931
7933
|
};
|
|
7932
|
-
var
|
|
7934
|
+
var join12 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + LF + gap : two ? two.trimRight() + LF + gap : EMPTY;
|
|
7933
7935
|
var join_content = (inside, value, gap) => {
|
|
7934
7936
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
7935
|
-
return
|
|
7937
|
+
return join12(comment, inside, gap);
|
|
7936
7938
|
};
|
|
7937
7939
|
var array_stringify = (value, gap) => {
|
|
7938
7940
|
const deeper_gap = gap + indent;
|
|
@@ -7943,7 +7945,7 @@ var require_stringify = __commonJS({
|
|
|
7943
7945
|
if (i !== 0) {
|
|
7944
7946
|
inside += COMMA;
|
|
7945
7947
|
}
|
|
7946
|
-
const before =
|
|
7948
|
+
const before = join12(
|
|
7947
7949
|
after_comma,
|
|
7948
7950
|
process_comments(value, BEFORE(i), deeper_gap),
|
|
7949
7951
|
deeper_gap
|
|
@@ -7953,7 +7955,7 @@ var require_stringify = __commonJS({
|
|
|
7953
7955
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
7954
7956
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
7955
7957
|
}
|
|
7956
|
-
inside +=
|
|
7958
|
+
inside += join12(
|
|
7957
7959
|
after_comma,
|
|
7958
7960
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
7959
7961
|
deeper_gap
|
|
@@ -7978,7 +7980,7 @@ var require_stringify = __commonJS({
|
|
|
7978
7980
|
inside += COMMA;
|
|
7979
7981
|
}
|
|
7980
7982
|
first = false;
|
|
7981
|
-
const before =
|
|
7983
|
+
const before = join12(
|
|
7982
7984
|
after_comma,
|
|
7983
7985
|
process_comments(value, BEFORE(key), deeper_gap),
|
|
7984
7986
|
deeper_gap
|
|
@@ -7988,7 +7990,7 @@ var require_stringify = __commonJS({
|
|
|
7988
7990
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
7989
7991
|
};
|
|
7990
7992
|
keys.forEach(iteratee);
|
|
7991
|
-
inside +=
|
|
7993
|
+
inside += join12(
|
|
7992
7994
|
after_comma,
|
|
7993
7995
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
7994
7996
|
deeper_gap
|
|
@@ -8146,7 +8148,7 @@ var require_pend = __commonJS({
|
|
|
8146
8148
|
// ../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/fd-slicer.js
|
|
8147
8149
|
var require_fd_slicer = __commonJS({
|
|
8148
8150
|
"../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/fd-slicer.js"(exports$1) {
|
|
8149
|
-
var
|
|
8151
|
+
var fs14 = __require("fs");
|
|
8150
8152
|
var util = __require("util");
|
|
8151
8153
|
var stream = __require("stream");
|
|
8152
8154
|
var Readable = stream.Readable;
|
|
@@ -8171,7 +8173,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8171
8173
|
FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
|
|
8172
8174
|
var self = this;
|
|
8173
8175
|
self.pend.go(function(cb) {
|
|
8174
|
-
|
|
8176
|
+
fs14.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) {
|
|
8175
8177
|
cb();
|
|
8176
8178
|
callback(err, bytesRead, buffer2);
|
|
8177
8179
|
});
|
|
@@ -8180,7 +8182,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8180
8182
|
FdSlicer.prototype.write = function(buffer, offset, length, position, callback) {
|
|
8181
8183
|
var self = this;
|
|
8182
8184
|
self.pend.go(function(cb) {
|
|
8183
|
-
|
|
8185
|
+
fs14.write(self.fd, buffer, offset, length, position, function(err, written, buffer2) {
|
|
8184
8186
|
cb();
|
|
8185
8187
|
callback(err, written, buffer2);
|
|
8186
8188
|
});
|
|
@@ -8201,7 +8203,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8201
8203
|
if (self.refCount > 0) return;
|
|
8202
8204
|
if (self.refCount < 0) throw new Error("invalid unref");
|
|
8203
8205
|
if (self.autoClose) {
|
|
8204
|
-
|
|
8206
|
+
fs14.close(self.fd, onCloseDone);
|
|
8205
8207
|
}
|
|
8206
8208
|
function onCloseDone(err) {
|
|
8207
8209
|
if (err) {
|
|
@@ -8238,7 +8240,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8238
8240
|
self.context.pend.go(function(cb) {
|
|
8239
8241
|
if (self.destroyed) return cb();
|
|
8240
8242
|
var buffer = Buffer.allocUnsafe(toRead);
|
|
8241
|
-
|
|
8243
|
+
fs14.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
|
|
8242
8244
|
if (err) {
|
|
8243
8245
|
self.destroy(err);
|
|
8244
8246
|
} else if (bytesRead === 0) {
|
|
@@ -8285,7 +8287,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8285
8287
|
}
|
|
8286
8288
|
self.context.pend.go(function(cb) {
|
|
8287
8289
|
if (self.destroyed) return cb();
|
|
8288
|
-
|
|
8290
|
+
fs14.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err2, bytes) {
|
|
8289
8291
|
if (err2) {
|
|
8290
8292
|
self.destroy();
|
|
8291
8293
|
cb();
|
|
@@ -8723,7 +8725,7 @@ var require_buffer_crc32 = __commonJS({
|
|
|
8723
8725
|
// ../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/index.js
|
|
8724
8726
|
var require_yauzl = __commonJS({
|
|
8725
8727
|
"../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/index.js"(exports$1) {
|
|
8726
|
-
var
|
|
8728
|
+
var fs14 = __require("fs");
|
|
8727
8729
|
var zlib = __require("zlib");
|
|
8728
8730
|
var fd_slicer = require_fd_slicer();
|
|
8729
8731
|
var crc32 = require_buffer_crc32();
|
|
@@ -8744,7 +8746,7 @@ var require_yauzl = __commonJS({
|
|
|
8744
8746
|
exports$1.Entry = Entry;
|
|
8745
8747
|
exports$1.LocalFileHeader = LocalFileHeader;
|
|
8746
8748
|
exports$1.RandomAccessReader = RandomAccessReader;
|
|
8747
|
-
function open2(
|
|
8749
|
+
function open2(path12, options2, callback) {
|
|
8748
8750
|
if (typeof options2 === "function") {
|
|
8749
8751
|
callback = options2;
|
|
8750
8752
|
options2 = null;
|
|
@@ -8756,10 +8758,10 @@ var require_yauzl = __commonJS({
|
|
|
8756
8758
|
if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
|
|
8757
8759
|
if (options2.strictFileNames == null) options2.strictFileNames = false;
|
|
8758
8760
|
if (callback == null) callback = defaultCallback;
|
|
8759
|
-
|
|
8761
|
+
fs14.open(path12, "r", function(err, fd) {
|
|
8760
8762
|
if (err) return callback(err);
|
|
8761
8763
|
fromFd(fd, options2, function(err2, zipfile) {
|
|
8762
|
-
if (err2)
|
|
8764
|
+
if (err2) fs14.close(fd, defaultCallback);
|
|
8763
8765
|
callback(err2, zipfile);
|
|
8764
8766
|
});
|
|
8765
8767
|
});
|
|
@@ -8776,7 +8778,7 @@ var require_yauzl = __commonJS({
|
|
|
8776
8778
|
if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
|
|
8777
8779
|
if (options2.strictFileNames == null) options2.strictFileNames = false;
|
|
8778
8780
|
if (callback == null) callback = defaultCallback;
|
|
8779
|
-
|
|
8781
|
+
fs14.fstat(fd, function(err, stats) {
|
|
8780
8782
|
if (err) return callback(err);
|
|
8781
8783
|
var reader = fd_slicer.createFromFd(fd, { autoClose: true });
|
|
8782
8784
|
fromRandomAccessReader(reader, stats.size, options2, callback);
|
|
@@ -9474,7 +9476,14 @@ var BRIDGE_METHODS = [
|
|
|
9474
9476
|
"system.shutdown",
|
|
9475
9477
|
"task.execute",
|
|
9476
9478
|
"task.cancel",
|
|
9477
|
-
"task.list-running"
|
|
9479
|
+
"task.list-running",
|
|
9480
|
+
"skill.marketplace-state",
|
|
9481
|
+
"skill.mutate",
|
|
9482
|
+
"skill.reconcile",
|
|
9483
|
+
"skill.publishable",
|
|
9484
|
+
"agent.marketplace-state",
|
|
9485
|
+
"agent.mutate",
|
|
9486
|
+
"agent.permissions"
|
|
9478
9487
|
];
|
|
9479
9488
|
function isBridgeMethod(value) {
|
|
9480
9489
|
return typeof value === "string" && BRIDGE_METHODS.includes(value);
|
|
@@ -9600,13 +9609,284 @@ function normalizeServicemeError(error, fallbackCode = "internal_error") {
|
|
|
9600
9609
|
}
|
|
9601
9610
|
|
|
9602
9611
|
// src/version.ts
|
|
9603
|
-
var SERVICEME_CLI_VERSION = "0.1.
|
|
9612
|
+
var SERVICEME_CLI_VERSION = "0.1.6";
|
|
9604
9613
|
|
|
9605
|
-
// src/
|
|
9606
|
-
|
|
9607
|
-
|
|
9608
|
-
|
|
9614
|
+
// ../../packages/serviceme-core/src/agents/AgentCatalogClient.ts
|
|
9615
|
+
var AgentCatalogClient = class {
|
|
9616
|
+
constructor(options2 = {}) {
|
|
9617
|
+
this.fetchImpl = options2.fetchImpl ?? fetch;
|
|
9618
|
+
this.baseUrl = options2.baseUrl;
|
|
9619
|
+
}
|
|
9620
|
+
async getCatalog() {
|
|
9621
|
+
if (!this.baseUrl) {
|
|
9622
|
+
return {
|
|
9623
|
+
agents: [],
|
|
9624
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9625
|
+
};
|
|
9626
|
+
}
|
|
9627
|
+
const response = await this.fetchImpl(
|
|
9628
|
+
`${this.baseUrl}/api/v1/marketplace/agents`
|
|
9629
|
+
);
|
|
9630
|
+
if (!response.ok) {
|
|
9631
|
+
throw new Error(`Failed to fetch agents catalog: ${response.status}`);
|
|
9632
|
+
}
|
|
9633
|
+
const data = await response.json();
|
|
9634
|
+
return {
|
|
9635
|
+
agents: data.agents ?? [],
|
|
9636
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9637
|
+
};
|
|
9638
|
+
}
|
|
9639
|
+
};
|
|
9640
|
+
|
|
9641
|
+
// ../../packages/serviceme-core/src/permissions/agent-permissions.ts
|
|
9642
|
+
var TOOL_RISK_MAP = {
|
|
9643
|
+
shell: "high",
|
|
9644
|
+
terminal: "high",
|
|
9645
|
+
run_in_terminal: "high",
|
|
9646
|
+
execution_subagent: "high",
|
|
9647
|
+
filesystem: "medium",
|
|
9648
|
+
fetch: "medium",
|
|
9649
|
+
fetch_webpage: "medium",
|
|
9650
|
+
create_file: "medium",
|
|
9651
|
+
replace_string_in_file: "medium",
|
|
9652
|
+
multi_replace_string_in_file: "medium",
|
|
9653
|
+
read_file: "low",
|
|
9654
|
+
search: "low",
|
|
9655
|
+
grep_search: "low",
|
|
9656
|
+
file_search: "low",
|
|
9657
|
+
semantic_search: "low",
|
|
9658
|
+
list_dir: "low"
|
|
9659
|
+
};
|
|
9660
|
+
var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
9661
|
+
var TOOLS_LINE_REGEX = /^tools:\s*$/m;
|
|
9662
|
+
var TOOLS_INLINE_REGEX = /^tools:\s*\[([^\]]*)\]/m;
|
|
9663
|
+
var LIST_ITEM_REGEX = /^\s*-\s+(.+)$/;
|
|
9664
|
+
function parseAgentToolPermissions(content) {
|
|
9665
|
+
const fmMatch = content.match(FRONTMATTER_REGEX);
|
|
9666
|
+
if (!fmMatch?.[1]) return [];
|
|
9667
|
+
const frontmatter = fmMatch[1];
|
|
9668
|
+
const inlineMatch = frontmatter.match(TOOLS_INLINE_REGEX);
|
|
9669
|
+
if (inlineMatch?.[1] != null) {
|
|
9670
|
+
const raw = inlineMatch[1];
|
|
9671
|
+
return raw.split(",").map((t) => t.trim()).filter(Boolean).map((tool) => ({
|
|
9672
|
+
tool,
|
|
9673
|
+
riskLevel: TOOL_RISK_MAP[tool] ?? "medium"
|
|
9674
|
+
}));
|
|
9675
|
+
}
|
|
9676
|
+
const blockMatch = frontmatter.match(TOOLS_LINE_REGEX);
|
|
9677
|
+
if (!blockMatch?.[0]) return [];
|
|
9678
|
+
const toolsStartIndex = frontmatter.indexOf(blockMatch[0]) + blockMatch[0].length;
|
|
9679
|
+
const remaining = frontmatter.slice(toolsStartIndex);
|
|
9680
|
+
const lines = remaining.split(/\r?\n/);
|
|
9681
|
+
const tools = [];
|
|
9682
|
+
for (const line of lines) {
|
|
9683
|
+
const itemMatch = line.match(LIST_ITEM_REGEX);
|
|
9684
|
+
if (itemMatch?.[1]) {
|
|
9685
|
+
const tool = itemMatch[1].trim();
|
|
9686
|
+
tools.push({ tool, riskLevel: TOOL_RISK_MAP[tool] ?? "medium" });
|
|
9687
|
+
} else if (line.trim() !== "" && !line.startsWith(" ") && !line.startsWith(" ")) {
|
|
9688
|
+
break;
|
|
9689
|
+
}
|
|
9690
|
+
}
|
|
9691
|
+
return tools;
|
|
9692
|
+
}
|
|
9693
|
+
|
|
9694
|
+
// ../../packages/serviceme-core/src/agents/AgentReconciler.ts
|
|
9695
|
+
var AgentReconciler = class {
|
|
9696
|
+
constructor(deps) {
|
|
9697
|
+
this.deps = deps;
|
|
9698
|
+
}
|
|
9699
|
+
async mutate(request) {
|
|
9700
|
+
if (request.targetScope !== "workspace" && request.targetScope !== "user") {
|
|
9701
|
+
throw new Error(`Invalid target scope: ${String(request.targetScope)}`);
|
|
9702
|
+
}
|
|
9703
|
+
if (request.action === "uninstall" || request.action === "move" || request.action === "removeExternal") {
|
|
9704
|
+
return {
|
|
9705
|
+
status: "success",
|
|
9706
|
+
changed: true,
|
|
9707
|
+
message: `Agent ${request.action} completed.`
|
|
9708
|
+
};
|
|
9709
|
+
}
|
|
9710
|
+
if (request.action !== "install") {
|
|
9711
|
+
return {
|
|
9712
|
+
status: "blocked",
|
|
9713
|
+
changed: false,
|
|
9714
|
+
message: `Agent action is not supported by bridge reconciler: ${request.action}`
|
|
9715
|
+
};
|
|
9716
|
+
}
|
|
9717
|
+
const catalog = await this.deps.catalogClient.getCatalog();
|
|
9718
|
+
const remoteAgent = catalog.agents.find(
|
|
9719
|
+
(agent) => this.deps.agentStore.normalizeRemoteAgentId(agent.id) === request.agentId
|
|
9720
|
+
);
|
|
9721
|
+
if (!remoteAgent) {
|
|
9722
|
+
return {
|
|
9723
|
+
status: "blocked",
|
|
9724
|
+
changed: false,
|
|
9725
|
+
message: "Agent not found in catalog."
|
|
9726
|
+
};
|
|
9727
|
+
}
|
|
9728
|
+
if (!request.confirmed && this.hasHighRiskTool(remoteAgent.tools)) {
|
|
9729
|
+
return {
|
|
9730
|
+
status: "requires_confirmation",
|
|
9731
|
+
changed: false,
|
|
9732
|
+
message: "This agent uses high-risk tools that require confirmation.",
|
|
9733
|
+
tools: remoteAgent.tools
|
|
9734
|
+
};
|
|
9735
|
+
}
|
|
9736
|
+
return {
|
|
9737
|
+
status: "success",
|
|
9738
|
+
changed: true,
|
|
9739
|
+
message: "Agent installed."
|
|
9740
|
+
};
|
|
9741
|
+
}
|
|
9742
|
+
getPermissionSummary(agentId, agentName, content) {
|
|
9743
|
+
const tools = parseAgentToolPermissions(content);
|
|
9744
|
+
return {
|
|
9745
|
+
agentId,
|
|
9746
|
+
agentName,
|
|
9747
|
+
tools,
|
|
9748
|
+
highRiskCount: tools.filter((tool) => tool.riskLevel === "high").length,
|
|
9749
|
+
mediumRiskCount: tools.filter((tool) => tool.riskLevel === "medium").length,
|
|
9750
|
+
lowRiskCount: tools.filter((tool) => tool.riskLevel === "low").length
|
|
9751
|
+
};
|
|
9752
|
+
}
|
|
9753
|
+
hasHighRiskTool(tools) {
|
|
9754
|
+
return tools.some((tool) => TOOL_RISK_MAP[tool] === "high");
|
|
9755
|
+
}
|
|
9756
|
+
};
|
|
9757
|
+
var WORKSPACE_AGENTS_ROOT_RELATIVE = ".github/agents";
|
|
9758
|
+
var WORKSPACE_AGENTS_STATE_RELATIVE = ".github/.ms-devtools-agents.yml";
|
|
9759
|
+
var SAFE_LOCAL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
9760
|
+
function assertSafeLocalAgentId(agentId) {
|
|
9761
|
+
if (typeof agentId !== "string" || agentId.length === 0 || agentId === "." || agentId === ".." || agentId.includes("/") || agentId.includes("\\") || !SAFE_LOCAL_ID_PATTERN.test(agentId)) {
|
|
9762
|
+
throw new Error(`Invalid agent id: ${agentId}`);
|
|
9763
|
+
}
|
|
9764
|
+
return agentId;
|
|
9609
9765
|
}
|
|
9766
|
+
var AgentStore = class {
|
|
9767
|
+
constructor(options2) {
|
|
9768
|
+
this.workspacePath = options2.workspacePath;
|
|
9769
|
+
this.userAgentsRoot = options2.userAgentsRoot;
|
|
9770
|
+
this.fileSystem = options2.fileSystem ?? fs12__namespace;
|
|
9771
|
+
this.schemaVersion = options2.schemaVersion ?? 1;
|
|
9772
|
+
}
|
|
9773
|
+
normalizeRemoteAgentId(remoteId) {
|
|
9774
|
+
if (remoteId.startsWith("official/")) {
|
|
9775
|
+
return assertSafeLocalAgentId(remoteId.slice("official/".length));
|
|
9776
|
+
}
|
|
9777
|
+
if (remoteId.startsWith("community/")) {
|
|
9778
|
+
const lastSlash = remoteId.lastIndexOf("/");
|
|
9779
|
+
return assertSafeLocalAgentId(remoteId.slice(lastSlash + 1));
|
|
9780
|
+
}
|
|
9781
|
+
return assertSafeLocalAgentId(remoteId);
|
|
9782
|
+
}
|
|
9783
|
+
getWorkspaceAgentsRootPath() {
|
|
9784
|
+
return WORKSPACE_AGENTS_ROOT_RELATIVE;
|
|
9785
|
+
}
|
|
9786
|
+
getWorkspaceStateFilePath() {
|
|
9787
|
+
return WORKSPACE_AGENTS_STATE_RELATIVE;
|
|
9788
|
+
}
|
|
9789
|
+
getUserAgentsRootPath() {
|
|
9790
|
+
return this.userAgentsRoot;
|
|
9791
|
+
}
|
|
9792
|
+
async listWorkspaceAgentIds() {
|
|
9793
|
+
return this.listAgentIds(
|
|
9794
|
+
path10__namespace.join(this.workspacePath, WORKSPACE_AGENTS_ROOT_RELATIVE)
|
|
9795
|
+
);
|
|
9796
|
+
}
|
|
9797
|
+
async listUserAgentIds() {
|
|
9798
|
+
return this.listAgentIds(this.userAgentsRoot);
|
|
9799
|
+
}
|
|
9800
|
+
async readState() {
|
|
9801
|
+
try {
|
|
9802
|
+
const raw = await this.fileSystem.readFile(
|
|
9803
|
+
path10__namespace.join(this.workspacePath, WORKSPACE_AGENTS_STATE_RELATIVE),
|
|
9804
|
+
"utf-8"
|
|
9805
|
+
);
|
|
9806
|
+
const parsed = JSON.parse(raw);
|
|
9807
|
+
if (typeof parsed.schemaVersion !== "number" || !Array.isArray(parsed.installedAgents)) {
|
|
9808
|
+
return null;
|
|
9809
|
+
}
|
|
9810
|
+
return parsed;
|
|
9811
|
+
} catch {
|
|
9812
|
+
return null;
|
|
9813
|
+
}
|
|
9814
|
+
}
|
|
9815
|
+
async writeState(state) {
|
|
9816
|
+
const statePath = path10__namespace.join(
|
|
9817
|
+
this.workspacePath,
|
|
9818
|
+
WORKSPACE_AGENTS_STATE_RELATIVE
|
|
9819
|
+
);
|
|
9820
|
+
await this.fileSystem.mkdir(path10__namespace.dirname(statePath), { recursive: true });
|
|
9821
|
+
await this.fileSystem.writeFile(
|
|
9822
|
+
statePath,
|
|
9823
|
+
JSON.stringify(state, null, 2),
|
|
9824
|
+
"utf-8"
|
|
9825
|
+
);
|
|
9826
|
+
}
|
|
9827
|
+
async addInstalledAgent(entry) {
|
|
9828
|
+
const state = await this.readState() ?? {
|
|
9829
|
+
schemaVersion: this.schemaVersion,
|
|
9830
|
+
installedAgents: []
|
|
9831
|
+
};
|
|
9832
|
+
state.installedAgents = state.installedAgents.filter(
|
|
9833
|
+
(agent) => agent.id !== entry.id
|
|
9834
|
+
);
|
|
9835
|
+
state.installedAgents.push(entry);
|
|
9836
|
+
await this.writeState(state);
|
|
9837
|
+
}
|
|
9838
|
+
async removeInstalledAgent(agentId) {
|
|
9839
|
+
const state = await this.readState();
|
|
9840
|
+
if (!state) {
|
|
9841
|
+
return;
|
|
9842
|
+
}
|
|
9843
|
+
state.installedAgents = state.installedAgents.filter(
|
|
9844
|
+
(agent) => agent.id !== agentId
|
|
9845
|
+
);
|
|
9846
|
+
await this.writeState(state);
|
|
9847
|
+
}
|
|
9848
|
+
async writeAgentFiles(agentId, scope, files) {
|
|
9849
|
+
const root = scope === "workspace" ? path10__namespace.join(this.workspacePath, WORKSPACE_AGENTS_ROOT_RELATIVE) : this.userAgentsRoot;
|
|
9850
|
+
const firstFile = files[0];
|
|
9851
|
+
const isSingleFlatFile = files.length === 1 && firstFile !== void 0 && firstFile.path === `${agentId}.agent.md` && !firstFile.path.includes("/");
|
|
9852
|
+
const targetDir = isSingleFlatFile ? root : path10__namespace.join(root, agentId);
|
|
9853
|
+
await this.fileSystem.mkdir(targetDir, { recursive: true });
|
|
9854
|
+
for (const file of files) {
|
|
9855
|
+
const filePath = path10__namespace.join(targetDir, file.path);
|
|
9856
|
+
await this.fileSystem.mkdir(path10__namespace.dirname(filePath), { recursive: true });
|
|
9857
|
+
await this.fileSystem.writeFile(filePath, file.content, "utf-8");
|
|
9858
|
+
if (file.executable) {
|
|
9859
|
+
try {
|
|
9860
|
+
await this.fileSystem.chmod(filePath, 493);
|
|
9861
|
+
} catch {
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9866
|
+
async listAgentIds(dir) {
|
|
9867
|
+
try {
|
|
9868
|
+
const entries = await this.fileSystem.readdir(dir, {
|
|
9869
|
+
withFileTypes: true
|
|
9870
|
+
});
|
|
9871
|
+
const ids = [];
|
|
9872
|
+
for (const entry of entries) {
|
|
9873
|
+
if (entry.name.startsWith(".")) {
|
|
9874
|
+
continue;
|
|
9875
|
+
}
|
|
9876
|
+
if (entry.isDirectory()) {
|
|
9877
|
+
ids.push(entry.name);
|
|
9878
|
+
continue;
|
|
9879
|
+
}
|
|
9880
|
+
if (entry.isFile() && entry.name.endsWith(".agent.md")) {
|
|
9881
|
+
ids.push(entry.name.replace(/\.agent\.md$/, ""));
|
|
9882
|
+
}
|
|
9883
|
+
}
|
|
9884
|
+
return ids.sort();
|
|
9885
|
+
} catch {
|
|
9886
|
+
return [];
|
|
9887
|
+
}
|
|
9888
|
+
}
|
|
9889
|
+
};
|
|
9610
9890
|
function terminateCommandProcess(child) {
|
|
9611
9891
|
if (child.killed) {
|
|
9612
9892
|
return;
|
|
@@ -9755,11 +10035,35 @@ function redactArgs(args) {
|
|
|
9755
10035
|
function writeDiagnostic(message) {
|
|
9756
10036
|
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
9757
10037
|
if (logPath) {
|
|
9758
|
-
|
|
10038
|
+
fs7__namespace.appendFileSync(logPath, message);
|
|
9759
10039
|
return;
|
|
9760
10040
|
}
|
|
9761
10041
|
process.stderr.write(message);
|
|
9762
10042
|
}
|
|
10043
|
+
function resolveGithubCopilotCliExecution(payload) {
|
|
10044
|
+
const args = ["copilot", "prompt", "--prompt", payload.prompt];
|
|
10045
|
+
if (payload.autopilot) {
|
|
10046
|
+
args.push("--autopilot");
|
|
10047
|
+
}
|
|
10048
|
+
if (payload.allowTools && payload.allowTools.length > 0) {
|
|
10049
|
+
args.push("--allow-tools", payload.allowTools.join(","));
|
|
10050
|
+
}
|
|
10051
|
+
if (payload.model) {
|
|
10052
|
+
args.push("--model", payload.model);
|
|
10053
|
+
}
|
|
10054
|
+
if (payload.agent) {
|
|
10055
|
+
args.push("--agent", payload.agent);
|
|
10056
|
+
}
|
|
10057
|
+
args.push("--timeout", String(payload.timeout ?? 0));
|
|
10058
|
+
return {
|
|
10059
|
+
command: "serviceme",
|
|
10060
|
+
args,
|
|
10061
|
+
cwd: payload.workspace,
|
|
10062
|
+
timeoutMs: resolveConfiguredTimeoutMs(payload.timeout, DEFAULT_TIMEOUT_MS),
|
|
10063
|
+
diagnosticArgs: redactArgs(args),
|
|
10064
|
+
promptLen: payload.prompt.length
|
|
10065
|
+
};
|
|
10066
|
+
}
|
|
9763
10067
|
var GithubCopilotCliExecutor = class {
|
|
9764
10068
|
async execute(payload, abortSignal) {
|
|
9765
10069
|
const authenticated = await isCopilotAuthenticated();
|
|
@@ -9782,7 +10086,7 @@ var GithubCopilotCliExecutor = class {
|
|
|
9782
10086
|
}
|
|
9783
10087
|
executeStreaming(payload, onOutput, abortSignal) {
|
|
9784
10088
|
const p = payload;
|
|
9785
|
-
const
|
|
10089
|
+
const execution = resolveGithubCopilotCliExecution(p);
|
|
9786
10090
|
let resolve;
|
|
9787
10091
|
const resultPromise = new Promise((r) => {
|
|
9788
10092
|
resolve = r;
|
|
@@ -9804,26 +10108,12 @@ var GithubCopilotCliExecutor = class {
|
|
|
9804
10108
|
}
|
|
9805
10109
|
};
|
|
9806
10110
|
}
|
|
9807
|
-
const args = ["copilot", "prompt", "--prompt", p.prompt];
|
|
9808
|
-
if (p.autopilot) {
|
|
9809
|
-
args.push("--autopilot");
|
|
9810
|
-
}
|
|
9811
|
-
if (p.allowTools && p.allowTools.length > 0) {
|
|
9812
|
-
args.push("--allow-tools", p.allowTools.join(","));
|
|
9813
|
-
}
|
|
9814
|
-
if (p.model) {
|
|
9815
|
-
args.push("--model", p.model);
|
|
9816
|
-
}
|
|
9817
|
-
if (p.agent) {
|
|
9818
|
-
args.push("--agent", p.agent);
|
|
9819
|
-
}
|
|
9820
|
-
args.push("--timeout", String(p.timeout ?? 0));
|
|
9821
10111
|
writeDiagnostic(
|
|
9822
|
-
`[GithubCopilotCliExecutor] spawn: command
|
|
10112
|
+
`[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}
|
|
9823
10113
|
`
|
|
9824
10114
|
);
|
|
9825
|
-
const child = child_process.spawn(
|
|
9826
|
-
cwd:
|
|
10115
|
+
const child = child_process.spawn(execution.command, execution.args, {
|
|
10116
|
+
cwd: execution.cwd,
|
|
9827
10117
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9828
10118
|
windowsHide: true
|
|
9829
10119
|
});
|
|
@@ -9833,6 +10123,7 @@ var GithubCopilotCliExecutor = class {
|
|
|
9833
10123
|
`
|
|
9834
10124
|
);
|
|
9835
10125
|
}
|
|
10126
|
+
const timeoutMs = execution.timeoutMs;
|
|
9836
10127
|
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9837
10128
|
child.kill("SIGTERM");
|
|
9838
10129
|
setTimeout(() => {
|
|
@@ -9957,7 +10248,7 @@ var POSIX_SHELL_CANDIDATES = ["bash.exe", "sh.exe"];
|
|
|
9957
10248
|
function resolveShellExecution(script, options2 = {}) {
|
|
9958
10249
|
const platform = options2.platform ?? process.platform;
|
|
9959
10250
|
const env = options2.env ?? process.env;
|
|
9960
|
-
const fileExists = options2.fileExists ??
|
|
10251
|
+
const fileExists = options2.fileExists ?? fs7__namespace.existsSync;
|
|
9961
10252
|
if (platform === "win32") {
|
|
9962
10253
|
const posixShell = usesPosixShellSyntax(script) ? findWindowsPosixShell(env, fileExists) : null;
|
|
9963
10254
|
if (posixShell) {
|
|
@@ -10002,10 +10293,10 @@ function findWindowsPosixShell(env, fileExists) {
|
|
|
10002
10293
|
if (fileExists(candidate)) return candidate;
|
|
10003
10294
|
}
|
|
10004
10295
|
const pathValue = env.Path ?? env.PATH ?? "";
|
|
10005
|
-
for (const dir of pathValue.split(
|
|
10296
|
+
for (const dir of pathValue.split(path10__namespace.win32.delimiter)) {
|
|
10006
10297
|
if (!dir) continue;
|
|
10007
10298
|
for (const executable of POSIX_SHELL_CANDIDATES) {
|
|
10008
|
-
const candidate =
|
|
10299
|
+
const candidate = path10__namespace.win32.join(dir, executable);
|
|
10009
10300
|
if (fileExists(candidate) && !isWindowsWslLauncher(candidate)) {
|
|
10010
10301
|
return candidate;
|
|
10011
10302
|
}
|
|
@@ -10014,13 +10305,13 @@ function findWindowsPosixShell(env, fileExists) {
|
|
|
10014
10305
|
return null;
|
|
10015
10306
|
}
|
|
10016
10307
|
function isWindowsWslLauncher(candidate) {
|
|
10017
|
-
const normalized =
|
|
10308
|
+
const normalized = path10__namespace.win32.normalize(candidate).toLowerCase();
|
|
10018
10309
|
return normalized.endsWith("\\windows\\system32\\bash.exe") || normalized.endsWith("\\windows\\syswow64\\bash.exe");
|
|
10019
10310
|
}
|
|
10020
10311
|
function writeDiagnostic2(message) {
|
|
10021
10312
|
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
10022
10313
|
if (logPath) {
|
|
10023
|
-
|
|
10314
|
+
fs7__namespace.appendFileSync(logPath, message);
|
|
10024
10315
|
return;
|
|
10025
10316
|
}
|
|
10026
10317
|
process.stderr.write(message);
|
|
@@ -10380,6 +10671,767 @@ var TaskExecutionEngine = class {
|
|
|
10380
10671
|
}
|
|
10381
10672
|
};
|
|
10382
10673
|
|
|
10674
|
+
// ../../packages/serviceme-core/src/skills/SkillCatalogClient.ts
|
|
10675
|
+
var SkillCatalogClient = class {
|
|
10676
|
+
constructor(options2 = {}) {
|
|
10677
|
+
this.fetchImpl = options2.fetchImpl ?? fetch;
|
|
10678
|
+
this.baseUrl = options2.baseUrl;
|
|
10679
|
+
}
|
|
10680
|
+
async getCatalog() {
|
|
10681
|
+
if (!this.baseUrl) {
|
|
10682
|
+
return {
|
|
10683
|
+
skills: [],
|
|
10684
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10685
|
+
};
|
|
10686
|
+
}
|
|
10687
|
+
const response = await this.fetchImpl(
|
|
10688
|
+
`${this.baseUrl}/api/v1/marketplace/skills`
|
|
10689
|
+
);
|
|
10690
|
+
if (!response.ok) {
|
|
10691
|
+
throw new Error(`Failed to fetch skills catalog: ${response.status}`);
|
|
10692
|
+
}
|
|
10693
|
+
const data = await response.json();
|
|
10694
|
+
return {
|
|
10695
|
+
skills: data.skills ?? [],
|
|
10696
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10697
|
+
};
|
|
10698
|
+
}
|
|
10699
|
+
};
|
|
10700
|
+
|
|
10701
|
+
// ../../packages/serviceme-core/src/skills/SkillReconciler.ts
|
|
10702
|
+
var SkillReconciler = class {
|
|
10703
|
+
constructor(deps) {
|
|
10704
|
+
this.deps = deps;
|
|
10705
|
+
}
|
|
10706
|
+
async mutate(request) {
|
|
10707
|
+
if (request.targetScope !== "workspace" && request.targetScope !== "user") {
|
|
10708
|
+
throw new Error(`Invalid target scope: ${String(request.targetScope)}`);
|
|
10709
|
+
}
|
|
10710
|
+
if (request.action === "uninstall" || request.action === "move" || request.action === "removeExternal") {
|
|
10711
|
+
return {
|
|
10712
|
+
status: "success",
|
|
10713
|
+
changed: true,
|
|
10714
|
+
message: `Skill ${request.action} completed.`
|
|
10715
|
+
};
|
|
10716
|
+
}
|
|
10717
|
+
if (request.action !== "install") {
|
|
10718
|
+
return {
|
|
10719
|
+
status: "blocked",
|
|
10720
|
+
changed: false,
|
|
10721
|
+
message: `Skill action is not supported by bridge reconciler: ${request.action}`
|
|
10722
|
+
};
|
|
10723
|
+
}
|
|
10724
|
+
const catalog = await this.deps.catalogClient.getCatalog();
|
|
10725
|
+
const remoteSkill = catalog.skills.find(
|
|
10726
|
+
(skill) => this.deps.skillStore.normalizeRemoteSkillId(skill.id) === request.skillId
|
|
10727
|
+
);
|
|
10728
|
+
if (!remoteSkill) {
|
|
10729
|
+
return {
|
|
10730
|
+
status: "blocked",
|
|
10731
|
+
changed: false,
|
|
10732
|
+
message: "Skill not found in catalog."
|
|
10733
|
+
};
|
|
10734
|
+
}
|
|
10735
|
+
if (!request.confirmed && (remoteSkill.hasScripts || remoteSkill.hasHooks)) {
|
|
10736
|
+
return {
|
|
10737
|
+
status: "requires_confirmation",
|
|
10738
|
+
changed: false,
|
|
10739
|
+
hasScripts: Boolean(remoteSkill.hasScripts),
|
|
10740
|
+
hasHooks: Boolean(remoteSkill.hasHooks),
|
|
10741
|
+
message: "This skill contains executable scripts that require confirmation."
|
|
10742
|
+
};
|
|
10743
|
+
}
|
|
10744
|
+
return {
|
|
10745
|
+
status: "success",
|
|
10746
|
+
changed: true,
|
|
10747
|
+
message: "Skill installed."
|
|
10748
|
+
};
|
|
10749
|
+
}
|
|
10750
|
+
};
|
|
10751
|
+
var USER_SKILL_MARKER_FILE = ".ms-devtools-skill.json";
|
|
10752
|
+
var WORKSPACE_SKILLS_ROOT_RELATIVE = ".github/skills";
|
|
10753
|
+
var WORKSPACE_SKILLS_MARKER_RELATIVE = ".github/.ms-devtools-skills.yml";
|
|
10754
|
+
var SAFE_LOCAL_ID_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
10755
|
+
function assertSafeLocalSkillId(skillId) {
|
|
10756
|
+
if (typeof skillId !== "string" || skillId.length === 0 || skillId === "." || skillId === ".." || skillId.includes("/") || skillId.includes("\\") || !SAFE_LOCAL_ID_PATTERN2.test(skillId)) {
|
|
10757
|
+
throw new Error(`Invalid skill id: ${skillId}`);
|
|
10758
|
+
}
|
|
10759
|
+
return skillId;
|
|
10760
|
+
}
|
|
10761
|
+
var SkillStore = class {
|
|
10762
|
+
constructor(options2) {
|
|
10763
|
+
this.workspacePath = options2.workspacePath;
|
|
10764
|
+
this.userSkillsRoot = options2.userSkillsRoot;
|
|
10765
|
+
this.fileSystem = options2.fileSystem ?? fs12__namespace;
|
|
10766
|
+
}
|
|
10767
|
+
normalizeRemoteSkillId(remoteId) {
|
|
10768
|
+
if (remoteId.startsWith("official/")) {
|
|
10769
|
+
return assertSafeLocalSkillId(remoteId.slice("official/".length));
|
|
10770
|
+
}
|
|
10771
|
+
if (remoteId.startsWith("community/")) {
|
|
10772
|
+
const lastSlash = remoteId.lastIndexOf("/");
|
|
10773
|
+
return assertSafeLocalSkillId(remoteId.slice(lastSlash + 1));
|
|
10774
|
+
}
|
|
10775
|
+
return assertSafeLocalSkillId(remoteId);
|
|
10776
|
+
}
|
|
10777
|
+
getWorkspaceSkillPath(skillId) {
|
|
10778
|
+
return `${WORKSPACE_SKILLS_ROOT_RELATIVE}/${skillId}`;
|
|
10779
|
+
}
|
|
10780
|
+
getWorkspaceMarkerPath() {
|
|
10781
|
+
return WORKSPACE_SKILLS_MARKER_RELATIVE;
|
|
10782
|
+
}
|
|
10783
|
+
getUserSkillPath(skillId) {
|
|
10784
|
+
return path10__namespace.join(this.userSkillsRoot, skillId);
|
|
10785
|
+
}
|
|
10786
|
+
async listWorkspaceSkillIds() {
|
|
10787
|
+
const skillsRootPath = path10__namespace.join(
|
|
10788
|
+
this.workspacePath,
|
|
10789
|
+
WORKSPACE_SKILLS_ROOT_RELATIVE
|
|
10790
|
+
);
|
|
10791
|
+
try {
|
|
10792
|
+
const entries = await this.fileSystem.readdir(skillsRootPath, {
|
|
10793
|
+
withFileTypes: true
|
|
10794
|
+
});
|
|
10795
|
+
return entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name).sort();
|
|
10796
|
+
} catch {
|
|
10797
|
+
return [];
|
|
10798
|
+
}
|
|
10799
|
+
}
|
|
10800
|
+
async listUserSkillIds() {
|
|
10801
|
+
try {
|
|
10802
|
+
const entries = await this.fileSystem.readdir(this.userSkillsRoot, {
|
|
10803
|
+
withFileTypes: true
|
|
10804
|
+
});
|
|
10805
|
+
return entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name).sort();
|
|
10806
|
+
} catch {
|
|
10807
|
+
return [];
|
|
10808
|
+
}
|
|
10809
|
+
}
|
|
10810
|
+
async writeManagedUserSkillMarker(skillId) {
|
|
10811
|
+
const targetDir = this.getUserSkillPath(skillId);
|
|
10812
|
+
await this.fileSystem.mkdir(targetDir, { recursive: true });
|
|
10813
|
+
await this.fileSystem.writeFile(
|
|
10814
|
+
path10__namespace.join(targetDir, USER_SKILL_MARKER_FILE),
|
|
10815
|
+
JSON.stringify({ skillId, installedBy: "ms-devtools" }, null, 2),
|
|
10816
|
+
"utf-8"
|
|
10817
|
+
);
|
|
10818
|
+
}
|
|
10819
|
+
async isManagedUserSkill(skillId) {
|
|
10820
|
+
try {
|
|
10821
|
+
const marker = await this.fileSystem.readFile(
|
|
10822
|
+
path10__namespace.join(this.getUserSkillPath(skillId), USER_SKILL_MARKER_FILE),
|
|
10823
|
+
"utf-8"
|
|
10824
|
+
);
|
|
10825
|
+
const parsed = JSON.parse(marker);
|
|
10826
|
+
return parsed.skillId === skillId;
|
|
10827
|
+
} catch {
|
|
10828
|
+
return false;
|
|
10829
|
+
}
|
|
10830
|
+
}
|
|
10831
|
+
};
|
|
10832
|
+
|
|
10833
|
+
// src/bridge/AgentBridgeHandler.ts
|
|
10834
|
+
function normalizeAgentIdOrThrow(store, remoteId) {
|
|
10835
|
+
try {
|
|
10836
|
+
return store.normalizeRemoteAgentId(remoteId);
|
|
10837
|
+
} catch {
|
|
10838
|
+
throw createServicemeError("invalid_params", `Invalid agent id: ${remoteId}`);
|
|
10839
|
+
}
|
|
10840
|
+
}
|
|
10841
|
+
var AgentBridgeHandler = class {
|
|
10842
|
+
async getMarketplaceState(params) {
|
|
10843
|
+
const context = this.createContext(params.workspacePath);
|
|
10844
|
+
const [catalog, workspaceAgentIds, userAgentIds] = await Promise.all([
|
|
10845
|
+
context.catalogClient.getCatalog(),
|
|
10846
|
+
context.store.listWorkspaceAgentIds(),
|
|
10847
|
+
context.store.listUserAgentIds()
|
|
10848
|
+
]);
|
|
10849
|
+
const workspaceSet = new Set(workspaceAgentIds);
|
|
10850
|
+
const userSet = new Set(userAgentIds);
|
|
10851
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10852
|
+
const byId = /* @__PURE__ */ new Map();
|
|
10853
|
+
for (const agent of catalog.agents) {
|
|
10854
|
+
const agentId = normalizeAgentIdOrThrow(context.store, agent.id);
|
|
10855
|
+
const workspaceInstalled = workspaceSet.has(agentId);
|
|
10856
|
+
const userInstalled = userSet.has(agentId);
|
|
10857
|
+
byId.set(agentId, {
|
|
10858
|
+
id: agentId,
|
|
10859
|
+
displayName: agent.displayName,
|
|
10860
|
+
description: agent.description,
|
|
10861
|
+
version: agent.version,
|
|
10862
|
+
updatedAt: agent.updatedAt,
|
|
10863
|
+
categoryId: agent.categoryId,
|
|
10864
|
+
isCatalogAgent: true,
|
|
10865
|
+
recommended: agent.recommended,
|
|
10866
|
+
installCount: agent.installCount,
|
|
10867
|
+
ownerScope: agent.ownerScope,
|
|
10868
|
+
ownerKind: agent.ownerKind,
|
|
10869
|
+
hasConflict: agent.hasConflict,
|
|
10870
|
+
tools: agent.tools,
|
|
10871
|
+
source: agent.source,
|
|
10872
|
+
localAgentPath: workspaceInstalled || userInstalled ? workspaceInstalled ? path10__namespace.join(
|
|
10873
|
+
context.workspacePath,
|
|
10874
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
10875
|
+
`${agentId}.agent.md`
|
|
10876
|
+
) : path10__namespace.join(
|
|
10877
|
+
context.store.getUserAgentsRootPath(),
|
|
10878
|
+
`${agentId}.agent.md`
|
|
10879
|
+
) : void 0,
|
|
10880
|
+
canPublish: agent.canPublish,
|
|
10881
|
+
workspaceState: this.makeScopeState(
|
|
10882
|
+
"workspace",
|
|
10883
|
+
workspaceInstalled,
|
|
10884
|
+
path10__namespace.join(
|
|
10885
|
+
context.workspacePath,
|
|
10886
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
10887
|
+
`${agentId}.agent.md`
|
|
10888
|
+
)
|
|
10889
|
+
),
|
|
10890
|
+
userState: this.makeScopeState(
|
|
10891
|
+
"user",
|
|
10892
|
+
userInstalled,
|
|
10893
|
+
path10__namespace.join(
|
|
10894
|
+
context.store.getUserAgentsRootPath(),
|
|
10895
|
+
`${agentId}.agent.md`
|
|
10896
|
+
)
|
|
10897
|
+
)
|
|
10898
|
+
});
|
|
10899
|
+
}
|
|
10900
|
+
for (const agentId of workspaceAgentIds) {
|
|
10901
|
+
if (byId.has(agentId)) {
|
|
10902
|
+
continue;
|
|
10903
|
+
}
|
|
10904
|
+
byId.set(agentId, {
|
|
10905
|
+
id: agentId,
|
|
10906
|
+
displayName: agentId,
|
|
10907
|
+
description: "Local installed agent",
|
|
10908
|
+
version: "0.0.0",
|
|
10909
|
+
updatedAt: now,
|
|
10910
|
+
isCatalogAgent: false,
|
|
10911
|
+
recommended: false,
|
|
10912
|
+
installCount: 0,
|
|
10913
|
+
hasConflict: false,
|
|
10914
|
+
tools: [],
|
|
10915
|
+
source: "local",
|
|
10916
|
+
localAgentPath: path10__namespace.join(
|
|
10917
|
+
context.workspacePath,
|
|
10918
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
10919
|
+
`${agentId}.agent.md`
|
|
10920
|
+
),
|
|
10921
|
+
workspaceState: this.makeScopeState(
|
|
10922
|
+
"workspace",
|
|
10923
|
+
true,
|
|
10924
|
+
path10__namespace.join(
|
|
10925
|
+
context.workspacePath,
|
|
10926
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
10927
|
+
`${agentId}.agent.md`
|
|
10928
|
+
)
|
|
10929
|
+
),
|
|
10930
|
+
userState: this.makeScopeState(
|
|
10931
|
+
"user",
|
|
10932
|
+
userSet.has(agentId),
|
|
10933
|
+
path10__namespace.join(
|
|
10934
|
+
context.store.getUserAgentsRootPath(),
|
|
10935
|
+
`${agentId}.agent.md`
|
|
10936
|
+
)
|
|
10937
|
+
)
|
|
10938
|
+
});
|
|
10939
|
+
}
|
|
10940
|
+
for (const agentId of userAgentIds) {
|
|
10941
|
+
if (byId.has(agentId)) {
|
|
10942
|
+
continue;
|
|
10943
|
+
}
|
|
10944
|
+
byId.set(agentId, {
|
|
10945
|
+
id: agentId,
|
|
10946
|
+
displayName: agentId,
|
|
10947
|
+
description: "Local installed agent",
|
|
10948
|
+
version: "0.0.0",
|
|
10949
|
+
updatedAt: now,
|
|
10950
|
+
isCatalogAgent: false,
|
|
10951
|
+
recommended: false,
|
|
10952
|
+
installCount: 0,
|
|
10953
|
+
hasConflict: false,
|
|
10954
|
+
tools: [],
|
|
10955
|
+
source: "local",
|
|
10956
|
+
localAgentPath: path10__namespace.join(
|
|
10957
|
+
context.store.getUserAgentsRootPath(),
|
|
10958
|
+
`${agentId}.agent.md`
|
|
10959
|
+
),
|
|
10960
|
+
workspaceState: this.makeScopeState(
|
|
10961
|
+
"workspace",
|
|
10962
|
+
workspaceSet.has(agentId),
|
|
10963
|
+
path10__namespace.join(
|
|
10964
|
+
context.workspacePath,
|
|
10965
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
10966
|
+
`${agentId}.agent.md`
|
|
10967
|
+
)
|
|
10968
|
+
),
|
|
10969
|
+
userState: this.makeScopeState(
|
|
10970
|
+
"user",
|
|
10971
|
+
true,
|
|
10972
|
+
path10__namespace.join(
|
|
10973
|
+
context.store.getUserAgentsRootPath(),
|
|
10974
|
+
`${agentId}.agent.md`
|
|
10975
|
+
)
|
|
10976
|
+
)
|
|
10977
|
+
});
|
|
10978
|
+
}
|
|
10979
|
+
return {
|
|
10980
|
+
configPath: path10__namespace.join(
|
|
10981
|
+
context.workspacePath,
|
|
10982
|
+
context.store.getWorkspaceStateFilePath()
|
|
10983
|
+
),
|
|
10984
|
+
userAgentsPath: context.userAgentsRoot,
|
|
10985
|
+
agents: [...byId.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
10986
|
+
installedAgentIds: [.../* @__PURE__ */ new Set([...workspaceAgentIds, ...userAgentIds])],
|
|
10987
|
+
workspaceOpen: true
|
|
10988
|
+
};
|
|
10989
|
+
}
|
|
10990
|
+
async mutate(request) {
|
|
10991
|
+
const context = this.createContext();
|
|
10992
|
+
const agentId = normalizeAgentIdOrThrow(context.store, request.agentId);
|
|
10993
|
+
const mutateResult = await context.reconciler.mutate({
|
|
10994
|
+
...request,
|
|
10995
|
+
agentId
|
|
10996
|
+
});
|
|
10997
|
+
if (mutateResult.status === "success") {
|
|
10998
|
+
await this.applyMutationSideEffect(context, {
|
|
10999
|
+
...request,
|
|
11000
|
+
agentId
|
|
11001
|
+
});
|
|
11002
|
+
}
|
|
11003
|
+
return {
|
|
11004
|
+
state: await this.getMarketplaceState({
|
|
11005
|
+
workspacePath: context.workspacePath
|
|
11006
|
+
}),
|
|
11007
|
+
agentId,
|
|
11008
|
+
targetScope: request.targetScope,
|
|
11009
|
+
action: request.action,
|
|
11010
|
+
changed: mutateResult.changed,
|
|
11011
|
+
status: mutateResult.status,
|
|
11012
|
+
message: mutateResult.message,
|
|
11013
|
+
tools: mutateResult.tools
|
|
11014
|
+
};
|
|
11015
|
+
}
|
|
11016
|
+
async permissions(params) {
|
|
11017
|
+
const context = this.createContext();
|
|
11018
|
+
const agentId = normalizeAgentIdOrThrow(context.store, params.agentId);
|
|
11019
|
+
const scope = params.scope ?? "workspace";
|
|
11020
|
+
const content = await this.readAgentContent(context, agentId, scope);
|
|
11021
|
+
return context.reconciler.getPermissionSummary(agentId, agentId, content);
|
|
11022
|
+
}
|
|
11023
|
+
createContext(workspacePath) {
|
|
11024
|
+
const resolvedWorkspacePath = workspacePath ?? process.cwd();
|
|
11025
|
+
const userAgentsRoot = path10__namespace.join(os2__namespace.homedir(), ".copilot", "agents");
|
|
11026
|
+
const store = new AgentStore({
|
|
11027
|
+
workspacePath: resolvedWorkspacePath,
|
|
11028
|
+
userAgentsRoot
|
|
11029
|
+
});
|
|
11030
|
+
const catalogClient = new AgentCatalogClient();
|
|
11031
|
+
const reconciler = new AgentReconciler({
|
|
11032
|
+
agentStore: store,
|
|
11033
|
+
catalogClient
|
|
11034
|
+
});
|
|
11035
|
+
return {
|
|
11036
|
+
workspacePath: resolvedWorkspacePath,
|
|
11037
|
+
userAgentsRoot,
|
|
11038
|
+
store,
|
|
11039
|
+
catalogClient,
|
|
11040
|
+
reconciler
|
|
11041
|
+
};
|
|
11042
|
+
}
|
|
11043
|
+
makeScopeState(scope, installed, agentPath) {
|
|
11044
|
+
if (installed) {
|
|
11045
|
+
return {
|
|
11046
|
+
scope,
|
|
11047
|
+
status: "installed",
|
|
11048
|
+
path: agentPath,
|
|
11049
|
+
isInstalled: true,
|
|
11050
|
+
canInstall: false,
|
|
11051
|
+
canUninstall: true,
|
|
11052
|
+
canRemove: false,
|
|
11053
|
+
canMoveHere: false
|
|
11054
|
+
};
|
|
11055
|
+
}
|
|
11056
|
+
return {
|
|
11057
|
+
scope,
|
|
11058
|
+
status: "absent",
|
|
11059
|
+
isInstalled: false,
|
|
11060
|
+
canInstall: true,
|
|
11061
|
+
canUninstall: false,
|
|
11062
|
+
canRemove: false,
|
|
11063
|
+
canMoveHere: true
|
|
11064
|
+
};
|
|
11065
|
+
}
|
|
11066
|
+
async applyMutationSideEffect(context, request) {
|
|
11067
|
+
const workspaceFlatPath = path10__namespace.join(
|
|
11068
|
+
context.workspacePath,
|
|
11069
|
+
context.store.getWorkspaceAgentsRootPath(),
|
|
11070
|
+
`${request.agentId}.agent.md`
|
|
11071
|
+
);
|
|
11072
|
+
const userFlatPath = path10__namespace.join(
|
|
11073
|
+
context.store.getUserAgentsRootPath(),
|
|
11074
|
+
`${request.agentId}.agent.md`
|
|
11075
|
+
);
|
|
11076
|
+
switch (request.action) {
|
|
11077
|
+
case "install":
|
|
11078
|
+
if (request.targetScope === "workspace") {
|
|
11079
|
+
await this.writeDefaultAgentFile(workspaceFlatPath, request.agentId);
|
|
11080
|
+
} else {
|
|
11081
|
+
await this.writeDefaultAgentFile(userFlatPath, request.agentId);
|
|
11082
|
+
}
|
|
11083
|
+
return;
|
|
11084
|
+
case "uninstall":
|
|
11085
|
+
if (request.targetScope === "workspace") {
|
|
11086
|
+
await fs12__namespace.rm(workspaceFlatPath, { recursive: true, force: true });
|
|
11087
|
+
} else {
|
|
11088
|
+
await fs12__namespace.rm(userFlatPath, { recursive: true, force: true });
|
|
11089
|
+
}
|
|
11090
|
+
return;
|
|
11091
|
+
case "move":
|
|
11092
|
+
if (request.targetScope === "workspace") {
|
|
11093
|
+
await this.moveEntry(userFlatPath, workspaceFlatPath);
|
|
11094
|
+
} else {
|
|
11095
|
+
await this.moveEntry(workspaceFlatPath, userFlatPath);
|
|
11096
|
+
}
|
|
11097
|
+
return;
|
|
11098
|
+
default:
|
|
11099
|
+
return;
|
|
11100
|
+
}
|
|
11101
|
+
}
|
|
11102
|
+
async moveEntry(fromPath, toPath) {
|
|
11103
|
+
await fs12__namespace.mkdir(path10__namespace.dirname(toPath), { recursive: true });
|
|
11104
|
+
try {
|
|
11105
|
+
await fs12__namespace.rename(fromPath, toPath);
|
|
11106
|
+
} catch {
|
|
11107
|
+
await fs12__namespace.cp(fromPath, toPath, { recursive: true });
|
|
11108
|
+
await fs12__namespace.rm(fromPath, { recursive: true, force: true });
|
|
11109
|
+
}
|
|
11110
|
+
}
|
|
11111
|
+
async writeDefaultAgentFile(targetPath, agentId) {
|
|
11112
|
+
await fs12__namespace.mkdir(path10__namespace.dirname(targetPath), { recursive: true });
|
|
11113
|
+
await fs12__namespace.writeFile(
|
|
11114
|
+
targetPath,
|
|
11115
|
+
`---
|
|
11116
|
+
name: ${agentId}
|
|
11117
|
+
tools:
|
|
11118
|
+
- run_in_terminal
|
|
11119
|
+
- read_file
|
|
11120
|
+
---
|
|
11121
|
+
|
|
11122
|
+
# ${agentId}
|
|
11123
|
+
`,
|
|
11124
|
+
"utf8"
|
|
11125
|
+
);
|
|
11126
|
+
}
|
|
11127
|
+
async readAgentContent(context, agentId, scope) {
|
|
11128
|
+
const root = scope === "workspace" ? path10__namespace.join(
|
|
11129
|
+
context.workspacePath,
|
|
11130
|
+
context.store.getWorkspaceAgentsRootPath()
|
|
11131
|
+
) : context.store.getUserAgentsRootPath();
|
|
11132
|
+
const candidates = [
|
|
11133
|
+
path10__namespace.join(root, `${agentId}.agent.md`),
|
|
11134
|
+
path10__namespace.join(root, agentId, `${agentId}.agent.md`)
|
|
11135
|
+
];
|
|
11136
|
+
for (const candidate of candidates) {
|
|
11137
|
+
try {
|
|
11138
|
+
return await fs12__namespace.readFile(candidate, "utf8");
|
|
11139
|
+
} catch {
|
|
11140
|
+
}
|
|
11141
|
+
}
|
|
11142
|
+
throw createServicemeError(
|
|
11143
|
+
"not_found",
|
|
11144
|
+
`Agent file not found for ${agentId} in ${scope} scope.`
|
|
11145
|
+
);
|
|
11146
|
+
}
|
|
11147
|
+
};
|
|
11148
|
+
|
|
11149
|
+
// src/bridge/ndjson.ts
|
|
11150
|
+
function writeBridgeMessage(message) {
|
|
11151
|
+
process.stdout.write(`${JSON.stringify(message)}
|
|
11152
|
+
`);
|
|
11153
|
+
}
|
|
11154
|
+
function normalizeSkillIdOrThrow(store, remoteId) {
|
|
11155
|
+
try {
|
|
11156
|
+
return store.normalizeRemoteSkillId(remoteId);
|
|
11157
|
+
} catch {
|
|
11158
|
+
throw createServicemeError("invalid_params", `Invalid skill id: ${remoteId}`);
|
|
11159
|
+
}
|
|
11160
|
+
}
|
|
11161
|
+
var SkillBridgeHandler = class {
|
|
11162
|
+
async getMarketplaceState(params) {
|
|
11163
|
+
const context = this.createContext(params.workspacePath);
|
|
11164
|
+
const [catalog, workspaceSkillIds, userSkillIds] = await Promise.all([
|
|
11165
|
+
context.catalogClient.getCatalog(),
|
|
11166
|
+
context.store.listWorkspaceSkillIds(),
|
|
11167
|
+
context.store.listUserSkillIds()
|
|
11168
|
+
]);
|
|
11169
|
+
const workspaceSet = new Set(workspaceSkillIds);
|
|
11170
|
+
const userSet = new Set(userSkillIds);
|
|
11171
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11172
|
+
const byId = /* @__PURE__ */ new Map();
|
|
11173
|
+
for (const skill of catalog.skills) {
|
|
11174
|
+
const skillId = normalizeSkillIdOrThrow(context.store, skill.id);
|
|
11175
|
+
const workspaceInstalled = workspaceSet.has(skillId);
|
|
11176
|
+
const userInstalled = userSet.has(skillId);
|
|
11177
|
+
byId.set(skillId, {
|
|
11178
|
+
id: skillId,
|
|
11179
|
+
displayName: skill.displayName,
|
|
11180
|
+
description: skill.description,
|
|
11181
|
+
version: skill.version,
|
|
11182
|
+
updatedAt: skill.updatedAt,
|
|
11183
|
+
categoryId: skill.categoryId,
|
|
11184
|
+
enabled: skill.enabled,
|
|
11185
|
+
isCatalogSkill: true,
|
|
11186
|
+
recommended: skill.recommended,
|
|
11187
|
+
installCount: skill.installCount,
|
|
11188
|
+
requiresSetup: skill.requiresSetup,
|
|
11189
|
+
setupHint: skill.setupHint,
|
|
11190
|
+
homepage: skill.homepage,
|
|
11191
|
+
ownerScope: skill.ownerScope,
|
|
11192
|
+
ownerKind: skill.ownerKind,
|
|
11193
|
+
hasConflict: skill.hasConflict,
|
|
11194
|
+
hasScripts: skill.hasScripts,
|
|
11195
|
+
hasHooks: skill.hasHooks,
|
|
11196
|
+
source: skill.source,
|
|
11197
|
+
localSkillPath: workspaceInstalled || userInstalled ? workspaceInstalled ? path10__namespace.join(
|
|
11198
|
+
context.workspacePath,
|
|
11199
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
11200
|
+
) : context.store.getUserSkillPath(skillId) : void 0,
|
|
11201
|
+
canPublish: skill.canPublish,
|
|
11202
|
+
workspaceState: this.makeScopeState(
|
|
11203
|
+
"workspace",
|
|
11204
|
+
workspaceInstalled,
|
|
11205
|
+
path10__namespace.join(
|
|
11206
|
+
context.workspacePath,
|
|
11207
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
11208
|
+
)
|
|
11209
|
+
),
|
|
11210
|
+
userState: this.makeScopeState(
|
|
11211
|
+
"user",
|
|
11212
|
+
userInstalled,
|
|
11213
|
+
context.store.getUserSkillPath(skillId)
|
|
11214
|
+
)
|
|
11215
|
+
});
|
|
11216
|
+
}
|
|
11217
|
+
for (const skillId of workspaceSkillIds) {
|
|
11218
|
+
if (byId.has(skillId)) {
|
|
11219
|
+
continue;
|
|
11220
|
+
}
|
|
11221
|
+
byId.set(skillId, {
|
|
11222
|
+
id: skillId,
|
|
11223
|
+
displayName: skillId,
|
|
11224
|
+
description: "Local installed skill",
|
|
11225
|
+
version: "0.0.0",
|
|
11226
|
+
updatedAt: now,
|
|
11227
|
+
isCatalogSkill: false,
|
|
11228
|
+
recommended: false,
|
|
11229
|
+
installCount: 0,
|
|
11230
|
+
hasConflict: false,
|
|
11231
|
+
source: "local",
|
|
11232
|
+
localSkillPath: path10__namespace.join(
|
|
11233
|
+
context.workspacePath,
|
|
11234
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
11235
|
+
),
|
|
11236
|
+
workspaceState: this.makeScopeState(
|
|
11237
|
+
"workspace",
|
|
11238
|
+
true,
|
|
11239
|
+
path10__namespace.join(
|
|
11240
|
+
context.workspacePath,
|
|
11241
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
11242
|
+
)
|
|
11243
|
+
),
|
|
11244
|
+
userState: this.makeScopeState(
|
|
11245
|
+
"user",
|
|
11246
|
+
userSet.has(skillId),
|
|
11247
|
+
context.store.getUserSkillPath(skillId)
|
|
11248
|
+
)
|
|
11249
|
+
});
|
|
11250
|
+
}
|
|
11251
|
+
for (const skillId of userSkillIds) {
|
|
11252
|
+
if (byId.has(skillId)) {
|
|
11253
|
+
continue;
|
|
11254
|
+
}
|
|
11255
|
+
byId.set(skillId, {
|
|
11256
|
+
id: skillId,
|
|
11257
|
+
displayName: skillId,
|
|
11258
|
+
description: "Local installed skill",
|
|
11259
|
+
version: "0.0.0",
|
|
11260
|
+
updatedAt: now,
|
|
11261
|
+
isCatalogSkill: false,
|
|
11262
|
+
recommended: false,
|
|
11263
|
+
installCount: 0,
|
|
11264
|
+
hasConflict: false,
|
|
11265
|
+
source: "local",
|
|
11266
|
+
localSkillPath: context.store.getUserSkillPath(skillId),
|
|
11267
|
+
workspaceState: this.makeScopeState(
|
|
11268
|
+
"workspace",
|
|
11269
|
+
workspaceSet.has(skillId),
|
|
11270
|
+
path10__namespace.join(
|
|
11271
|
+
context.workspacePath,
|
|
11272
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
11273
|
+
)
|
|
11274
|
+
),
|
|
11275
|
+
userState: this.makeScopeState(
|
|
11276
|
+
"user",
|
|
11277
|
+
true,
|
|
11278
|
+
context.store.getUserSkillPath(skillId)
|
|
11279
|
+
)
|
|
11280
|
+
});
|
|
11281
|
+
}
|
|
11282
|
+
return {
|
|
11283
|
+
configPath: path10__namespace.join(
|
|
11284
|
+
context.workspacePath,
|
|
11285
|
+
context.store.getWorkspaceMarkerPath()
|
|
11286
|
+
),
|
|
11287
|
+
userSkillsPath: context.userSkillsRoot,
|
|
11288
|
+
skills: [...byId.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
11289
|
+
enabledSkillIds: [],
|
|
11290
|
+
recommendedSkillIds: catalog.skills.filter((skill) => skill.recommended).map((skill) => context.store.normalizeRemoteSkillId(skill.id)),
|
|
11291
|
+
onboardingRequired: false,
|
|
11292
|
+
hasPersistedSelection: false,
|
|
11293
|
+
workspaceOpen: true
|
|
11294
|
+
};
|
|
11295
|
+
}
|
|
11296
|
+
async mutate(request) {
|
|
11297
|
+
const context = this.createContext();
|
|
11298
|
+
const skillId = normalizeSkillIdOrThrow(context.store, request.skillId);
|
|
11299
|
+
const mutateResult = await context.reconciler.mutate({
|
|
11300
|
+
...request,
|
|
11301
|
+
skillId
|
|
11302
|
+
});
|
|
11303
|
+
if (mutateResult.status === "success") {
|
|
11304
|
+
await this.applyMutationSideEffect(context, {
|
|
11305
|
+
...request,
|
|
11306
|
+
skillId
|
|
11307
|
+
});
|
|
11308
|
+
}
|
|
11309
|
+
return {
|
|
11310
|
+
state: await this.getMarketplaceState({
|
|
11311
|
+
workspacePath: context.workspacePath
|
|
11312
|
+
}),
|
|
11313
|
+
skillId,
|
|
11314
|
+
targetScope: request.targetScope,
|
|
11315
|
+
action: request.action,
|
|
11316
|
+
changed: mutateResult.changed,
|
|
11317
|
+
status: mutateResult.status,
|
|
11318
|
+
message: mutateResult.message,
|
|
11319
|
+
hasScripts: mutateResult.hasScripts,
|
|
11320
|
+
hasHooks: mutateResult.hasHooks
|
|
11321
|
+
};
|
|
11322
|
+
}
|
|
11323
|
+
async reconcile(params) {
|
|
11324
|
+
const state = await this.getMarketplaceState({
|
|
11325
|
+
workspacePath: params.workspacePath,
|
|
11326
|
+
forceRefresh: params.force
|
|
11327
|
+
});
|
|
11328
|
+
return {
|
|
11329
|
+
state,
|
|
11330
|
+
changed: false
|
|
11331
|
+
};
|
|
11332
|
+
}
|
|
11333
|
+
async publishable(params) {
|
|
11334
|
+
const context = this.createContext(params.workspacePath);
|
|
11335
|
+
const workspaceSkillIds = await context.store.listWorkspaceSkillIds();
|
|
11336
|
+
return {
|
|
11337
|
+
skills: workspaceSkillIds.map((skillId) => ({
|
|
11338
|
+
id: skillId,
|
|
11339
|
+
displayName: skillId,
|
|
11340
|
+
path: path10__namespace.join(
|
|
11341
|
+
context.workspacePath,
|
|
11342
|
+
context.store.getWorkspaceSkillPath(skillId)
|
|
11343
|
+
)
|
|
11344
|
+
}))
|
|
11345
|
+
};
|
|
11346
|
+
}
|
|
11347
|
+
createContext(workspacePath) {
|
|
11348
|
+
const resolvedWorkspacePath = workspacePath ?? process.cwd();
|
|
11349
|
+
const userSkillsRoot = path10__namespace.join(os2__namespace.homedir(), ".agents", "skills");
|
|
11350
|
+
const store = new SkillStore({
|
|
11351
|
+
workspacePath: resolvedWorkspacePath,
|
|
11352
|
+
userSkillsRoot
|
|
11353
|
+
});
|
|
11354
|
+
const catalogClient = new SkillCatalogClient();
|
|
11355
|
+
const reconciler = new SkillReconciler({
|
|
11356
|
+
skillStore: store,
|
|
11357
|
+
catalogClient
|
|
11358
|
+
});
|
|
11359
|
+
return {
|
|
11360
|
+
workspacePath: resolvedWorkspacePath,
|
|
11361
|
+
userSkillsRoot,
|
|
11362
|
+
store,
|
|
11363
|
+
catalogClient,
|
|
11364
|
+
reconciler
|
|
11365
|
+
};
|
|
11366
|
+
}
|
|
11367
|
+
makeScopeState(scope, installed, skillPath) {
|
|
11368
|
+
if (installed) {
|
|
11369
|
+
return {
|
|
11370
|
+
scope,
|
|
11371
|
+
status: "installed",
|
|
11372
|
+
path: skillPath,
|
|
11373
|
+
isInstalled: true,
|
|
11374
|
+
canInstall: false,
|
|
11375
|
+
canUninstall: true,
|
|
11376
|
+
canRemove: false,
|
|
11377
|
+
canMoveHere: false
|
|
11378
|
+
};
|
|
11379
|
+
}
|
|
11380
|
+
return {
|
|
11381
|
+
scope,
|
|
11382
|
+
status: "absent",
|
|
11383
|
+
isInstalled: false,
|
|
11384
|
+
canInstall: true,
|
|
11385
|
+
canUninstall: false,
|
|
11386
|
+
canRemove: false,
|
|
11387
|
+
canMoveHere: true
|
|
11388
|
+
};
|
|
11389
|
+
}
|
|
11390
|
+
async applyMutationSideEffect(context, request) {
|
|
11391
|
+
const workspaceSkillPath = path10__namespace.join(
|
|
11392
|
+
context.workspacePath,
|
|
11393
|
+
context.store.getWorkspaceSkillPath(request.skillId)
|
|
11394
|
+
);
|
|
11395
|
+
const userSkillPath = context.store.getUserSkillPath(request.skillId);
|
|
11396
|
+
switch (request.action) {
|
|
11397
|
+
case "install":
|
|
11398
|
+
if (request.targetScope === "workspace") {
|
|
11399
|
+
await fs12__namespace.mkdir(workspaceSkillPath, { recursive: true });
|
|
11400
|
+
} else {
|
|
11401
|
+
await fs12__namespace.mkdir(userSkillPath, { recursive: true });
|
|
11402
|
+
await context.store.writeManagedUserSkillMarker(request.skillId);
|
|
11403
|
+
}
|
|
11404
|
+
return;
|
|
11405
|
+
case "uninstall":
|
|
11406
|
+
if (request.targetScope === "workspace") {
|
|
11407
|
+
await fs12__namespace.rm(workspaceSkillPath, { recursive: true, force: true });
|
|
11408
|
+
} else {
|
|
11409
|
+
await fs12__namespace.rm(userSkillPath, { recursive: true, force: true });
|
|
11410
|
+
}
|
|
11411
|
+
return;
|
|
11412
|
+
case "move":
|
|
11413
|
+
if (request.targetScope === "workspace") {
|
|
11414
|
+
await this.moveDirectory(userSkillPath, workspaceSkillPath);
|
|
11415
|
+
} else {
|
|
11416
|
+
await this.moveDirectory(workspaceSkillPath, userSkillPath);
|
|
11417
|
+
await context.store.writeManagedUserSkillMarker(request.skillId);
|
|
11418
|
+
}
|
|
11419
|
+
return;
|
|
11420
|
+
default:
|
|
11421
|
+
return;
|
|
11422
|
+
}
|
|
11423
|
+
}
|
|
11424
|
+
async moveDirectory(fromPath, toPath) {
|
|
11425
|
+
await fs12__namespace.mkdir(path10__namespace.dirname(toPath), { recursive: true });
|
|
11426
|
+
try {
|
|
11427
|
+
await fs12__namespace.rename(fromPath, toPath);
|
|
11428
|
+
} catch {
|
|
11429
|
+
await fs12__namespace.cp(fromPath, toPath, { recursive: true });
|
|
11430
|
+
await fs12__namespace.rm(fromPath, { recursive: true, force: true });
|
|
11431
|
+
}
|
|
11432
|
+
}
|
|
11433
|
+
};
|
|
11434
|
+
|
|
10383
11435
|
// src/bridge/TaskBridgeHandler.ts
|
|
10384
11436
|
var TaskBridgeHandler = class {
|
|
10385
11437
|
constructor(logger, emitEvent) {
|
|
@@ -10427,7 +11479,9 @@ var CAPABILITIES = {
|
|
|
10427
11479
|
bridge: true,
|
|
10428
11480
|
json: 1,
|
|
10429
11481
|
env: 1,
|
|
10430
|
-
tasks: 1
|
|
11482
|
+
tasks: 1,
|
|
11483
|
+
skills: 1,
|
|
11484
|
+
agents: 1
|
|
10431
11485
|
};
|
|
10432
11486
|
var BridgeServer = class {
|
|
10433
11487
|
constructor(logger) {
|
|
@@ -10436,6 +11490,8 @@ var BridgeServer = class {
|
|
|
10436
11490
|
this.taskHandler = new TaskBridgeHandler(logger, (event, params) => {
|
|
10437
11491
|
this.writeEvent(event, params);
|
|
10438
11492
|
});
|
|
11493
|
+
this.skillHandler = new SkillBridgeHandler();
|
|
11494
|
+
this.agentHandler = new AgentBridgeHandler();
|
|
10439
11495
|
}
|
|
10440
11496
|
async run() {
|
|
10441
11497
|
const reader = readline__namespace.createInterface({
|
|
@@ -10541,6 +11597,56 @@ var BridgeServer = class {
|
|
|
10541
11597
|
this.writeSuccess(request.id, result);
|
|
10542
11598
|
return;
|
|
10543
11599
|
}
|
|
11600
|
+
case "skill.marketplace-state": {
|
|
11601
|
+
const skillRequest = request;
|
|
11602
|
+
const result = await this.skillHandler.getMarketplaceState(
|
|
11603
|
+
skillRequest.params
|
|
11604
|
+
);
|
|
11605
|
+
this.writeSuccess(request.id, result);
|
|
11606
|
+
return;
|
|
11607
|
+
}
|
|
11608
|
+
case "skill.mutate": {
|
|
11609
|
+
const skillRequest = request;
|
|
11610
|
+
const result = await this.skillHandler.mutate(skillRequest.params);
|
|
11611
|
+
this.writeSuccess(request.id, result);
|
|
11612
|
+
return;
|
|
11613
|
+
}
|
|
11614
|
+
case "skill.reconcile": {
|
|
11615
|
+
const skillRequest = request;
|
|
11616
|
+
const result = await this.skillHandler.reconcile(skillRequest.params);
|
|
11617
|
+
this.writeSuccess(request.id, result);
|
|
11618
|
+
return;
|
|
11619
|
+
}
|
|
11620
|
+
case "skill.publishable": {
|
|
11621
|
+
const skillRequest = request;
|
|
11622
|
+
const result = await this.skillHandler.publishable(
|
|
11623
|
+
skillRequest.params
|
|
11624
|
+
);
|
|
11625
|
+
this.writeSuccess(request.id, result);
|
|
11626
|
+
return;
|
|
11627
|
+
}
|
|
11628
|
+
case "agent.marketplace-state": {
|
|
11629
|
+
const agentRequest = request;
|
|
11630
|
+
const result = await this.agentHandler.getMarketplaceState(
|
|
11631
|
+
agentRequest.params
|
|
11632
|
+
);
|
|
11633
|
+
this.writeSuccess(request.id, result);
|
|
11634
|
+
return;
|
|
11635
|
+
}
|
|
11636
|
+
case "agent.mutate": {
|
|
11637
|
+
const agentRequest = request;
|
|
11638
|
+
const result = await this.agentHandler.mutate(agentRequest.params);
|
|
11639
|
+
this.writeSuccess(request.id, result);
|
|
11640
|
+
return;
|
|
11641
|
+
}
|
|
11642
|
+
case "agent.permissions": {
|
|
11643
|
+
const agentRequest = request;
|
|
11644
|
+
const result = await this.agentHandler.permissions(
|
|
11645
|
+
agentRequest.params
|
|
11646
|
+
);
|
|
11647
|
+
this.writeSuccess(request.id, result);
|
|
11648
|
+
return;
|
|
11649
|
+
}
|
|
10544
11650
|
default:
|
|
10545
11651
|
this.writeError(
|
|
10546
11652
|
request.id,
|