@neta-art/neta-search-cli 0.2.16 → 0.2.20
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/README.md +13 -9
- package/neta-search.mjs +393 -244
- package/package.json +1 -1
package/neta-search.mjs
CHANGED
|
@@ -7021,8 +7021,8 @@ var require_util2 = __commonJS({
|
|
|
7021
7021
|
function createDeferredPromise() {
|
|
7022
7022
|
let res;
|
|
7023
7023
|
let rej;
|
|
7024
|
-
const promise = new Promise((
|
|
7025
|
-
res =
|
|
7024
|
+
const promise = new Promise((resolve2, reject) => {
|
|
7025
|
+
res = resolve2;
|
|
7026
7026
|
rej = reject;
|
|
7027
7027
|
});
|
|
7028
7028
|
return { promise, resolve: res, reject: rej };
|
|
@@ -8526,8 +8526,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
8526
8526
|
});
|
|
8527
8527
|
}
|
|
8528
8528
|
});
|
|
8529
|
-
const busboyResolve = new Promise((
|
|
8530
|
-
busboy.on("finish",
|
|
8529
|
+
const busboyResolve = new Promise((resolve2, reject) => {
|
|
8530
|
+
busboy.on("finish", resolve2);
|
|
8531
8531
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
8532
8532
|
});
|
|
8533
8533
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -9061,9 +9061,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
9061
9061
|
}
|
|
9062
9062
|
close(callback) {
|
|
9063
9063
|
if (callback === void 0) {
|
|
9064
|
-
return new Promise((
|
|
9064
|
+
return new Promise((resolve2, reject) => {
|
|
9065
9065
|
this.close((err, data) => {
|
|
9066
|
-
return err ? reject(err) :
|
|
9066
|
+
return err ? reject(err) : resolve2(data);
|
|
9067
9067
|
});
|
|
9068
9068
|
});
|
|
9069
9069
|
}
|
|
@@ -9101,12 +9101,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
9101
9101
|
err = null;
|
|
9102
9102
|
}
|
|
9103
9103
|
if (callback === void 0) {
|
|
9104
|
-
return new Promise((
|
|
9104
|
+
return new Promise((resolve2, reject) => {
|
|
9105
9105
|
this.destroy(err, (err2, data) => {
|
|
9106
9106
|
return err2 ? (
|
|
9107
9107
|
/* istanbul ignore next: should never error */
|
|
9108
9108
|
reject(err2)
|
|
9109
|
-
) :
|
|
9109
|
+
) : resolve2(data);
|
|
9110
9110
|
});
|
|
9111
9111
|
});
|
|
9112
9112
|
}
|
|
@@ -10166,16 +10166,16 @@ var require_client = __commonJS({
|
|
|
10166
10166
|
return this[kNeedDrain] < 2;
|
|
10167
10167
|
}
|
|
10168
10168
|
async [kClose]() {
|
|
10169
|
-
return new Promise((
|
|
10169
|
+
return new Promise((resolve2) => {
|
|
10170
10170
|
if (!this[kSize]) {
|
|
10171
|
-
|
|
10171
|
+
resolve2(null);
|
|
10172
10172
|
} else {
|
|
10173
|
-
this[kClosedResolve] =
|
|
10173
|
+
this[kClosedResolve] = resolve2;
|
|
10174
10174
|
}
|
|
10175
10175
|
});
|
|
10176
10176
|
}
|
|
10177
10177
|
async [kDestroy](err) {
|
|
10178
|
-
return new Promise((
|
|
10178
|
+
return new Promise((resolve2) => {
|
|
10179
10179
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
10180
10180
|
for (let i = 0; i < requests.length; i++) {
|
|
10181
10181
|
const request3 = requests[i];
|
|
@@ -10186,7 +10186,7 @@ var require_client = __commonJS({
|
|
|
10186
10186
|
this[kClosedResolve]();
|
|
10187
10187
|
this[kClosedResolve] = null;
|
|
10188
10188
|
}
|
|
10189
|
-
|
|
10189
|
+
resolve2();
|
|
10190
10190
|
};
|
|
10191
10191
|
if (this[kHTTP2Session] != null) {
|
|
10192
10192
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -10766,7 +10766,7 @@ var require_client = __commonJS({
|
|
|
10766
10766
|
});
|
|
10767
10767
|
}
|
|
10768
10768
|
try {
|
|
10769
|
-
const socket = await new Promise((
|
|
10769
|
+
const socket = await new Promise((resolve2, reject) => {
|
|
10770
10770
|
client[kConnector]({
|
|
10771
10771
|
host,
|
|
10772
10772
|
hostname,
|
|
@@ -10778,7 +10778,7 @@ var require_client = __commonJS({
|
|
|
10778
10778
|
if (err) {
|
|
10779
10779
|
reject(err);
|
|
10780
10780
|
} else {
|
|
10781
|
-
|
|
10781
|
+
resolve2(socket2);
|
|
10782
10782
|
}
|
|
10783
10783
|
});
|
|
10784
10784
|
});
|
|
@@ -11402,12 +11402,12 @@ upgrade: ${upgrade}\r
|
|
|
11402
11402
|
cb();
|
|
11403
11403
|
}
|
|
11404
11404
|
}
|
|
11405
|
-
const waitForDrain = () => new Promise((
|
|
11405
|
+
const waitForDrain = () => new Promise((resolve2, reject) => {
|
|
11406
11406
|
assert2(callback === null);
|
|
11407
11407
|
if (socket[kError]) {
|
|
11408
11408
|
reject(socket[kError]);
|
|
11409
11409
|
} else {
|
|
11410
|
-
callback =
|
|
11410
|
+
callback = resolve2;
|
|
11411
11411
|
}
|
|
11412
11412
|
});
|
|
11413
11413
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -11752,8 +11752,8 @@ var require_pool_base = __commonJS({
|
|
|
11752
11752
|
if (this[kQueue].isEmpty()) {
|
|
11753
11753
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
11754
11754
|
} else {
|
|
11755
|
-
return new Promise((
|
|
11756
|
-
this[kClosedResolve] =
|
|
11755
|
+
return new Promise((resolve2) => {
|
|
11756
|
+
this[kClosedResolve] = resolve2;
|
|
11757
11757
|
});
|
|
11758
11758
|
}
|
|
11759
11759
|
}
|
|
@@ -12331,7 +12331,7 @@ var require_readable = __commonJS({
|
|
|
12331
12331
|
if (this.closed) {
|
|
12332
12332
|
return Promise.resolve(null);
|
|
12333
12333
|
}
|
|
12334
|
-
return new Promise((
|
|
12334
|
+
return new Promise((resolve2, reject) => {
|
|
12335
12335
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
12336
12336
|
this.destroy();
|
|
12337
12337
|
}) : noop;
|
|
@@ -12340,7 +12340,7 @@ var require_readable = __commonJS({
|
|
|
12340
12340
|
if (signal && signal.aborted) {
|
|
12341
12341
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
12342
12342
|
} else {
|
|
12343
|
-
|
|
12343
|
+
resolve2(null);
|
|
12344
12344
|
}
|
|
12345
12345
|
}).on("error", noop).on("data", function(chunk) {
|
|
12346
12346
|
limit -= chunk.length;
|
|
@@ -12362,11 +12362,11 @@ var require_readable = __commonJS({
|
|
|
12362
12362
|
throw new TypeError("unusable");
|
|
12363
12363
|
}
|
|
12364
12364
|
assert2(!stream[kConsume]);
|
|
12365
|
-
return new Promise((
|
|
12365
|
+
return new Promise((resolve2, reject) => {
|
|
12366
12366
|
stream[kConsume] = {
|
|
12367
12367
|
type,
|
|
12368
12368
|
stream,
|
|
12369
|
-
resolve,
|
|
12369
|
+
resolve: resolve2,
|
|
12370
12370
|
reject,
|
|
12371
12371
|
length: 0,
|
|
12372
12372
|
body: []
|
|
@@ -12401,12 +12401,12 @@ var require_readable = __commonJS({
|
|
|
12401
12401
|
}
|
|
12402
12402
|
}
|
|
12403
12403
|
function consumeEnd(consume2) {
|
|
12404
|
-
const { type, body, resolve, stream, length } = consume2;
|
|
12404
|
+
const { type, body, resolve: resolve2, stream, length } = consume2;
|
|
12405
12405
|
try {
|
|
12406
12406
|
if (type === "text") {
|
|
12407
|
-
|
|
12407
|
+
resolve2(toUSVString(Buffer.concat(body)));
|
|
12408
12408
|
} else if (type === "json") {
|
|
12409
|
-
|
|
12409
|
+
resolve2(JSON.parse(Buffer.concat(body)));
|
|
12410
12410
|
} else if (type === "arrayBuffer") {
|
|
12411
12411
|
const dst = new Uint8Array(length);
|
|
12412
12412
|
let pos = 0;
|
|
@@ -12414,12 +12414,12 @@ var require_readable = __commonJS({
|
|
|
12414
12414
|
dst.set(buf, pos);
|
|
12415
12415
|
pos += buf.byteLength;
|
|
12416
12416
|
}
|
|
12417
|
-
|
|
12417
|
+
resolve2(dst.buffer);
|
|
12418
12418
|
} else if (type === "blob") {
|
|
12419
12419
|
if (!Blob2) {
|
|
12420
12420
|
Blob2 = __require("buffer").Blob;
|
|
12421
12421
|
}
|
|
12422
|
-
|
|
12422
|
+
resolve2(new Blob2(body, { type: stream[kContentType] }));
|
|
12423
12423
|
}
|
|
12424
12424
|
consumeFinish(consume2);
|
|
12425
12425
|
} catch (err) {
|
|
@@ -12674,9 +12674,9 @@ var require_api_request = __commonJS({
|
|
|
12674
12674
|
};
|
|
12675
12675
|
function request3(opts, callback) {
|
|
12676
12676
|
if (callback === void 0) {
|
|
12677
|
-
return new Promise((
|
|
12677
|
+
return new Promise((resolve2, reject) => {
|
|
12678
12678
|
request3.call(this, opts, (err, data) => {
|
|
12679
|
-
return err ? reject(err) :
|
|
12679
|
+
return err ? reject(err) : resolve2(data);
|
|
12680
12680
|
});
|
|
12681
12681
|
});
|
|
12682
12682
|
}
|
|
@@ -12849,9 +12849,9 @@ var require_api_stream = __commonJS({
|
|
|
12849
12849
|
};
|
|
12850
12850
|
function stream(opts, factory, callback) {
|
|
12851
12851
|
if (callback === void 0) {
|
|
12852
|
-
return new Promise((
|
|
12852
|
+
return new Promise((resolve2, reject) => {
|
|
12853
12853
|
stream.call(this, opts, factory, (err, data) => {
|
|
12854
|
-
return err ? reject(err) :
|
|
12854
|
+
return err ? reject(err) : resolve2(data);
|
|
12855
12855
|
});
|
|
12856
12856
|
});
|
|
12857
12857
|
}
|
|
@@ -13132,9 +13132,9 @@ var require_api_upgrade = __commonJS({
|
|
|
13132
13132
|
};
|
|
13133
13133
|
function upgrade(opts, callback) {
|
|
13134
13134
|
if (callback === void 0) {
|
|
13135
|
-
return new Promise((
|
|
13135
|
+
return new Promise((resolve2, reject) => {
|
|
13136
13136
|
upgrade.call(this, opts, (err, data) => {
|
|
13137
|
-
return err ? reject(err) :
|
|
13137
|
+
return err ? reject(err) : resolve2(data);
|
|
13138
13138
|
});
|
|
13139
13139
|
});
|
|
13140
13140
|
}
|
|
@@ -13223,9 +13223,9 @@ var require_api_connect = __commonJS({
|
|
|
13223
13223
|
};
|
|
13224
13224
|
function connect3(opts, callback) {
|
|
13225
13225
|
if (callback === void 0) {
|
|
13226
|
-
return new Promise((
|
|
13226
|
+
return new Promise((resolve2, reject) => {
|
|
13227
13227
|
connect3.call(this, opts, (err, data) => {
|
|
13228
|
-
return err ? reject(err) :
|
|
13228
|
+
return err ? reject(err) : resolve2(data);
|
|
13229
13229
|
});
|
|
13230
13230
|
});
|
|
13231
13231
|
}
|
|
@@ -16847,7 +16847,7 @@ var require_fetch = __commonJS({
|
|
|
16847
16847
|
async function dispatch({ body }) {
|
|
16848
16848
|
const url = requestCurrentURL(request3);
|
|
16849
16849
|
const agent = fetchParams.controller.dispatcher;
|
|
16850
|
-
return new Promise((
|
|
16850
|
+
return new Promise((resolve2, reject) => agent.dispatch(
|
|
16851
16851
|
{
|
|
16852
16852
|
path: url.pathname + url.search,
|
|
16853
16853
|
origin: url.origin,
|
|
@@ -16923,7 +16923,7 @@ var require_fetch = __commonJS({
|
|
|
16923
16923
|
}
|
|
16924
16924
|
}
|
|
16925
16925
|
}
|
|
16926
|
-
|
|
16926
|
+
resolve2({
|
|
16927
16927
|
status,
|
|
16928
16928
|
statusText,
|
|
16929
16929
|
headersList: headers[kHeadersList],
|
|
@@ -16966,7 +16966,7 @@ var require_fetch = __commonJS({
|
|
|
16966
16966
|
const val = headersList[n + 1].toString("latin1");
|
|
16967
16967
|
headers[kHeadersList].append(key, val);
|
|
16968
16968
|
}
|
|
16969
|
-
|
|
16969
|
+
resolve2({
|
|
16970
16970
|
status,
|
|
16971
16971
|
statusText: STATUS_CODES[status],
|
|
16972
16972
|
headersList: headers[kHeadersList],
|
|
@@ -23943,14 +23943,14 @@ var __asyncValues = function(o) {
|
|
|
23943
23943
|
}, i);
|
|
23944
23944
|
function verb(n) {
|
|
23945
23945
|
i[n] = o[n] && function(v) {
|
|
23946
|
-
return new Promise(function(
|
|
23947
|
-
v = o[n](v), settle(
|
|
23946
|
+
return new Promise(function(resolve2, reject) {
|
|
23947
|
+
v = o[n](v), settle(resolve2, reject, v.done, v.value);
|
|
23948
23948
|
});
|
|
23949
23949
|
};
|
|
23950
23950
|
}
|
|
23951
|
-
function settle(
|
|
23951
|
+
function settle(resolve2, reject, d, v) {
|
|
23952
23952
|
Promise.resolve(v).then(function(v2) {
|
|
23953
|
-
|
|
23953
|
+
resolve2({ value: v2, done: d });
|
|
23954
23954
|
}, reject);
|
|
23955
23955
|
}
|
|
23956
23956
|
};
|
|
@@ -24475,14 +24475,14 @@ var __asyncValues2 = function(o) {
|
|
|
24475
24475
|
}, i);
|
|
24476
24476
|
function verb(n) {
|
|
24477
24477
|
i[n] = o[n] && function(v) {
|
|
24478
|
-
return new Promise(function(
|
|
24479
|
-
v = o[n](v), settle(
|
|
24478
|
+
return new Promise(function(resolve2, reject) {
|
|
24479
|
+
v = o[n](v), settle(resolve2, reject, v.done, v.value);
|
|
24480
24480
|
});
|
|
24481
24481
|
};
|
|
24482
24482
|
}
|
|
24483
|
-
function settle(
|
|
24483
|
+
function settle(resolve2, reject, d, v) {
|
|
24484
24484
|
Promise.resolve(v).then(function(v2) {
|
|
24485
|
-
|
|
24485
|
+
resolve2({ value: v2, done: d });
|
|
24486
24486
|
}, reject);
|
|
24487
24487
|
}
|
|
24488
24488
|
};
|
|
@@ -25217,14 +25217,14 @@ var __asyncValues3 = function(o) {
|
|
|
25217
25217
|
}, i);
|
|
25218
25218
|
function verb(n) {
|
|
25219
25219
|
i[n] = o[n] && function(v) {
|
|
25220
|
-
return new Promise(function(
|
|
25221
|
-
v = o[n](v), settle(
|
|
25220
|
+
return new Promise(function(resolve2, reject) {
|
|
25221
|
+
v = o[n](v), settle(resolve2, reject, v.done, v.value);
|
|
25222
25222
|
});
|
|
25223
25223
|
};
|
|
25224
25224
|
}
|
|
25225
|
-
function settle(
|
|
25225
|
+
function settle(resolve2, reject, d, v) {
|
|
25226
25226
|
Promise.resolve(v).then(function(v2) {
|
|
25227
|
-
|
|
25227
|
+
resolve2({ value: v2, done: d });
|
|
25228
25228
|
}, reject);
|
|
25229
25229
|
}
|
|
25230
25230
|
};
|
|
@@ -25862,17 +25862,17 @@ function closedOrError(reason) {
|
|
|
25862
25862
|
return isCancel ? closed() : error(reason);
|
|
25863
25863
|
}
|
|
25864
25864
|
function connect2(authority, http2SessionOptions) {
|
|
25865
|
-
let
|
|
25865
|
+
let resolve2;
|
|
25866
25866
|
let reject;
|
|
25867
25867
|
const conn = new Promise((res, rej) => {
|
|
25868
|
-
|
|
25868
|
+
resolve2 = res;
|
|
25869
25869
|
reject = rej;
|
|
25870
25870
|
});
|
|
25871
25871
|
const newConn = http2.connect(authority, http2SessionOptions);
|
|
25872
25872
|
newConn.on("connect", onConnect);
|
|
25873
25873
|
newConn.on("error", onError);
|
|
25874
25874
|
function onConnect() {
|
|
25875
|
-
|
|
25875
|
+
resolve2 === null || resolve2 === void 0 ? void 0 : resolve2(newConn);
|
|
25876
25876
|
cleanup();
|
|
25877
25877
|
}
|
|
25878
25878
|
function onError(err) {
|
|
@@ -25958,13 +25958,13 @@ function ready(conn, options) {
|
|
|
25958
25958
|
},
|
|
25959
25959
|
verify() {
|
|
25960
25960
|
conn.ref();
|
|
25961
|
-
return new Promise((
|
|
25961
|
+
return new Promise((resolve2) => {
|
|
25962
25962
|
commonPing(() => {
|
|
25963
25963
|
if (streamCount == 0)
|
|
25964
25964
|
conn.unref();
|
|
25965
|
-
|
|
25965
|
+
resolve2(true);
|
|
25966
25966
|
});
|
|
25967
|
-
conn.once("error", () =>
|
|
25967
|
+
conn.once("error", () => resolve2(false));
|
|
25968
25968
|
});
|
|
25969
25969
|
},
|
|
25970
25970
|
abort(reason) {
|
|
@@ -26095,7 +26095,7 @@ function createNodeHttpClient(options) {
|
|
|
26095
26095
|
function createNodeHttp1Client(httpOptions) {
|
|
26096
26096
|
return async function request3(req) {
|
|
26097
26097
|
const sentinel = createSentinel(req.signal);
|
|
26098
|
-
return new Promise((
|
|
26098
|
+
return new Promise((resolve2, reject) => {
|
|
26099
26099
|
sentinel.catch((e) => {
|
|
26100
26100
|
reject(e);
|
|
26101
26101
|
});
|
|
@@ -26106,7 +26106,7 @@ function createNodeHttp1Client(httpOptions) {
|
|
|
26106
26106
|
response.on("error", sentinel.reject);
|
|
26107
26107
|
sentinel.catch((reason) => response.destroy(connectErrorFromNodeReason(reason)));
|
|
26108
26108
|
const trailer = new Headers();
|
|
26109
|
-
|
|
26109
|
+
resolve2({
|
|
26110
26110
|
status: (_a = response.statusCode) !== null && _a !== void 0 ? _a : 0,
|
|
26111
26111
|
header: nodeHeaderToWebHeader(response.headers),
|
|
26112
26112
|
body: h1ResponseIterable(sentinel, response, trailer),
|
|
@@ -26121,7 +26121,7 @@ function createNodeHttp2Client(sessionProvider) {
|
|
|
26121
26121
|
return function request3(req) {
|
|
26122
26122
|
const sentinel = createSentinel(req.signal);
|
|
26123
26123
|
const sessionManager = sessionProvider(req.url);
|
|
26124
|
-
return new Promise((
|
|
26124
|
+
return new Promise((resolve2, reject) => {
|
|
26125
26125
|
sentinel.catch((e) => {
|
|
26126
26126
|
reject(e);
|
|
26127
26127
|
});
|
|
@@ -26135,7 +26135,7 @@ function createNodeHttp2Client(sessionProvider) {
|
|
|
26135
26135
|
body: h2ResponseIterable(sentinel, stream, sessionManager),
|
|
26136
26136
|
trailer: h2ResponseTrailer(stream)
|
|
26137
26137
|
};
|
|
26138
|
-
|
|
26138
|
+
resolve2(response);
|
|
26139
26139
|
});
|
|
26140
26140
|
});
|
|
26141
26141
|
});
|
|
@@ -26200,7 +26200,7 @@ function h2Request(sentinel, sm, url, method, headers, options, onStream) {
|
|
|
26200
26200
|
return;
|
|
26201
26201
|
}
|
|
26202
26202
|
const rstCode = reason instanceof ConnectError && reason.code == Code.Canceled ? H2Code.CANCEL : H2Code.INTERNAL_ERROR;
|
|
26203
|
-
return new Promise((
|
|
26203
|
+
return new Promise((resolve2) => stream.close(rstCode, resolve2));
|
|
26204
26204
|
});
|
|
26205
26205
|
stream.on("error", function h2StreamError(e) {
|
|
26206
26206
|
if (stream.writableEnded && unwrapNodeErrorChain(e).map(getNodeErrorProps).some((p) => p.code == "ERR_STREAM_WRITE_AFTER_END")) {
|
|
@@ -26252,11 +26252,11 @@ function h2ResponseIterable(sentinel, response, sm) {
|
|
|
26252
26252
|
}
|
|
26253
26253
|
async function sinkRequest(request3, nodeRequest, sentinel) {
|
|
26254
26254
|
if (request3.body === void 0) {
|
|
26255
|
-
await new Promise((
|
|
26255
|
+
await new Promise((resolve2) => nodeRequest.end(resolve2));
|
|
26256
26256
|
return;
|
|
26257
26257
|
}
|
|
26258
26258
|
const it = request3.body[Symbol.asyncIterator]();
|
|
26259
|
-
return new Promise((
|
|
26259
|
+
return new Promise((resolve2) => {
|
|
26260
26260
|
writeNext();
|
|
26261
26261
|
function writeNext() {
|
|
26262
26262
|
if (sentinel.isRejected()) {
|
|
@@ -26264,7 +26264,7 @@ async function sinkRequest(request3, nodeRequest, sentinel) {
|
|
|
26264
26264
|
}
|
|
26265
26265
|
it.next().then((r) => {
|
|
26266
26266
|
if (r.done === true) {
|
|
26267
|
-
nodeRequest.end(
|
|
26267
|
+
nodeRequest.end(resolve2);
|
|
26268
26268
|
return;
|
|
26269
26269
|
}
|
|
26270
26270
|
nodeRequest.write(r.value, "binary", function(e) {
|
|
@@ -26292,8 +26292,8 @@ function createSentinel(signal) {
|
|
|
26292
26292
|
let rej;
|
|
26293
26293
|
let resolved = false;
|
|
26294
26294
|
let rejected = false;
|
|
26295
|
-
const p = new Promise((
|
|
26296
|
-
res =
|
|
26295
|
+
const p = new Promise((resolve2, reject) => {
|
|
26296
|
+
res = resolve2;
|
|
26297
26297
|
rej = reject;
|
|
26298
26298
|
});
|
|
26299
26299
|
const c = {
|
|
@@ -26906,6 +26906,21 @@ var SkillFeedbackService = {
|
|
|
26906
26906
|
}
|
|
26907
26907
|
};
|
|
26908
26908
|
|
|
26909
|
+
// cli/src/version.ts
|
|
26910
|
+
import { createRequire } from "node:module";
|
|
26911
|
+
var OUR_NAMES = /* @__PURE__ */ new Set(["@neta-search/cli", "@neta-art/neta-search-cli"]);
|
|
26912
|
+
function cliVersion() {
|
|
26913
|
+
const req = createRequire(import.meta.url);
|
|
26914
|
+
for (const p of ["./package.json", "../package.json"]) {
|
|
26915
|
+
try {
|
|
26916
|
+
const pkg = req(p);
|
|
26917
|
+
if (pkg.name && OUR_NAMES.has(pkg.name) && pkg.version) return pkg.version;
|
|
26918
|
+
} catch {
|
|
26919
|
+
}
|
|
26920
|
+
}
|
|
26921
|
+
return "0.0.0-unknown";
|
|
26922
|
+
}
|
|
26923
|
+
|
|
26909
26924
|
// cli/src/env.ts
|
|
26910
26925
|
function detectEnv() {
|
|
26911
26926
|
const actorId = process.env["COHUB_USER_UUID"] ?? "";
|
|
@@ -26925,16 +26940,18 @@ function detectEnv() {
|
|
|
26925
26940
|
anonymous: actorId === "" || spaceId === ""
|
|
26926
26941
|
};
|
|
26927
26942
|
}
|
|
26943
|
+
var SEARCH_TIMEOUT_MS = 15e3;
|
|
26944
|
+
var REPORT_TIMEOUT_MS = 3e3;
|
|
26928
26945
|
function searchClient(env) {
|
|
26929
|
-
const transport = createConnectTransport({ baseUrl: env.apiBase, httpVersion: "1.1" });
|
|
26946
|
+
const transport = createConnectTransport({ baseUrl: env.apiBase, httpVersion: "1.1", defaultTimeoutMs: SEARCH_TIMEOUT_MS });
|
|
26930
26947
|
return createClient(SearchService, transport);
|
|
26931
26948
|
}
|
|
26932
26949
|
function feedbackClient(env) {
|
|
26933
|
-
const transport = createConnectTransport({ baseUrl: env.apiBase, httpVersion: "1.1" });
|
|
26950
|
+
const transport = createConnectTransport({ baseUrl: env.apiBase, httpVersion: "1.1", defaultTimeoutMs: REPORT_TIMEOUT_MS });
|
|
26934
26951
|
return createClient(SkillFeedbackService, transport);
|
|
26935
26952
|
}
|
|
26936
26953
|
function eventContext(env, extra = {}) {
|
|
26937
|
-
const ctx = { source: "cli", ...extra };
|
|
26954
|
+
const ctx = { source: "cli", cli_version: cliVersion(), ...extra };
|
|
26938
26955
|
if (env.sessionId) ctx["session_id"] = env.sessionId;
|
|
26939
26956
|
if (env.turnId) ctx["turn_id"] = env.turnId;
|
|
26940
26957
|
return ctx;
|
|
@@ -26958,7 +26975,7 @@ async function reportSkillEvent(env, event, skillId, digest, skillName, extra =
|
|
|
26958
26975
|
});
|
|
26959
26976
|
return true;
|
|
26960
26977
|
} catch (e) {
|
|
26961
|
-
console.error(
|
|
26978
|
+
console.error(`Note: failed to report the ${event} event (this does not affect the ${event}): ${e instanceof Error ? e.message : e}`);
|
|
26962
26979
|
return false;
|
|
26963
26980
|
}
|
|
26964
26981
|
}
|
|
@@ -26978,7 +26995,8 @@ async function cmdFind(query, opts) {
|
|
|
26978
26995
|
name: c.name,
|
|
26979
26996
|
description: c.summary,
|
|
26980
26997
|
match: c.match,
|
|
26981
|
-
sources: sc.sourceCount || void 0
|
|
26998
|
+
sources: sc.sourceCount || void 0,
|
|
26999
|
+
use: useCommand(c.id)
|
|
26982
27000
|
};
|
|
26983
27001
|
})
|
|
26984
27002
|
);
|
|
@@ -26987,22 +27005,26 @@ async function cmdFind(query, opts) {
|
|
|
26987
27005
|
}
|
|
26988
27006
|
const candidates = res.groups.flatMap((g) => g.candidates);
|
|
26989
27007
|
if (candidates.length === 0) {
|
|
26990
|
-
console.log(
|
|
26991
|
-
console.log(
|
|
27008
|
+
console.log(`No skills found for "${query}".`);
|
|
27009
|
+
console.log(`(This is a useful demand signal: missing capabilities drive what gets added next.)`);
|
|
26992
27010
|
return 0;
|
|
26993
27011
|
}
|
|
26994
|
-
console.log(
|
|
27012
|
+
console.log(`Found ${candidates.length} skill${candidates.length === 1 ? "" : "s"} (query: ${query}):
|
|
26995
27013
|
`);
|
|
26996
27014
|
for (const c of candidates) {
|
|
26997
27015
|
const sc = c;
|
|
26998
27016
|
console.log(` ${c.id}`);
|
|
26999
27017
|
if (c.summary) console.log(` ${trunc(c.summary, 100)}`);
|
|
27000
|
-
if ((sc.sourceCount || 0) > 1) console.log(` \u21B3
|
|
27018
|
+
if ((sc.sourceCount || 0) > 1) console.log(` \u21B3 identical copies merged: ${sc.sourceCount} sources`);
|
|
27001
27019
|
console.log();
|
|
27002
27020
|
}
|
|
27003
|
-
console.log(
|
|
27021
|
+
console.log(`Install: neta-search skills add <id> Try without installing: neta-search ${useCommand("<id>")}`);
|
|
27004
27022
|
return 0;
|
|
27005
27023
|
}
|
|
27024
|
+
function useCommand(id) {
|
|
27025
|
+
return `skills use ${id} --via ${FIND_VIA}`;
|
|
27026
|
+
}
|
|
27027
|
+
var FIND_VIA = "find";
|
|
27006
27028
|
function trunc(s, n) {
|
|
27007
27029
|
return s.length > n ? s.slice(0, n - 1) + "\u2026" : s;
|
|
27008
27030
|
}
|
|
@@ -27065,25 +27087,31 @@ var ArchiveNotFound = class extends Error {
|
|
|
27065
27087
|
async function fetchArchive(env, id) {
|
|
27066
27088
|
const url = `${env.apiBase}${ARCHIVE_PATH}?id=${encodeURIComponent(id)}`;
|
|
27067
27089
|
const res = await fetch(url, { redirect: "manual", signal: AbortSignal.timeout(TIMEOUT_MS) });
|
|
27068
|
-
if (res.status === 404) throw new ArchiveNotFound(`${id}
|
|
27090
|
+
if (res.status === 404) throw new ArchiveNotFound(`${id} does not exist or has no released version`);
|
|
27069
27091
|
const location = res.headers.get("location");
|
|
27070
|
-
if (res.status < 300 || res.status >= 400 || !location) throw new Error(
|
|
27092
|
+
if (res.status < 300 || res.status >= 400 || !location) throw new Error(`failed to download ${id}: HTTP ${res.status}`);
|
|
27071
27093
|
const digest = res.headers.get("x-skill-digest") ?? "";
|
|
27072
27094
|
const name = res.headers.get("x-skill-name") ?? id.split("/").pop();
|
|
27073
|
-
if (!digest) throw new Error(
|
|
27095
|
+
if (!digest) throw new Error(`failed to download ${id}: the server did not return a version (x-skill-digest)`);
|
|
27074
27096
|
const body = await download(new URL(location, url).toString(), id);
|
|
27075
27097
|
const files = untarGz(body);
|
|
27076
27098
|
const got = digestOf(new Map(files.map((f) => [f.path, f.data])));
|
|
27077
|
-
if (got !== digest) throw new Error(
|
|
27078
|
-
|
|
27099
|
+
if (got !== digest) throw new Error(`downloaded ${id} failed verification (expected ${digest}, got ${got})`);
|
|
27100
|
+
const handle = res.headers.get("x-skill-handle") || void 0;
|
|
27101
|
+
return { id, handle, name, digest, files };
|
|
27079
27102
|
}
|
|
27080
27103
|
async function archiveHead(env, id) {
|
|
27081
27104
|
const url = `${env.apiBase}${ARCHIVE_PATH}?id=${encodeURIComponent(id)}`;
|
|
27082
27105
|
const res = await fetch(url, { method: "HEAD", redirect: "manual", signal: AbortSignal.timeout(1e4) });
|
|
27083
27106
|
if (res.status === 404) return null;
|
|
27084
27107
|
const digest = res.headers.get("x-skill-digest") ?? "";
|
|
27085
|
-
if (res.status < 300 || res.status >= 400 || !digest) throw new Error(
|
|
27086
|
-
return {
|
|
27108
|
+
if (res.status < 300 || res.status >= 400 || !digest) throw new Error(`failed to look up ${id}: HTTP ${res.status}`);
|
|
27109
|
+
return {
|
|
27110
|
+
id: res.headers.get("x-skill-id") ?? id,
|
|
27111
|
+
handle: res.headers.get("x-skill-handle") || void 0,
|
|
27112
|
+
name: res.headers.get("x-skill-name") ?? id.split("/").pop(),
|
|
27113
|
+
digest
|
|
27114
|
+
};
|
|
27087
27115
|
}
|
|
27088
27116
|
async function download(url, id) {
|
|
27089
27117
|
for (let attempt = 1; ; attempt++) {
|
|
@@ -27093,7 +27121,7 @@ async function download(url, id) {
|
|
|
27093
27121
|
await new Promise((r) => setTimeout(r, Math.min(Math.max(body.retryAfterMs ?? 2e3, 250), 5e3)));
|
|
27094
27122
|
continue;
|
|
27095
27123
|
}
|
|
27096
|
-
if (!res.ok) throw new Error(
|
|
27124
|
+
if (!res.ok) throw new Error(`failed to download ${id}: registry returned HTTP ${res.status}`);
|
|
27097
27125
|
return Buffer.from(await res.arrayBuffer());
|
|
27098
27126
|
}
|
|
27099
27127
|
}
|
|
@@ -27122,7 +27150,7 @@ function untarGz(gz) {
|
|
|
27122
27150
|
const path = paxPath ?? (prefix ? `${prefix}/${name}` : name);
|
|
27123
27151
|
paxPath = null;
|
|
27124
27152
|
if (path.startsWith("/") || path.split("/").some((s) => s === ".." || s === "")) {
|
|
27125
|
-
throw new Error(
|
|
27153
|
+
throw new Error(`unsafe path in archive: ${path}`);
|
|
27126
27154
|
}
|
|
27127
27155
|
const mode = parseOctal(hdr.subarray(100, 108));
|
|
27128
27156
|
out.push({ path, data: Buffer.from(body), exec: (mode & 73) !== 0 });
|
|
@@ -27169,14 +27197,17 @@ function isHandle(s) {
|
|
|
27169
27197
|
return !parseId(s) && HANDLE_RE.test(s);
|
|
27170
27198
|
}
|
|
27171
27199
|
async function resolveRef(env, input) {
|
|
27172
|
-
|
|
27200
|
+
return (await resolveRefDetail(env, input)).ref;
|
|
27201
|
+
}
|
|
27202
|
+
async function resolveRefDetail(env, input) {
|
|
27203
|
+
if (!isHandle(input)) return { ref: input, unreachable: false };
|
|
27173
27204
|
try {
|
|
27174
27205
|
const r = await fetch(`${env.apiBase}/v1/skills/resolve?handle=${encodeURIComponent(input)}`, { signal: AbortSignal.timeout(5e3) });
|
|
27175
|
-
if (!r.ok) return input;
|
|
27206
|
+
if (!r.ok) return { ref: input, unreachable: r.status >= 500 };
|
|
27176
27207
|
const out = await r.json();
|
|
27177
|
-
return typeof out.id === "string" && parseId(out.id) ? out.id : input;
|
|
27208
|
+
return { ref: typeof out.id === "string" && parseId(out.id) ? out.id : input, unreachable: false };
|
|
27178
27209
|
} catch {
|
|
27179
|
-
return input;
|
|
27210
|
+
return { ref: input, unreachable: true };
|
|
27180
27211
|
}
|
|
27181
27212
|
}
|
|
27182
27213
|
function ownId(env, name) {
|
|
@@ -27188,11 +27219,20 @@ function skillDirExists(p) {
|
|
|
27188
27219
|
function readSource(dir) {
|
|
27189
27220
|
try {
|
|
27190
27221
|
const r = JSON.parse(readFileSync2(join2(dir, SOURCE_FILE), "utf8"));
|
|
27191
|
-
|
|
27222
|
+
if (typeof r?.id !== "string" || !parseId(r.id)) return null;
|
|
27223
|
+
const rec = { id: r.id, digest: String(r.digest ?? "") };
|
|
27224
|
+
if (typeof r.handle === "string" && HANDLE_RE.test(r.handle)) rec.handle = r.handle;
|
|
27225
|
+
return rec;
|
|
27192
27226
|
} catch {
|
|
27193
27227
|
return null;
|
|
27194
27228
|
}
|
|
27195
27229
|
}
|
|
27230
|
+
function writeSource(dir, rec) {
|
|
27231
|
+
writeFileSync(join2(dir, SOURCE_FILE), JSON.stringify(rec, null, 2) + "\n");
|
|
27232
|
+
}
|
|
27233
|
+
function displayRef(rec, fallback2 = "") {
|
|
27234
|
+
return rec?.handle || rec?.id || fallback2;
|
|
27235
|
+
}
|
|
27196
27236
|
function writeSkill(target, files, source) {
|
|
27197
27237
|
const staging = join2(dirname(target), `.staging-${target.split("/").pop()}-${process.pid}`);
|
|
27198
27238
|
rmSync(staging, { recursive: true, force: true });
|
|
@@ -27238,13 +27278,13 @@ function sharedOptOut(dir) {
|
|
|
27238
27278
|
}
|
|
27239
27279
|
function shareNotice(id, dir, draft, reported) {
|
|
27240
27280
|
if (draft) {
|
|
27241
|
-
console.error(
|
|
27281
|
+
console.error(`Note: skills in the drafts directory are not shared. Move it to ${SKILLS_DIR}/ and others will be able to find and install it.`);
|
|
27242
27282
|
} else if (sharedOptOut(dir)) {
|
|
27243
|
-
console.error(
|
|
27283
|
+
console.error(`Note: ${id} sets share: false, so it is not shared with others.`);
|
|
27244
27284
|
} else if (!reported) {
|
|
27245
|
-
console.error(
|
|
27285
|
+
console.error(`Note: could not reach the server this time, so ${id} is not shared yet; it will retry on the next use.`);
|
|
27246
27286
|
} else {
|
|
27247
|
-
console.error(
|
|
27287
|
+
console.error(`Note: the version you just used will be shared with others under your name once the server verifies it: ${id}. To opt out, add share: false to the SKILL.md frontmatter.`);
|
|
27248
27288
|
}
|
|
27249
27289
|
}
|
|
27250
27290
|
|
|
@@ -27259,32 +27299,32 @@ async function cmdAdd(idOrName, opts) {
|
|
|
27259
27299
|
return graduate(env, name, target, opts);
|
|
27260
27300
|
}
|
|
27261
27301
|
if (!parsed) {
|
|
27262
|
-
console.log(`"${idOrName}"
|
|
27302
|
+
console.log(`"${idOrName}" is not an id; searching by name. Pick an id from the results and run add again:`);
|
|
27263
27303
|
await cmdFind(idOrName, { limit: 5, json: false });
|
|
27264
27304
|
return 1;
|
|
27265
27305
|
}
|
|
27266
27306
|
if (parsed.spaceId === env.spaceId) {
|
|
27267
|
-
console.error(`${idOrName}
|
|
27307
|
+
console.error(`${idOrName} is a skill in your own space; no need to install it (it is in ${join3(".agents/skills", name)}/ or your drafts).`);
|
|
27268
27308
|
return 1;
|
|
27269
27309
|
}
|
|
27270
27310
|
let archive;
|
|
27271
27311
|
try {
|
|
27272
27312
|
archive = await fetchArchive(env, idOrName);
|
|
27273
27313
|
} catch (e) {
|
|
27274
|
-
console.error(e instanceof ArchiveNotFound ? `${e.message}
|
|
27314
|
+
console.error(e instanceof ArchiveNotFound ? `${e.message}. Try neta-search skills find first.` : String(e instanceof Error ? e.message : e));
|
|
27275
27315
|
return 1;
|
|
27276
27316
|
}
|
|
27277
27317
|
mkdirSync2(opts.dir, { recursive: true });
|
|
27278
|
-
writeSkill(target, archive.files, { id: archive.id, digest: archive.digest });
|
|
27318
|
+
writeSkill(target, archive.files, { id: archive.id, digest: archive.digest, handle: archive.handle });
|
|
27279
27319
|
const report = reportSkillEvent(env, "install", archive.id, archive.digest, name);
|
|
27280
|
-
if (opts.json) console.log(JSON.stringify({ installed: archive.id, path: target, digest: archive.digest }));
|
|
27281
|
-
else console.log(
|
|
27320
|
+
if (opts.json) console.log(JSON.stringify({ installed: archive.id, handle: archive.handle, path: target, digest: archive.digest }));
|
|
27321
|
+
else console.log(`Installed ${displayRef(archive)} \u2192 ${target}`);
|
|
27282
27322
|
await report;
|
|
27283
27323
|
return 0;
|
|
27284
27324
|
}
|
|
27285
27325
|
async function graduate(env, name, target, opts) {
|
|
27286
27326
|
if (existsSync2(target)) {
|
|
27287
|
-
console.error(`${target}
|
|
27327
|
+
console.error(`${target} already exists; draft ${name} was not moved (deal with the existing directory first).`);
|
|
27288
27328
|
return 1;
|
|
27289
27329
|
}
|
|
27290
27330
|
mkdirSync2(opts.dir, { recursive: true });
|
|
@@ -27293,116 +27333,224 @@ async function graduate(env, name, target, opts) {
|
|
|
27293
27333
|
const digest = skillDirDigest(target);
|
|
27294
27334
|
const reported = await reportSkillEvent(env, "install", id, digest, name);
|
|
27295
27335
|
if (opts.json) console.log(JSON.stringify({ graduated: id, path: target, digest }));
|
|
27296
|
-
else console.log(
|
|
27336
|
+
else console.log(`Moved draft ${name} to ${target}`);
|
|
27297
27337
|
if (!env.anonymous) shareNotice(id, target, false, reported);
|
|
27298
27338
|
return 0;
|
|
27299
27339
|
}
|
|
27300
27340
|
|
|
27301
27341
|
// cli/src/skills/use.ts
|
|
27302
|
-
import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as
|
|
27342
|
+
import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
27303
27343
|
import { randomUUID } from "node:crypto";
|
|
27304
|
-
import { join as join4 } from "node:path";
|
|
27344
|
+
import { join as join4, resolve } from "node:path";
|
|
27345
|
+
|
|
27346
|
+
// cli/src/mounts.ts
|
|
27347
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
27348
|
+
var SOURCE_RE = /\/checkpoints\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/latest\/?$/i;
|
|
27349
|
+
function mountsFile() {
|
|
27350
|
+
return process.env["NETASEARCH_MOUNTS_FILE"] ?? "/proc/mounts";
|
|
27351
|
+
}
|
|
27352
|
+
function unescape(s) {
|
|
27353
|
+
return s.replace(/\\([0-7]{3})/g, (_, o) => String.fromCharCode(parseInt(o, 8)));
|
|
27354
|
+
}
|
|
27355
|
+
function modMounts() {
|
|
27356
|
+
let text;
|
|
27357
|
+
try {
|
|
27358
|
+
text = readFileSync3(mountsFile(), "utf8");
|
|
27359
|
+
} catch {
|
|
27360
|
+
return [];
|
|
27361
|
+
}
|
|
27362
|
+
const out = [];
|
|
27363
|
+
for (const line of text.split("\n")) {
|
|
27364
|
+
const [src, dir] = line.split(" ");
|
|
27365
|
+
if (!src || !dir) continue;
|
|
27366
|
+
const m = SOURCE_RE.exec(unescape(src));
|
|
27367
|
+
if (m) out.push({ spaceId: m[1].toLowerCase(), dir: unescape(dir) });
|
|
27368
|
+
}
|
|
27369
|
+
return out;
|
|
27370
|
+
}
|
|
27371
|
+
|
|
27372
|
+
// cli/src/skills/use.ts
|
|
27305
27373
|
var FETCH_ROOT = process.env["NETASEARCH_FETCH_ROOT"] ?? join4("/tmp", "neta-skills");
|
|
27374
|
+
var WHERE_LABEL = {
|
|
27375
|
+
local: "from this space",
|
|
27376
|
+
mod: "from a mounted mod",
|
|
27377
|
+
cache: "from the local cache",
|
|
27378
|
+
fetched: "downloaded"
|
|
27379
|
+
};
|
|
27306
27380
|
async function cmdUse(idOrName, opts) {
|
|
27307
27381
|
const env = detectEnv();
|
|
27308
|
-
|
|
27382
|
+
const input = idOrName;
|
|
27383
|
+
const resolved = await resolveRefDetail(env, idOrName);
|
|
27384
|
+
idOrName = resolved.ref;
|
|
27309
27385
|
const parsed = parseId(idOrName);
|
|
27310
27386
|
const name = parsed?.name ?? idOrName;
|
|
27311
27387
|
const mine = !parsed || parsed.spaceId === env.spaceId;
|
|
27312
|
-
let
|
|
27313
|
-
|
|
27314
|
-
let
|
|
27388
|
+
let handle = isHandle(input) && parsed ? input.toLowerCase() : void 0;
|
|
27389
|
+
const via = opts.via ? opts.via.slice(0, 32) : null;
|
|
27390
|
+
let viaPointer = false;
|
|
27391
|
+
const entry = opts.entry ? opts.entry.slice(0, 128) : null;
|
|
27315
27392
|
let notice = null;
|
|
27393
|
+
let found = null;
|
|
27316
27394
|
let fetchId = parsed && !mine ? idOrName : null;
|
|
27317
|
-
let via = opts.via ? opts.via.slice(0, 32) : null;
|
|
27318
27395
|
const installed = join4(SKILLS_DIR, name);
|
|
27319
27396
|
const draft = join4(DRAFTS_DIR, name);
|
|
27320
27397
|
if (skillDirExists(installed)) {
|
|
27321
27398
|
const src = readSource(installed);
|
|
27322
27399
|
if (src && (!parsed || src.id === idOrName)) {
|
|
27323
|
-
|
|
27324
|
-
|
|
27400
|
+
found = { path: installed, where: "local", reportId: src.id };
|
|
27401
|
+
handle = handle ?? src.handle;
|
|
27325
27402
|
} else if (!src && mine) {
|
|
27326
|
-
|
|
27327
|
-
reportId = ownId(env, name);
|
|
27403
|
+
found = { path: installed, where: "local", reportId: ownId(env, name) };
|
|
27328
27404
|
notice = "shared";
|
|
27329
27405
|
}
|
|
27330
27406
|
}
|
|
27331
|
-
if (!
|
|
27332
|
-
|
|
27333
|
-
reportId = ownId(env, name);
|
|
27407
|
+
if (!found && mine && skillDirExists(draft)) {
|
|
27408
|
+
found = { path: draft, where: "local", reportId: ownId(env, name) };
|
|
27334
27409
|
notice = "draft";
|
|
27335
27410
|
}
|
|
27336
|
-
if (!
|
|
27337
|
-
const
|
|
27338
|
-
if (
|
|
27339
|
-
|
|
27340
|
-
where = "mod";
|
|
27341
|
-
}
|
|
27411
|
+
if (!found) {
|
|
27412
|
+
const r = findInMounts(parsed?.spaceId ?? null, name);
|
|
27413
|
+
if (r === "ambiguous") return 1;
|
|
27414
|
+
if (r) found = r;
|
|
27342
27415
|
}
|
|
27343
|
-
if (
|
|
27344
|
-
const target = pointerTarget(path);
|
|
27416
|
+
if (found) {
|
|
27417
|
+
const target = pointerTarget(found.path);
|
|
27345
27418
|
if (target !== null) {
|
|
27346
27419
|
if (!parseId(target)) {
|
|
27347
|
-
console.error(`${join4(path, "SKILL.md")}
|
|
27420
|
+
console.error(`${join4(found.path, "SKILL.md")} is a pointer, but its neta-skill-id is not a valid id: ${target}`);
|
|
27348
27421
|
return 1;
|
|
27349
27422
|
}
|
|
27350
|
-
|
|
27423
|
+
viaPointer = true;
|
|
27351
27424
|
fetchId = target;
|
|
27352
|
-
|
|
27353
|
-
reportId = null;
|
|
27425
|
+
found = null;
|
|
27354
27426
|
notice = null;
|
|
27427
|
+
const p = parseId(target);
|
|
27428
|
+
const r = findInMounts(p.spaceId, p.name);
|
|
27429
|
+
if (r && r !== "ambiguous" && pointerTarget(r.path) === null) {
|
|
27430
|
+
found = r;
|
|
27431
|
+
fetchId = null;
|
|
27432
|
+
}
|
|
27355
27433
|
}
|
|
27356
27434
|
}
|
|
27357
|
-
if (!
|
|
27358
|
-
|
|
27359
|
-
|
|
27360
|
-
|
|
27361
|
-
|
|
27362
|
-
|
|
27363
|
-
|
|
27364
|
-
|
|
27365
|
-
|
|
27366
|
-
path = join4(FETCH_ROOT, p.spaceId, p.name);
|
|
27367
|
-
const have = readSource(path);
|
|
27368
|
-
if (!skillDirExists(path) || have?.digest !== a.digest) writeSkill(path, a.files, { id: a.id, digest: a.digest });
|
|
27369
|
-
reportId = a.id;
|
|
27370
|
-
where = "fetched";
|
|
27371
|
-
} catch (e) {
|
|
27372
|
-
console.error(e instanceof ArchiveNotFound ? `${e.message}\u3002` : String(e instanceof Error ? e.message : e));
|
|
27435
|
+
if (!found && fetchId) {
|
|
27436
|
+
const r = await fromCacheOrDownload(env, fetchId);
|
|
27437
|
+
if (!r) return 1;
|
|
27438
|
+
found = r.found;
|
|
27439
|
+
handle = r.handle ?? handle;
|
|
27440
|
+
}
|
|
27441
|
+
if (!found) {
|
|
27442
|
+
if (resolved.unreachable) {
|
|
27443
|
+
console.error(`Cannot reach the server (${env.apiBase}), so handle "${input}" could not be resolved. Try again later; if the mod is mounted here, you can read /mods/<mod>/.agents/skills/<name>/SKILL.md directly.`);
|
|
27373
27444
|
return 1;
|
|
27374
27445
|
}
|
|
27375
|
-
|
|
27376
|
-
if (!path) {
|
|
27377
|
-
console.error(`skill "${idOrName}" \u672C\u5730\u6CA1\u6709\u2014\u2014\u5148 neta-search skills find "${name}" \u62FF\u5230 id\u3002`);
|
|
27446
|
+
console.error(`Skill "${idOrName}" is not available locally. Run neta-search skills find "${name}" to get its id.`);
|
|
27378
27447
|
return 1;
|
|
27379
27448
|
}
|
|
27380
27449
|
const useId = randomUUID();
|
|
27381
|
-
const extra = { use_id: useId };
|
|
27450
|
+
const extra = { use_id: useId, where: found.where };
|
|
27382
27451
|
if (via) extra["via"] = via;
|
|
27383
|
-
|
|
27384
|
-
const
|
|
27452
|
+
if (entry) extra["entry"] = entry;
|
|
27453
|
+
const digest = found.where === "mod" ? "" : found.digest ?? skillDirDigest(found.path);
|
|
27454
|
+
const reported = found.reportId ? await reportSkillEvent(env, "use", found.reportId, digest, name, extra) : false;
|
|
27455
|
+
const skillMd = readFileSync4(join4(found.path, "SKILL.md"), "utf8");
|
|
27456
|
+
const dir = resolve(found.path);
|
|
27457
|
+
const shown = handle ?? found.reportId ?? name;
|
|
27385
27458
|
if (opts.json) {
|
|
27386
|
-
console.log(
|
|
27459
|
+
console.log(
|
|
27460
|
+
JSON.stringify({
|
|
27461
|
+
skill: found.reportId ?? name,
|
|
27462
|
+
handle,
|
|
27463
|
+
path: dir,
|
|
27464
|
+
where: found.where,
|
|
27465
|
+
entry: entry ?? void 0,
|
|
27466
|
+
use_id: found.reportId ? useId : void 0,
|
|
27467
|
+
skill_md: skillMd
|
|
27468
|
+
})
|
|
27469
|
+
);
|
|
27387
27470
|
} else {
|
|
27388
|
-
|
|
27389
|
-
console.log(
|
|
27390
|
-
|
|
27391
|
-
console.log(
|
|
27392
|
-
|
|
27393
|
-
|
|
27394
|
-
|
|
27395
|
-
|
|
27396
|
-
|
|
27471
|
+
console.log(`You are being given a skill to execute for the user's request: ${shown} (${WHERE_LABEL[found.where]}${viaPointer ? ", via a pointer" : ""}).`);
|
|
27472
|
+
console.log(`Use the following SKILL.md as your instructions:
|
|
27473
|
+
`);
|
|
27474
|
+
console.log(`<SKILL.md>
|
|
27475
|
+
${skillMd}${skillMd.endsWith("\n") ? "" : "\n"}</SKILL.md>
|
|
27476
|
+
`);
|
|
27477
|
+
console.log(`Skill directory: ${dir}`);
|
|
27478
|
+
console.log(`When the SKILL.md references relative paths, read them from that directory.`);
|
|
27479
|
+
}
|
|
27480
|
+
if (notice && found.reportId && !env.anonymous) shareNotice(found.reportId, found.path, notice === "draft", reported);
|
|
27397
27481
|
return 0;
|
|
27398
27482
|
}
|
|
27399
|
-
function
|
|
27400
|
-
if (
|
|
27401
|
-
|
|
27402
|
-
|
|
27403
|
-
|
|
27483
|
+
function findInMounts(spaceId, name) {
|
|
27484
|
+
if (name.includes("/") || name.startsWith(".")) return null;
|
|
27485
|
+
const mounts = modMounts();
|
|
27486
|
+
if (spaceId) {
|
|
27487
|
+
for (const m of mounts) {
|
|
27488
|
+
const p = join4(m.dir, ".agents/skills", name);
|
|
27489
|
+
if (m.spaceId === spaceId && skillDirExists(p)) return { path: p, where: "mod", reportId: `cohub:${spaceId}/${name}` };
|
|
27490
|
+
}
|
|
27491
|
+
return null;
|
|
27492
|
+
}
|
|
27493
|
+
const hits = [];
|
|
27494
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27495
|
+
for (const m of mounts) {
|
|
27496
|
+
seen.add(resolve(m.dir));
|
|
27497
|
+
const p = join4(m.dir, ".agents/skills", name);
|
|
27498
|
+
if (skillDirExists(p)) hits.push({ path: p, where: "mod", reportId: `cohub:${m.spaceId}/${name}` });
|
|
27499
|
+
}
|
|
27500
|
+
if (existsSync3("/mods")) {
|
|
27501
|
+
for (const d of readdirSync2("/mods")) {
|
|
27502
|
+
const dir = join4("/mods", d);
|
|
27503
|
+
if (seen.has(resolve(dir))) continue;
|
|
27504
|
+
const p = join4(dir, ".agents/skills", name);
|
|
27505
|
+
if (skillDirExists(p)) hits.push({ path: p, where: "mod", reportId: null });
|
|
27506
|
+
}
|
|
27507
|
+
}
|
|
27508
|
+
if (hits.length > 1) {
|
|
27509
|
+
console.error(`${hits.length} mounted mods each have a different skill named ${name}:`);
|
|
27510
|
+
for (const h of hits) console.error(` ${h.path}${h.reportId ? ` (${h.reportId})` : ""}`);
|
|
27511
|
+
console.error(`Use a handle (<prefix>/${name}) to pick one; neta-search skills find "${name}" shows each handle.`);
|
|
27512
|
+
return "ambiguous";
|
|
27513
|
+
}
|
|
27514
|
+
return hits[0] ?? null;
|
|
27515
|
+
}
|
|
27516
|
+
async function fromCacheOrDownload(env, fetchId) {
|
|
27517
|
+
const p = parseId(fetchId);
|
|
27518
|
+
const cacheDir = join4(FETCH_ROOT, p.spaceId, p.name);
|
|
27519
|
+
const have = skillDirExists(cacheDir) ? readSource(cacheDir) : null;
|
|
27520
|
+
let head;
|
|
27521
|
+
try {
|
|
27522
|
+
head = await archiveHead(env, fetchId);
|
|
27523
|
+
} catch (e) {
|
|
27524
|
+
if (have) {
|
|
27525
|
+
console.error(`Note: cannot reach the server (${e instanceof Error ? e.message : e}); using the cached copy, which may not be the latest.`);
|
|
27526
|
+
return { found: { path: cacheDir, where: "cache", reportId: have.id, digest: have.digest }, handle: have.handle };
|
|
27527
|
+
}
|
|
27528
|
+
console.error(String(e instanceof Error ? e.message : e));
|
|
27529
|
+
return null;
|
|
27530
|
+
}
|
|
27531
|
+
if (head === null) {
|
|
27532
|
+
console.error(`${fetchId} does not exist or has no released version.`);
|
|
27533
|
+
return null;
|
|
27534
|
+
}
|
|
27535
|
+
if (have && have.digest === head.digest) {
|
|
27536
|
+
if (head.handle && head.handle !== have.handle) writeSource(cacheDir, { ...have, handle: head.handle });
|
|
27537
|
+
return { found: { path: cacheDir, where: "cache", reportId: have.id, digest: have.digest }, handle: head.handle ?? have.handle };
|
|
27538
|
+
}
|
|
27539
|
+
try {
|
|
27540
|
+
const a = await fetchArchive(env, fetchId);
|
|
27541
|
+
const skillMd = a.files.find((f) => f.path === "SKILL.md");
|
|
27542
|
+
if (skillMd && pointerTargetOf(skillMd.data.toString("utf8")) !== null) {
|
|
27543
|
+
console.error(`${fetchId} downloaded as another pointer; stopping here (pointers are followed only one level, to avoid loops).`);
|
|
27544
|
+
return null;
|
|
27545
|
+
}
|
|
27546
|
+
const q = parseId(a.id);
|
|
27547
|
+
const path = join4(FETCH_ROOT, q.spaceId, q.name);
|
|
27548
|
+
writeSkill(path, a.files, { id: a.id, digest: a.digest, handle: a.handle });
|
|
27549
|
+
return { found: { path, where: "fetched", reportId: a.id, digest: a.digest }, handle: a.handle };
|
|
27550
|
+
} catch (e) {
|
|
27551
|
+
console.error(e instanceof ArchiveNotFound ? `${e.message}.` : String(e instanceof Error ? e.message : e));
|
|
27552
|
+
return null;
|
|
27404
27553
|
}
|
|
27405
|
-
return null;
|
|
27406
27554
|
}
|
|
27407
27555
|
|
|
27408
27556
|
// cli/src/skills/init.ts
|
|
@@ -27410,50 +27558,50 @@ import { existsSync as existsSync4, mkdirSync as mkdirSync3, writeFileSync as wr
|
|
|
27410
27558
|
import { join as join5 } from "node:path";
|
|
27411
27559
|
async function cmdInit(name, opts) {
|
|
27412
27560
|
if (!name) {
|
|
27413
|
-
console.error(
|
|
27561
|
+
console.error(`Usage: neta-search skills init <name> (kebab-case, e.g. brawl-creator).`);
|
|
27414
27562
|
return 1;
|
|
27415
27563
|
}
|
|
27416
27564
|
const slug = name;
|
|
27417
27565
|
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug)) {
|
|
27418
|
-
console.error(`
|
|
27566
|
+
console.error(`Skill names must be kebab-case (e.g. brawl-creator), got "${slug}".`);
|
|
27419
27567
|
return 1;
|
|
27420
27568
|
}
|
|
27421
27569
|
const dir = opts.here ? "." : join5(".agents", "skills-drafts", slug);
|
|
27422
27570
|
const target = join5(dir, "SKILL.md");
|
|
27423
27571
|
if (existsSync4(target)) {
|
|
27424
|
-
console.error(`${target}
|
|
27572
|
+
console.error(`${target} already exists; init does not overwrite it.`);
|
|
27425
27573
|
return 1;
|
|
27426
27574
|
}
|
|
27427
27575
|
mkdirSync3(dir, { recursive: true });
|
|
27428
27576
|
writeFileSync2(target, template(slug));
|
|
27429
|
-
console.log(
|
|
27577
|
+
console.log(`Created ${target} (drafts directory: not loaded into the agent's skills while you write it)`);
|
|
27430
27578
|
console.log(`
|
|
27431
|
-
|
|
27432
|
-
console.log(` 1.
|
|
27433
|
-
console.log(` 2. neta-search skills use ${slug}
|
|
27434
|
-
console.log(` 3.
|
|
27435
|
-
console.log(`
|
|
27579
|
+
Next steps:`);
|
|
27580
|
+
console.log(` 1. Edit SKILL.md. Make the description say when to use this skill; agents decide by it, and search matches on it.`);
|
|
27581
|
+
console.log(` 2. Try it: neta-search skills use ${slug} (drafts work directly and are not shared)`);
|
|
27582
|
+
console.log(` 3. When it is ready: neta-search skills add ${slug} moves it to .agents/skills/; versions you use from there are shared with others`);
|
|
27583
|
+
console.log(` (under your name; to opt out, add share: false to the frontmatter)`);
|
|
27436
27584
|
return 0;
|
|
27437
27585
|
}
|
|
27438
27586
|
function template(slug) {
|
|
27439
27587
|
return `---
|
|
27440
27588
|
name: ${slug}
|
|
27441
|
-
description:
|
|
27589
|
+
description: One sentence on when to use this skill (what a user would search for). Search matches on this field.
|
|
27442
27590
|
metadata:
|
|
27443
27591
|
neta-scope: universal # character|world|image|video|audio|text|universal
|
|
27444
|
-
# neta-tags: [] #
|
|
27445
|
-
# disable-model-invocation: true #
|
|
27592
|
+
# neta-tags: [] # optional: your own tags (the server adds coarse tags too)
|
|
27593
|
+
# disable-model-invocation: true # optional: hide from the agent's skill list; only runs when named explicitly or via use
|
|
27446
27594
|
---
|
|
27447
27595
|
|
|
27448
27596
|
# ${slug}
|
|
27449
27597
|
|
|
27450
|
-
##
|
|
27598
|
+
## What it does
|
|
27451
27599
|
|
|
27452
|
-
|
|
27600
|
+
(What it does and who it is for.)
|
|
27453
27601
|
|
|
27454
|
-
##
|
|
27602
|
+
## How to use it
|
|
27455
27603
|
|
|
27456
|
-
|
|
27604
|
+
(How to call it, inputs and outputs, examples.)
|
|
27457
27605
|
`;
|
|
27458
27606
|
}
|
|
27459
27607
|
|
|
@@ -27469,7 +27617,7 @@ function scanLocal(dir) {
|
|
|
27469
27617
|
if (!skillDirExists(path)) continue;
|
|
27470
27618
|
const src = readSource(path);
|
|
27471
27619
|
if (src) {
|
|
27472
|
-
out.push({ name: e.name, path, kind: "installed", id: src.id, digest: src.digest });
|
|
27620
|
+
out.push({ name: e.name, path, kind: "installed", id: src.id, handle: src.handle, digest: src.digest });
|
|
27473
27621
|
continue;
|
|
27474
27622
|
}
|
|
27475
27623
|
const ptr = pointerTarget(path);
|
|
@@ -27477,47 +27625,58 @@ function scanLocal(dir) {
|
|
|
27477
27625
|
}
|
|
27478
27626
|
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
27479
27627
|
}
|
|
27628
|
+
async function findLocal(env, local, input) {
|
|
27629
|
+
if (!input.includes("/") && !input.startsWith(".")) {
|
|
27630
|
+
const s = local.find((x) => x.name === input);
|
|
27631
|
+
if (s) return [s];
|
|
27632
|
+
}
|
|
27633
|
+
const ref = parseId(input) ? input : await resolveRef(env, input);
|
|
27634
|
+
const lower = input.toLowerCase();
|
|
27635
|
+
return local.filter((x) => x.id !== void 0 && x.id === ref || x.handle !== void 0 && x.handle.toLowerCase() === lower);
|
|
27636
|
+
}
|
|
27480
27637
|
async function statusOf(env, s) {
|
|
27481
27638
|
if (s.kind !== "installed" || !s.id) return { status: "unknown" };
|
|
27482
27639
|
try {
|
|
27483
27640
|
const head = await archiveHead(env, s.id);
|
|
27484
27641
|
if (!head) return { status: "unavailable" };
|
|
27485
|
-
return { status: head.digest === s.digest ? "latest" : "outdated", latest: head.digest };
|
|
27642
|
+
return { status: head.digest === s.digest ? "latest" : "outdated", latest: head.digest, handle: head.handle };
|
|
27486
27643
|
} catch (e) {
|
|
27487
27644
|
return { status: "unknown", error: e instanceof Error ? e.message : String(e) };
|
|
27488
27645
|
}
|
|
27489
27646
|
}
|
|
27490
|
-
var KIND_LABEL = { installed: "
|
|
27491
|
-
var STATUS_LABEL = { latest: "
|
|
27647
|
+
var KIND_LABEL = { installed: "installed", pointer: "pointer", own: "your own" };
|
|
27648
|
+
var STATUS_LABEL = { latest: "latest", outdated: "update available", unavailable: "no longer available", unknown: "" };
|
|
27492
27649
|
async function cmdList(opts) {
|
|
27493
27650
|
const env = detectEnv();
|
|
27494
27651
|
const local = scanLocal(opts.dir);
|
|
27495
27652
|
const rows = await Promise.all(
|
|
27496
|
-
local.map(async (s) =>
|
|
27653
|
+
local.map(async (s) => {
|
|
27654
|
+
const st = opts.offline ? { status: "unknown", handle: void 0 } : await statusOf(env, s);
|
|
27655
|
+
return { ...s, ...st, handle: s.handle ?? st.handle };
|
|
27656
|
+
})
|
|
27497
27657
|
);
|
|
27498
27658
|
if (opts.json) {
|
|
27499
27659
|
console.log(JSON.stringify({ dir: opts.dir, count: rows.length, skills: rows }));
|
|
27500
27660
|
return 0;
|
|
27501
27661
|
}
|
|
27502
27662
|
if (rows.length === 0) {
|
|
27503
|
-
console.log(
|
|
27663
|
+
console.log(`No skills in ${opts.dir}/. Find one with neta-search skills find <what you want>, then add it.`);
|
|
27504
27664
|
return 0;
|
|
27505
27665
|
}
|
|
27506
|
-
console.log(`${opts.dir}
|
|
27666
|
+
console.log(`${opts.dir}/ (${rows.length}):`);
|
|
27507
27667
|
for (const r of rows) {
|
|
27508
27668
|
const st = STATUS_LABEL[r.status] ? ` [${STATUS_LABEL[r.status]}]` : "";
|
|
27509
|
-
const from = r.id ? ` ${r
|
|
27669
|
+
const from = r.id ? ` ${displayRef(r)}` : "";
|
|
27510
27670
|
console.log(` ${r.name.padEnd(28)} ${KIND_LABEL[r.kind]}${st}${from}`);
|
|
27511
27671
|
}
|
|
27512
27672
|
const outdated = rows.filter((r) => r.status === "outdated").length;
|
|
27513
27673
|
if (outdated > 0) console.log(`
|
|
27514
|
-
${outdated}
|
|
27674
|
+
${outdated} with updates available: neta-search skills update`);
|
|
27515
27675
|
return 0;
|
|
27516
27676
|
}
|
|
27517
27677
|
async function cmdUpdate(names, opts) {
|
|
27518
27678
|
const env = detectEnv();
|
|
27519
27679
|
const local = scanLocal(opts.dir);
|
|
27520
|
-
const byName = new Map(local.map((s) => [s.name, s]));
|
|
27521
27680
|
const targets = [];
|
|
27522
27681
|
const results = [];
|
|
27523
27682
|
let failed = 0;
|
|
@@ -27525,18 +27684,21 @@ async function cmdUpdate(names, opts) {
|
|
|
27525
27684
|
targets.push(...local.filter((s) => s.kind === "installed"));
|
|
27526
27685
|
} else {
|
|
27527
27686
|
for (const n of names) {
|
|
27528
|
-
const
|
|
27529
|
-
if (
|
|
27687
|
+
const found = await findLocal(env, local, n);
|
|
27688
|
+
if (found.length === 0) {
|
|
27530
27689
|
results.push({ name: n, result: "not_found" });
|
|
27531
27690
|
failed++;
|
|
27532
|
-
}
|
|
27533
|
-
|
|
27534
|
-
|
|
27691
|
+
}
|
|
27692
|
+
for (const s of found) {
|
|
27693
|
+
if (s.kind !== "installed") results.push({ name: s.name, result: s.kind === "own" ? "own_skipped" : "pointer_skipped" });
|
|
27694
|
+
else if (!targets.includes(s)) targets.push(s);
|
|
27695
|
+
}
|
|
27535
27696
|
}
|
|
27536
27697
|
}
|
|
27537
27698
|
for (const s of targets) {
|
|
27538
27699
|
const st = await statusOf(env, s);
|
|
27539
27700
|
if (st.status === "latest") {
|
|
27701
|
+
if (st.handle && st.handle !== s.handle) writeSource(s.path, { id: s.id, digest: s.digest, handle: st.handle });
|
|
27540
27702
|
results.push({ name: s.name, result: "latest" });
|
|
27541
27703
|
continue;
|
|
27542
27704
|
}
|
|
@@ -27551,7 +27713,7 @@ async function cmdUpdate(names, opts) {
|
|
|
27551
27713
|
}
|
|
27552
27714
|
try {
|
|
27553
27715
|
const a = await fetchArchive(env, s.id);
|
|
27554
|
-
writeSkill(s.path, a.files, { id: s.id, digest: a.digest });
|
|
27716
|
+
writeSkill(s.path, a.files, { id: s.id, digest: a.digest, handle: a.handle ?? s.handle });
|
|
27555
27717
|
await reportSkillEvent(env, "install", s.id, a.digest, s.name);
|
|
27556
27718
|
results.push({ name: s.name, result: "updated", from: s.digest, to: a.digest });
|
|
27557
27719
|
} catch (e) {
|
|
@@ -27563,15 +27725,15 @@ async function cmdUpdate(names, opts) {
|
|
|
27563
27725
|
console.log(JSON.stringify({ results }));
|
|
27564
27726
|
return failed > 0 ? 1 : 0;
|
|
27565
27727
|
}
|
|
27566
|
-
if (results.length === 0) console.log(
|
|
27728
|
+
if (results.length === 0) console.log(`No installed skills in ${opts.dir}/; nothing to update.`);
|
|
27567
27729
|
const say = {
|
|
27568
|
-
updated: (r) =>
|
|
27569
|
-
latest: (r) => `${r.name}
|
|
27570
|
-
unavailable: (r) => `${r.name}
|
|
27571
|
-
own_skipped: (r) => `${r.name}
|
|
27572
|
-
pointer_skipped: (r) => `${r.name}
|
|
27573
|
-
not_found: (r) => `${opts.dir}/${r.name}
|
|
27574
|
-
error: (r) =>
|
|
27730
|
+
updated: (r) => `Updated ${r.name} (${short(r.from)} \u2192 ${short(r.to)})`,
|
|
27731
|
+
latest: (r) => `${r.name} is up to date`,
|
|
27732
|
+
unavailable: (r) => `${r.name} is no longer available from its source; keeping the local copy`,
|
|
27733
|
+
own_skipped: (r) => `${r.name} is your own skill; nothing to update`,
|
|
27734
|
+
pointer_skipped: (r) => `${r.name} is a pointer; use always fetches the latest, nothing to update`,
|
|
27735
|
+
not_found: (r) => `${opts.dir}/${r.name} does not exist`,
|
|
27736
|
+
error: (r) => `Failed to update ${r.name}: ${r.from ?? ""}`
|
|
27575
27737
|
};
|
|
27576
27738
|
for (const r of results) console.log(say[r.result](r));
|
|
27577
27739
|
return failed > 0 ? 1 : 0;
|
|
@@ -27580,68 +27742,55 @@ function short(d) {
|
|
|
27580
27742
|
return (d ?? "").replace(/^sha256:/, "").slice(0, 12) || "?";
|
|
27581
27743
|
}
|
|
27582
27744
|
async function cmdRemove(names, opts) {
|
|
27583
|
-
const
|
|
27745
|
+
const env = detectEnv();
|
|
27746
|
+
const local = scanLocal(opts.dir);
|
|
27584
27747
|
const results = [];
|
|
27585
27748
|
for (const n of names) {
|
|
27586
|
-
const
|
|
27587
|
-
if (
|
|
27588
|
-
|
|
27589
|
-
|
|
27590
|
-
|
|
27591
|
-
|
|
27592
|
-
|
|
27593
|
-
|
|
27749
|
+
const found = (await findLocal(env, local, n)).filter((s) => existsSync5(s.path));
|
|
27750
|
+
if (found.length === 0) results.push({ name: n, result: "not_found" });
|
|
27751
|
+
for (const s of found) {
|
|
27752
|
+
if (s.kind === "own" && !opts.force) {
|
|
27753
|
+
results.push({ name: s.name, result: "own_refused" });
|
|
27754
|
+
} else {
|
|
27755
|
+
rmSync2(s.path, { recursive: true, force: true });
|
|
27756
|
+
results.push({ name: s.name, result: "removed" });
|
|
27757
|
+
}
|
|
27594
27758
|
}
|
|
27595
27759
|
}
|
|
27596
27760
|
const failed = results.filter((r) => r.result !== "removed").length;
|
|
27597
27761
|
if (opts.json) console.log(JSON.stringify({ results }));
|
|
27598
27762
|
else
|
|
27599
27763
|
for (const r of results) {
|
|
27600
|
-
if (r.result === "removed") console.log(
|
|
27601
|
-
else if (r.result === "not_found") console.error(`${join6(opts.dir, r.name)}
|
|
27602
|
-
else console.error(`${r.name}
|
|
27764
|
+
if (r.result === "removed") console.log(`Removed ${join6(opts.dir, r.name)}`);
|
|
27765
|
+
else if (r.result === "not_found") console.error(`${join6(opts.dir, r.name)} does not exist`);
|
|
27766
|
+
else console.error(`${r.name} is a skill you wrote yourself (no install source), so it was not removed. Add --force if you really want to delete it.`);
|
|
27603
27767
|
}
|
|
27604
27768
|
return failed > 0 ? 1 : 0;
|
|
27605
27769
|
}
|
|
27606
27770
|
|
|
27607
|
-
// cli/src/version.ts
|
|
27608
|
-
import { createRequire } from "node:module";
|
|
27609
|
-
var OUR_NAMES = /* @__PURE__ */ new Set(["@neta-search/cli", "@neta-art/neta-search-cli"]);
|
|
27610
|
-
function cliVersion() {
|
|
27611
|
-
const req = createRequire(import.meta.url);
|
|
27612
|
-
for (const p of ["./package.json", "../package.json"]) {
|
|
27613
|
-
try {
|
|
27614
|
-
const pkg = req(p);
|
|
27615
|
-
if (pkg.name && OUR_NAMES.has(pkg.name) && pkg.version) return pkg.version;
|
|
27616
|
-
} catch {
|
|
27617
|
-
}
|
|
27618
|
-
}
|
|
27619
|
-
return "0.0.0-unknown";
|
|
27620
|
-
}
|
|
27621
|
-
|
|
27622
27771
|
// cli/src/cli.ts
|
|
27623
27772
|
var program2 = new Command();
|
|
27624
|
-
program2.name("neta-search").description("neta-search
|
|
27625
|
-
var skills = program2.command("skills").description("
|
|
27626
|
-
skills.command("find").description("
|
|
27773
|
+
program2.name("neta-search").description("neta-search: search the Cohub skill ecosystem").version(cliVersion());
|
|
27774
|
+
var skills = program2.command("skills").description("skills: find / add / use / list / update / remove / init");
|
|
27775
|
+
skills.command("find").description("search the ecosystem for skills").argument("<query>", "what you want to do (natural language or keywords)").option("-n, --limit <n>", "max results", "20").option("--json", "compact JSON output (for agents)").action(async (query, opts) => {
|
|
27627
27776
|
await run(cmdFind(query, { limit: Number(opts.limit) || 20, json: opts.json }));
|
|
27628
27777
|
});
|
|
27629
|
-
skills.command("add").description("
|
|
27778
|
+
skills.command("add").description("install a skill: an id or handle from find downloads its current release; a name from your drafts moves it into .agents/skills/").argument("<id-or-name>", "skill id or handle from find (e.g. neta-skills/holo-pack-opening), or the name of one of your drafts").option("--dir <dir>", "install directory", ".agents/skills").option("--json", "compact JSON output (for agents)").action(async (idOrName, opts) => {
|
|
27630
27779
|
await run(cmdAdd(idOrName, opts));
|
|
27631
27780
|
});
|
|
27632
|
-
skills.command("use").description("
|
|
27781
|
+
skills.command("use").description("use a skill without installing it: prints the full SKILL.md and the skill directory (local copy, mounted mod, cache, or download)").argument("<id-or-name>", "skill id, handle (e.g. neta-skills/holo-pack-opening), or local skill name").option("--json", "compact JSON output (for agents)").option("--via <channel>", "where this use came from, recorded in usage stats (site / board-menu / picker / find)").option("--entry <id>", "entry id (picker / menu entry), recorded in usage stats").action(async (idOrName, opts) => {
|
|
27633
27782
|
await run(cmdUse(idOrName, opts));
|
|
27634
27783
|
});
|
|
27635
|
-
skills.command("list").alias("ls").description("
|
|
27784
|
+
skills.command("list").alias("ls").description("list local skills (installed / pointer / your own) and check installed ones for updates").option("--dir <dir>", "skills directory", ".agents/skills").option("--offline", "do not check for updates online").option("--json", "compact JSON output (for agents)").action(async (opts) => {
|
|
27636
27785
|
await run(cmdList({ dir: opts.dir, offline: !!opts.offline, json: !!opts.json }));
|
|
27637
27786
|
});
|
|
27638
|
-
skills.command("update").description("
|
|
27787
|
+
skills.command("update").description("update installed skills to their current release (no names = all; your own skills and pointers are left alone)").argument("[names...]", "skills to update: directory name, handle (e.g. neta-skills/holo-pack-opening), or id").option("--dir <dir>", "skills directory", ".agents/skills").option("--json", "compact JSON output (for agents)").action(async (names, opts) => {
|
|
27639
27788
|
await run(cmdUpdate(names, { dir: opts.dir, json: !!opts.json }));
|
|
27640
27789
|
});
|
|
27641
|
-
skills.command("remove").alias("rm").description("
|
|
27790
|
+
skills.command("remove").alias("rm").description("remove local skills (installed / pointer; your own need --force)").argument("<names...>", "skills to remove: directory name, handle, or id").option("--dir <dir>", "skills directory", ".agents/skills").option("--force", "also remove skills you wrote yourself").option("--json", "compact JSON output (for agents)").action(async (names, opts) => {
|
|
27642
27791
|
await run(cmdRemove(names, { dir: opts.dir, force: !!opts.force, json: !!opts.json }));
|
|
27643
27792
|
});
|
|
27644
|
-
skills.command("init").description("
|
|
27793
|
+
skills.command("init").description("scaffold a new skill (SKILL.md with frontmatter)").argument("[name]", "skill name (kebab-case)").option("--here", "create SKILL.md in the current directory instead of the drafts directory").action(async (name, opts) => {
|
|
27645
27794
|
await run(cmdInit(name, opts));
|
|
27646
27795
|
});
|
|
27647
27796
|
async function run(p) {
|
|
@@ -27649,7 +27798,7 @@ async function run(p) {
|
|
|
27649
27798
|
process.exit(code);
|
|
27650
27799
|
}
|
|
27651
27800
|
process.on("unhandledRejection", (err) => {
|
|
27652
|
-
console.error(import_picocolors.default.red(
|
|
27801
|
+
console.error(import_picocolors.default.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
27653
27802
|
process.exit(1);
|
|
27654
27803
|
});
|
|
27655
27804
|
program2.parseAsync();
|