@skillrecordings/cli 0.13.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +908 -363
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9700,9 +9700,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
9700
9700
|
}
|
|
9701
9701
|
close(callback) {
|
|
9702
9702
|
if (callback === void 0) {
|
|
9703
|
-
return new Promise((
|
|
9703
|
+
return new Promise((resolve9, reject) => {
|
|
9704
9704
|
this.close((err, data2) => {
|
|
9705
|
-
return err ? reject(err) :
|
|
9705
|
+
return err ? reject(err) : resolve9(data2);
|
|
9706
9706
|
});
|
|
9707
9707
|
});
|
|
9708
9708
|
}
|
|
@@ -9740,9 +9740,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
9740
9740
|
err = null;
|
|
9741
9741
|
}
|
|
9742
9742
|
if (callback === void 0) {
|
|
9743
|
-
return new Promise((
|
|
9743
|
+
return new Promise((resolve9, reject) => {
|
|
9744
9744
|
this.destroy(err, (err2, data2) => {
|
|
9745
|
-
return err2 ? reject(err2) :
|
|
9745
|
+
return err2 ? reject(err2) : resolve9(data2);
|
|
9746
9746
|
});
|
|
9747
9747
|
});
|
|
9748
9748
|
}
|
|
@@ -13234,8 +13234,8 @@ var require_promise = __commonJS({
|
|
|
13234
13234
|
function createDeferredPromise() {
|
|
13235
13235
|
let res;
|
|
13236
13236
|
let rej;
|
|
13237
|
-
const promise = new Promise((
|
|
13238
|
-
res =
|
|
13237
|
+
const promise = new Promise((resolve9, reject) => {
|
|
13238
|
+
res = resolve9;
|
|
13239
13239
|
rej = reject;
|
|
13240
13240
|
});
|
|
13241
13241
|
return { promise, resolve: res, reject: rej };
|
|
@@ -14538,12 +14538,12 @@ upgrade: ${upgrade}\r
|
|
|
14538
14538
|
cb();
|
|
14539
14539
|
}
|
|
14540
14540
|
}
|
|
14541
|
-
const waitForDrain = () => new Promise((
|
|
14541
|
+
const waitForDrain = () => new Promise((resolve9, reject) => {
|
|
14542
14542
|
assert(callback === null);
|
|
14543
14543
|
if (socket[kError]) {
|
|
14544
14544
|
reject(socket[kError]);
|
|
14545
14545
|
} else {
|
|
14546
|
-
callback =
|
|
14546
|
+
callback = resolve9;
|
|
14547
14547
|
}
|
|
14548
14548
|
});
|
|
14549
14549
|
socket.on("close", onDrain).on("drain", onDrain);
|
|
@@ -15354,12 +15354,12 @@ var require_client_h2 = __commonJS({
|
|
|
15354
15354
|
cb();
|
|
15355
15355
|
}
|
|
15356
15356
|
}
|
|
15357
|
-
const waitForDrain = () => new Promise((
|
|
15357
|
+
const waitForDrain = () => new Promise((resolve9, reject) => {
|
|
15358
15358
|
assert(callback === null);
|
|
15359
15359
|
if (socket[kError]) {
|
|
15360
15360
|
reject(socket[kError]);
|
|
15361
15361
|
} else {
|
|
15362
|
-
callback =
|
|
15362
|
+
callback = resolve9;
|
|
15363
15363
|
}
|
|
15364
15364
|
});
|
|
15365
15365
|
h2stream.on("close", onDrain).on("drain", onDrain);
|
|
@@ -15662,16 +15662,16 @@ var require_client = __commonJS({
|
|
|
15662
15662
|
return this[kNeedDrain] < 2;
|
|
15663
15663
|
}
|
|
15664
15664
|
[kClose]() {
|
|
15665
|
-
return new Promise((
|
|
15665
|
+
return new Promise((resolve9) => {
|
|
15666
15666
|
if (this[kSize]) {
|
|
15667
|
-
this[kClosedResolve] =
|
|
15667
|
+
this[kClosedResolve] = resolve9;
|
|
15668
15668
|
} else {
|
|
15669
|
-
|
|
15669
|
+
resolve9(null);
|
|
15670
15670
|
}
|
|
15671
15671
|
});
|
|
15672
15672
|
}
|
|
15673
15673
|
[kDestroy](err) {
|
|
15674
|
-
return new Promise((
|
|
15674
|
+
return new Promise((resolve9) => {
|
|
15675
15675
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
15676
15676
|
for (let i = 0; i < requests.length; i++) {
|
|
15677
15677
|
const request = requests[i];
|
|
@@ -15682,7 +15682,7 @@ var require_client = __commonJS({
|
|
|
15682
15682
|
this[kClosedResolve]();
|
|
15683
15683
|
this[kClosedResolve] = null;
|
|
15684
15684
|
}
|
|
15685
|
-
|
|
15685
|
+
resolve9(null);
|
|
15686
15686
|
};
|
|
15687
15687
|
if (this[kHTTPContext]) {
|
|
15688
15688
|
this[kHTTPContext].destroy(err, callback);
|
|
@@ -16075,8 +16075,8 @@ var require_pool_base = __commonJS({
|
|
|
16075
16075
|
}
|
|
16076
16076
|
return Promise.all(closeAll);
|
|
16077
16077
|
} else {
|
|
16078
|
-
return new Promise((
|
|
16079
|
-
this[kClosedResolve] =
|
|
16078
|
+
return new Promise((resolve9) => {
|
|
16079
|
+
this[kClosedResolve] = resolve9;
|
|
16080
16080
|
});
|
|
16081
16081
|
}
|
|
16082
16082
|
}
|
|
@@ -17615,7 +17615,7 @@ var require_readable = __commonJS({
|
|
|
17615
17615
|
if (this._readableState.closeEmitted) {
|
|
17616
17616
|
return Promise.resolve(null);
|
|
17617
17617
|
}
|
|
17618
|
-
return new Promise((
|
|
17618
|
+
return new Promise((resolve9, reject) => {
|
|
17619
17619
|
if (this[kContentLength] && this[kContentLength] > limit2 || this[kBytesRead] > limit2) {
|
|
17620
17620
|
this.destroy(new AbortError2());
|
|
17621
17621
|
}
|
|
@@ -17629,11 +17629,11 @@ var require_readable = __commonJS({
|
|
|
17629
17629
|
if (signal.aborted) {
|
|
17630
17630
|
reject(signal.reason ?? new AbortError2());
|
|
17631
17631
|
} else {
|
|
17632
|
-
|
|
17632
|
+
resolve9(null);
|
|
17633
17633
|
}
|
|
17634
17634
|
});
|
|
17635
17635
|
} else {
|
|
17636
|
-
this.on("close",
|
|
17636
|
+
this.on("close", resolve9);
|
|
17637
17637
|
}
|
|
17638
17638
|
this.on("error", noop).on("data", () => {
|
|
17639
17639
|
if (this[kBytesRead] > limit2) {
|
|
@@ -17661,7 +17661,7 @@ var require_readable = __commonJS({
|
|
|
17661
17661
|
}
|
|
17662
17662
|
function consume(stream, type) {
|
|
17663
17663
|
assert(!stream[kConsume]);
|
|
17664
|
-
return new Promise((
|
|
17664
|
+
return new Promise((resolve9, reject) => {
|
|
17665
17665
|
if (isUnusable(stream)) {
|
|
17666
17666
|
const rState = stream._readableState;
|
|
17667
17667
|
if (rState.destroyed && rState.closeEmitted === false) {
|
|
@@ -17676,7 +17676,7 @@ var require_readable = __commonJS({
|
|
|
17676
17676
|
stream[kConsume] = {
|
|
17677
17677
|
type,
|
|
17678
17678
|
stream,
|
|
17679
|
-
resolve:
|
|
17679
|
+
resolve: resolve9,
|
|
17680
17680
|
reject,
|
|
17681
17681
|
length: 0,
|
|
17682
17682
|
body: []
|
|
@@ -17750,18 +17750,18 @@ var require_readable = __commonJS({
|
|
|
17750
17750
|
return buffer;
|
|
17751
17751
|
}
|
|
17752
17752
|
function consumeEnd(consume2, encoding) {
|
|
17753
|
-
const { type, body, resolve:
|
|
17753
|
+
const { type, body, resolve: resolve9, stream, length } = consume2;
|
|
17754
17754
|
try {
|
|
17755
17755
|
if (type === "text") {
|
|
17756
|
-
|
|
17756
|
+
resolve9(chunksDecode(body, length, encoding));
|
|
17757
17757
|
} else if (type === "json") {
|
|
17758
|
-
|
|
17758
|
+
resolve9(JSON.parse(chunksDecode(body, length, encoding)));
|
|
17759
17759
|
} else if (type === "arrayBuffer") {
|
|
17760
|
-
|
|
17760
|
+
resolve9(chunksConcat(body, length).buffer);
|
|
17761
17761
|
} else if (type === "blob") {
|
|
17762
|
-
|
|
17762
|
+
resolve9(new Blob(body, { type: stream[kContentType] }));
|
|
17763
17763
|
} else if (type === "bytes") {
|
|
17764
|
-
|
|
17764
|
+
resolve9(chunksConcat(body, length));
|
|
17765
17765
|
}
|
|
17766
17766
|
consumeFinish(consume2);
|
|
17767
17767
|
} catch (err) {
|
|
@@ -17952,9 +17952,9 @@ var require_api_request = __commonJS({
|
|
|
17952
17952
|
};
|
|
17953
17953
|
function request(opts, callback) {
|
|
17954
17954
|
if (callback === void 0) {
|
|
17955
|
-
return new Promise((
|
|
17955
|
+
return new Promise((resolve9, reject) => {
|
|
17956
17956
|
request.call(this, opts, (err, data2) => {
|
|
17957
|
-
return err ? reject(err) :
|
|
17957
|
+
return err ? reject(err) : resolve9(data2);
|
|
17958
17958
|
});
|
|
17959
17959
|
});
|
|
17960
17960
|
}
|
|
@@ -18168,9 +18168,9 @@ var require_api_stream = __commonJS({
|
|
|
18168
18168
|
};
|
|
18169
18169
|
function stream(opts, factory, callback) {
|
|
18170
18170
|
if (callback === void 0) {
|
|
18171
|
-
return new Promise((
|
|
18171
|
+
return new Promise((resolve9, reject) => {
|
|
18172
18172
|
stream.call(this, opts, factory, (err, data2) => {
|
|
18173
|
-
return err ? reject(err) :
|
|
18173
|
+
return err ? reject(err) : resolve9(data2);
|
|
18174
18174
|
});
|
|
18175
18175
|
});
|
|
18176
18176
|
}
|
|
@@ -18460,9 +18460,9 @@ var require_api_upgrade = __commonJS({
|
|
|
18460
18460
|
};
|
|
18461
18461
|
function upgrade(opts, callback) {
|
|
18462
18462
|
if (callback === void 0) {
|
|
18463
|
-
return new Promise((
|
|
18463
|
+
return new Promise((resolve9, reject) => {
|
|
18464
18464
|
upgrade.call(this, opts, (err, data2) => {
|
|
18465
|
-
return err ? reject(err) :
|
|
18465
|
+
return err ? reject(err) : resolve9(data2);
|
|
18466
18466
|
});
|
|
18467
18467
|
});
|
|
18468
18468
|
}
|
|
@@ -18556,9 +18556,9 @@ var require_api_connect = __commonJS({
|
|
|
18556
18556
|
};
|
|
18557
18557
|
function connect(opts, callback) {
|
|
18558
18558
|
if (callback === void 0) {
|
|
18559
|
-
return new Promise((
|
|
18559
|
+
return new Promise((resolve9, reject) => {
|
|
18560
18560
|
connect.call(this, opts, (err, data2) => {
|
|
18561
|
-
return err ? reject(err) :
|
|
18561
|
+
return err ? reject(err) : resolve9(data2);
|
|
18562
18562
|
});
|
|
18563
18563
|
});
|
|
18564
18564
|
}
|
|
@@ -19838,7 +19838,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
19838
19838
|
"use strict";
|
|
19839
19839
|
init_esm_shims();
|
|
19840
19840
|
var { writeFile: writeFile9, readFile: readFile10, mkdir: mkdir2 } = __require("fs/promises");
|
|
19841
|
-
var { dirname:
|
|
19841
|
+
var { dirname: dirname8, resolve: resolve9 } = __require("path");
|
|
19842
19842
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
|
|
19843
19843
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
19844
19844
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -20039,7 +20039,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
20039
20039
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
20040
20040
|
}
|
|
20041
20041
|
try {
|
|
20042
|
-
const data2 = await readFile10(
|
|
20042
|
+
const data2 = await readFile10(resolve9(path), "utf8");
|
|
20043
20043
|
const parsed = JSON.parse(data2);
|
|
20044
20044
|
if (Array.isArray(parsed)) {
|
|
20045
20045
|
this.#snapshots.clear();
|
|
@@ -20068,8 +20068,8 @@ var require_snapshot_recorder = __commonJS({
|
|
|
20068
20068
|
if (!path) {
|
|
20069
20069
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
20070
20070
|
}
|
|
20071
|
-
const resolvedPath =
|
|
20072
|
-
await mkdir2(
|
|
20071
|
+
const resolvedPath = resolve9(path);
|
|
20072
|
+
await mkdir2(dirname8(resolvedPath), { recursive: true });
|
|
20073
20073
|
const data2 = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
20074
20074
|
hash,
|
|
20075
20075
|
snapshot
|
|
@@ -26646,7 +26646,7 @@ var require_fetch = __commonJS({
|
|
|
26646
26646
|
function dispatch({ body }) {
|
|
26647
26647
|
const url = requestCurrentURL(request);
|
|
26648
26648
|
const agent = fetchParams.controller.dispatcher;
|
|
26649
|
-
return new Promise((
|
|
26649
|
+
return new Promise((resolve9, reject) => agent.dispatch(
|
|
26650
26650
|
{
|
|
26651
26651
|
path: url.pathname + url.search,
|
|
26652
26652
|
origin: url.origin,
|
|
@@ -26726,7 +26726,7 @@ var require_fetch = __commonJS({
|
|
|
26726
26726
|
}
|
|
26727
26727
|
}
|
|
26728
26728
|
const onError = this.onError.bind(this);
|
|
26729
|
-
|
|
26729
|
+
resolve9({
|
|
26730
26730
|
status,
|
|
26731
26731
|
statusText,
|
|
26732
26732
|
headersList,
|
|
@@ -26769,7 +26769,7 @@ var require_fetch = __commonJS({
|
|
|
26769
26769
|
for (let i = 0; i < rawHeaders.length; i += 2) {
|
|
26770
26770
|
headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true);
|
|
26771
26771
|
}
|
|
26772
|
-
|
|
26772
|
+
resolve9({
|
|
26773
26773
|
status,
|
|
26774
26774
|
statusText: STATUS_CODES2[status],
|
|
26775
26775
|
headersList,
|
|
@@ -62982,7 +62982,7 @@ var require_resolve_uri_umd = __commonJS({
|
|
|
62982
62982
|
}
|
|
62983
62983
|
url.path = path;
|
|
62984
62984
|
}
|
|
62985
|
-
function
|
|
62985
|
+
function resolve9(input2, base) {
|
|
62986
62986
|
if (!input2 && !base)
|
|
62987
62987
|
return "";
|
|
62988
62988
|
const url = parseUrl(input2);
|
|
@@ -63035,7 +63035,7 @@ var require_resolve_uri_umd = __commonJS({
|
|
|
63035
63035
|
return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
|
|
63036
63036
|
}
|
|
63037
63037
|
}
|
|
63038
|
-
return
|
|
63038
|
+
return resolve9;
|
|
63039
63039
|
}));
|
|
63040
63040
|
}
|
|
63041
63041
|
});
|
|
@@ -63382,8 +63382,8 @@ var require_trace_mapping_umd = __commonJS({
|
|
|
63382
63382
|
this.sources = sources;
|
|
63383
63383
|
this.sourcesContent = sourcesContent;
|
|
63384
63384
|
this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
|
|
63385
|
-
const
|
|
63386
|
-
this.resolvedSources = sources.map(
|
|
63385
|
+
const resolve9 = resolver(mapUrl, sourceRoot);
|
|
63386
|
+
this.resolvedSources = sources.map(resolve9);
|
|
63387
63387
|
const { mappings } = parsed;
|
|
63388
63388
|
if (typeof mappings === "string") {
|
|
63389
63389
|
this._encoded = mappings;
|
|
@@ -72917,7 +72917,7 @@ var require_introspection = __commonJS({
|
|
|
72917
72917
|
exports.isStatic = isStatic;
|
|
72918
72918
|
exports.matchesPattern = matchesPattern;
|
|
72919
72919
|
exports.referencesImport = referencesImport;
|
|
72920
|
-
exports.resolve =
|
|
72920
|
+
exports.resolve = resolve9;
|
|
72921
72921
|
exports.willIMaybeExecuteBefore = willIMaybeExecuteBefore;
|
|
72922
72922
|
var _t = require_lib6();
|
|
72923
72923
|
var {
|
|
@@ -73175,7 +73175,7 @@ var require_introspection = __commonJS({
|
|
|
73175
73175
|
nodeMap.set(target.node, result);
|
|
73176
73176
|
return result;
|
|
73177
73177
|
}
|
|
73178
|
-
function
|
|
73178
|
+
function resolve9(dangerous, resolved) {
|
|
73179
73179
|
return _resolve.call(this, dangerous, resolved) || this;
|
|
73180
73180
|
}
|
|
73181
73181
|
function _resolve(dangerous, resolved) {
|
|
@@ -74537,8 +74537,67 @@ var require_lib10 = __commonJS({
|
|
|
74537
74537
|
|
|
74538
74538
|
// src/index.ts
|
|
74539
74539
|
init_esm_shims();
|
|
74540
|
-
import {
|
|
74541
|
-
|
|
74540
|
+
import { resolve as resolve8 } from "path";
|
|
74541
|
+
|
|
74542
|
+
// src/core/config-loader.ts
|
|
74543
|
+
init_esm_shims();
|
|
74544
|
+
import { readFileSync } from "fs";
|
|
74545
|
+
import { resolve } from "path";
|
|
74546
|
+
|
|
74547
|
+
// src/core/user-config.ts
|
|
74548
|
+
init_esm_shims();
|
|
74549
|
+
import { homedir } from "os";
|
|
74550
|
+
import { join } from "path";
|
|
74551
|
+
|
|
74552
|
+
// src/core/fs-extra.ts
|
|
74553
|
+
init_esm_shims();
|
|
74554
|
+
import { existsSync } from "fs";
|
|
74555
|
+
import { cp, mkdir, readFile } from "fs/promises";
|
|
74556
|
+
async function ensureDir(path) {
|
|
74557
|
+
await mkdir(path, { recursive: true });
|
|
74558
|
+
}
|
|
74559
|
+
async function pathExists(path) {
|
|
74560
|
+
return existsSync(path);
|
|
74561
|
+
}
|
|
74562
|
+
async function readJson(path) {
|
|
74563
|
+
const contents2 = await readFile(path, "utf-8");
|
|
74564
|
+
return JSON.parse(contents2);
|
|
74565
|
+
}
|
|
74566
|
+
async function copy(src, dest) {
|
|
74567
|
+
await cp(src, dest, { recursive: true, force: true });
|
|
74568
|
+
}
|
|
74569
|
+
|
|
74570
|
+
// src/core/config-loader.ts
|
|
74571
|
+
function parseEnvContent(content) {
|
|
74572
|
+
const env = {};
|
|
74573
|
+
for (const line of content.split("\n")) {
|
|
74574
|
+
const trimmed = line.trim();
|
|
74575
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
74576
|
+
const eqIdx = trimmed.indexOf("=");
|
|
74577
|
+
if (eqIdx === -1) continue;
|
|
74578
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
74579
|
+
const raw = trimmed.slice(eqIdx + 1).trim();
|
|
74580
|
+
const value = raw.replace(/^["'](.*)["']$/, "$1");
|
|
74581
|
+
env[key] = value;
|
|
74582
|
+
}
|
|
74583
|
+
return env;
|
|
74584
|
+
}
|
|
74585
|
+
var globalProvenance = /* @__PURE__ */ new Map();
|
|
74586
|
+
function getKeyProvenance(key) {
|
|
74587
|
+
return globalProvenance.get(key);
|
|
74588
|
+
}
|
|
74589
|
+
function loadPlaintextEnv(cliRoot2) {
|
|
74590
|
+
for (const envFile of [".env.local", ".env"]) {
|
|
74591
|
+
try {
|
|
74592
|
+
const content = readFileSync(resolve(cliRoot2, envFile), "utf8");
|
|
74593
|
+
return parseEnvContent(content);
|
|
74594
|
+
} catch {
|
|
74595
|
+
}
|
|
74596
|
+
}
|
|
74597
|
+
return {};
|
|
74598
|
+
}
|
|
74599
|
+
|
|
74600
|
+
// src/index.ts
|
|
74542
74601
|
import { Command as Command4 } from "commander";
|
|
74543
74602
|
|
|
74544
74603
|
// src/commands/auth/index.ts
|
|
@@ -75055,8 +75114,8 @@ async function loginAction(ctx, options) {
|
|
|
75055
75114
|
|
|
75056
75115
|
// src/commands/auth/setup.ts
|
|
75057
75116
|
init_esm_shims();
|
|
75058
|
-
import { existsSync, writeFileSync } from "fs";
|
|
75059
|
-
import { resolve } from "path";
|
|
75117
|
+
import { existsSync as existsSync2, writeFileSync } from "fs";
|
|
75118
|
+
import { resolve as resolve2 } from "path";
|
|
75060
75119
|
import { confirm, select } from "@inquirer/prompts";
|
|
75061
75120
|
|
|
75062
75121
|
// src/core/errors.ts
|
|
@@ -75403,8 +75462,8 @@ async function authSetupAction(ctx, options = {}) {
|
|
|
75403
75462
|
]
|
|
75404
75463
|
});
|
|
75405
75464
|
if (persistence === "env") {
|
|
75406
|
-
const envPath =
|
|
75407
|
-
if (
|
|
75465
|
+
const envPath = resolve2(process.cwd(), ".env.local");
|
|
75466
|
+
if (existsSync2(envPath)) {
|
|
75408
75467
|
const overwrite = await confirm({
|
|
75409
75468
|
message: `.env.local already exists at ${envPath}. Overwrite?`,
|
|
75410
75469
|
default: false
|
|
@@ -76955,11 +77014,11 @@ Saved to ${options.output}`);
|
|
|
76955
77014
|
}
|
|
76956
77015
|
}
|
|
76957
77016
|
async function toEvalite(options) {
|
|
76958
|
-
const { readFileSync:
|
|
77017
|
+
const { readFileSync: readFileSync12 } = await import("fs");
|
|
76959
77018
|
const { ctx } = options;
|
|
76960
77019
|
const outputJson = ctx.format === "json";
|
|
76961
77020
|
const data2 = JSON.parse(
|
|
76962
|
-
|
|
77021
|
+
readFileSync12(options.input, "utf-8")
|
|
76963
77022
|
);
|
|
76964
77023
|
const evaliteData = data2.map((d) => ({
|
|
76965
77024
|
input: d.triggerMessage.body,
|
|
@@ -77015,6 +77074,411 @@ function registerDatasetCommands(program3) {
|
|
|
77015
77074
|
});
|
|
77016
77075
|
}
|
|
77017
77076
|
|
|
77077
|
+
// src/commands/config/index.ts
|
|
77078
|
+
init_esm_shims();
|
|
77079
|
+
|
|
77080
|
+
// src/commands/config/get.ts
|
|
77081
|
+
init_esm_shims();
|
|
77082
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
77083
|
+
import { Decrypter as Decrypter2 } from "age-encryption";
|
|
77084
|
+
|
|
77085
|
+
// src/commands/config/init.ts
|
|
77086
|
+
init_esm_shims();
|
|
77087
|
+
import { existsSync as existsSync3, mkdirSync, writeFileSync as writeFileSync3 } from "fs";
|
|
77088
|
+
import { homedir as homedir2 } from "os";
|
|
77089
|
+
import { join as join2 } from "path";
|
|
77090
|
+
import { generateIdentity, identityToRecipient } from "age-encryption";
|
|
77091
|
+
function getUserConfigDir() {
|
|
77092
|
+
return join2(homedir2(), ".config", "skill");
|
|
77093
|
+
}
|
|
77094
|
+
function getAgeKeyPath() {
|
|
77095
|
+
return join2(getUserConfigDir(), "age.key");
|
|
77096
|
+
}
|
|
77097
|
+
async function configInitAction(ctx, options = {}) {
|
|
77098
|
+
const outputJson = options.json === true || ctx.format === "json";
|
|
77099
|
+
const keyPath = getAgeKeyPath();
|
|
77100
|
+
const configDir = getUserConfigDir();
|
|
77101
|
+
if (existsSync3(keyPath) && !options.force) {
|
|
77102
|
+
const result = {
|
|
77103
|
+
success: false,
|
|
77104
|
+
error: `Age key already exists at ${keyPath}. Use --force to overwrite.`
|
|
77105
|
+
};
|
|
77106
|
+
if (outputJson) {
|
|
77107
|
+
ctx.output.data(result);
|
|
77108
|
+
} else {
|
|
77109
|
+
ctx.output.error(result.error);
|
|
77110
|
+
ctx.output.data(`
|
|
77111
|
+
To view your public key: skill config public-key`);
|
|
77112
|
+
}
|
|
77113
|
+
process.exitCode = EXIT_CODES.usage;
|
|
77114
|
+
return;
|
|
77115
|
+
}
|
|
77116
|
+
try {
|
|
77117
|
+
if (!existsSync3(configDir)) {
|
|
77118
|
+
mkdirSync(configDir, { recursive: true, mode: 448 });
|
|
77119
|
+
}
|
|
77120
|
+
const identity = await generateIdentity();
|
|
77121
|
+
const recipient = await identityToRecipient(identity);
|
|
77122
|
+
writeFileSync3(keyPath, identity, { encoding: "utf8", mode: 384 });
|
|
77123
|
+
const result = {
|
|
77124
|
+
success: true,
|
|
77125
|
+
keyPath,
|
|
77126
|
+
publicKey: recipient
|
|
77127
|
+
};
|
|
77128
|
+
if (outputJson) {
|
|
77129
|
+
ctx.output.data(result);
|
|
77130
|
+
} else {
|
|
77131
|
+
ctx.output.success("Age keypair generated successfully!");
|
|
77132
|
+
ctx.output.data(`
|
|
77133
|
+
Private key saved to: ${keyPath}`);
|
|
77134
|
+
ctx.output.data(`Public key (age recipient): ${recipient}`);
|
|
77135
|
+
ctx.output.data(
|
|
77136
|
+
"\n\u26A0\uFE0F Keep your private key secure. Anyone with access can decrypt your config."
|
|
77137
|
+
);
|
|
77138
|
+
ctx.output.data("\nNext steps:");
|
|
77139
|
+
ctx.output.data(" 1. Set config values: skill config set KEY=value");
|
|
77140
|
+
ctx.output.data(" 2. View config: skill config list");
|
|
77141
|
+
}
|
|
77142
|
+
} catch (error) {
|
|
77143
|
+
const result = {
|
|
77144
|
+
success: false,
|
|
77145
|
+
error: error instanceof Error ? error.message : "Failed to generate keypair"
|
|
77146
|
+
};
|
|
77147
|
+
if (outputJson) {
|
|
77148
|
+
ctx.output.data(result);
|
|
77149
|
+
} else {
|
|
77150
|
+
ctx.output.error(`Failed to generate keypair: ${result.error}`);
|
|
77151
|
+
}
|
|
77152
|
+
process.exitCode = EXIT_CODES.error;
|
|
77153
|
+
}
|
|
77154
|
+
}
|
|
77155
|
+
|
|
77156
|
+
// src/commands/config/set.ts
|
|
77157
|
+
init_esm_shims();
|
|
77158
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
77159
|
+
import { Decrypter, Encrypter, identityToRecipient as identityToRecipient2 } from "age-encryption";
|
|
77160
|
+
function getEncryptedConfigPath() {
|
|
77161
|
+
return `${getUserConfigDir()}/.env.user.encrypted`;
|
|
77162
|
+
}
|
|
77163
|
+
function parseKeyValue(input2) {
|
|
77164
|
+
const match = input2.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
|
|
77165
|
+
if (!match) return null;
|
|
77166
|
+
const key = match[1];
|
|
77167
|
+
const value = match[2];
|
|
77168
|
+
if (!key || value === void 0) return null;
|
|
77169
|
+
return { key, value };
|
|
77170
|
+
}
|
|
77171
|
+
async function readExistingConfig(identity, configPath) {
|
|
77172
|
+
if (!existsSync4(configPath)) {
|
|
77173
|
+
return {};
|
|
77174
|
+
}
|
|
77175
|
+
try {
|
|
77176
|
+
const encrypted = readFileSync2(configPath);
|
|
77177
|
+
const decrypter = new Decrypter();
|
|
77178
|
+
decrypter.addIdentity(identity);
|
|
77179
|
+
const decrypted = await decrypter.decrypt(encrypted, "text");
|
|
77180
|
+
const config = {};
|
|
77181
|
+
for (const line of decrypted.split("\n")) {
|
|
77182
|
+
const trimmed = line.trim();
|
|
77183
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
77184
|
+
const eqIndex = trimmed.indexOf("=");
|
|
77185
|
+
if (eqIndex > 0) {
|
|
77186
|
+
const key = trimmed.substring(0, eqIndex);
|
|
77187
|
+
const value = trimmed.substring(eqIndex + 1);
|
|
77188
|
+
config[key] = value;
|
|
77189
|
+
}
|
|
77190
|
+
}
|
|
77191
|
+
return config;
|
|
77192
|
+
} catch {
|
|
77193
|
+
return {};
|
|
77194
|
+
}
|
|
77195
|
+
}
|
|
77196
|
+
async function configSetAction(ctx, keyValue, options = {}) {
|
|
77197
|
+
const outputJson = options.json === true || ctx.format === "json";
|
|
77198
|
+
const keyPath = getAgeKeyPath();
|
|
77199
|
+
if (!existsSync4(keyPath)) {
|
|
77200
|
+
const result = {
|
|
77201
|
+
success: false,
|
|
77202
|
+
error: "Age key not found. Run: skill config init"
|
|
77203
|
+
};
|
|
77204
|
+
if (outputJson) {
|
|
77205
|
+
ctx.output.data(result);
|
|
77206
|
+
} else {
|
|
77207
|
+
ctx.output.error(result.error);
|
|
77208
|
+
}
|
|
77209
|
+
process.exitCode = EXIT_CODES.usage;
|
|
77210
|
+
return;
|
|
77211
|
+
}
|
|
77212
|
+
const parsed = parseKeyValue(keyValue);
|
|
77213
|
+
if (!parsed) {
|
|
77214
|
+
const result = {
|
|
77215
|
+
success: false,
|
|
77216
|
+
error: "Invalid format. Expected: KEY=value"
|
|
77217
|
+
};
|
|
77218
|
+
if (outputJson) {
|
|
77219
|
+
ctx.output.data(result);
|
|
77220
|
+
} else {
|
|
77221
|
+
ctx.output.error(result.error);
|
|
77222
|
+
ctx.output.data("Example: skill config set DATABASE_URL=postgresql://...");
|
|
77223
|
+
}
|
|
77224
|
+
process.exitCode = EXIT_CODES.usage;
|
|
77225
|
+
return;
|
|
77226
|
+
}
|
|
77227
|
+
try {
|
|
77228
|
+
const identity = readFileSync2(keyPath, "utf8").trim();
|
|
77229
|
+
const recipient = await identityToRecipient2(identity);
|
|
77230
|
+
const configPath = getEncryptedConfigPath();
|
|
77231
|
+
const config = await readExistingConfig(identity, configPath);
|
|
77232
|
+
config[parsed.key] = parsed.value;
|
|
77233
|
+
const envContent = Object.entries(config).map(([k, v]) => `${k}=${v}`).join("\n");
|
|
77234
|
+
const encrypter = new Encrypter();
|
|
77235
|
+
encrypter.addRecipient(recipient);
|
|
77236
|
+
const encrypted = await encrypter.encrypt(envContent + "\n");
|
|
77237
|
+
writeFileSync4(configPath, Buffer.from(encrypted));
|
|
77238
|
+
const result = {
|
|
77239
|
+
success: true,
|
|
77240
|
+
key: parsed.key,
|
|
77241
|
+
encrypted: true
|
|
77242
|
+
};
|
|
77243
|
+
if (outputJson) {
|
|
77244
|
+
ctx.output.data(result);
|
|
77245
|
+
} else {
|
|
77246
|
+
ctx.output.success(`Set ${parsed.key} (encrypted)`);
|
|
77247
|
+
ctx.output.data(`Saved to: ${configPath}`);
|
|
77248
|
+
}
|
|
77249
|
+
} catch (error) {
|
|
77250
|
+
const result = {
|
|
77251
|
+
success: false,
|
|
77252
|
+
error: error instanceof Error ? error.message : "Failed to encrypt config"
|
|
77253
|
+
};
|
|
77254
|
+
if (outputJson) {
|
|
77255
|
+
ctx.output.data(result);
|
|
77256
|
+
} else {
|
|
77257
|
+
ctx.output.error(`Failed to set config: ${result.error}`);
|
|
77258
|
+
}
|
|
77259
|
+
process.exitCode = EXIT_CODES.error;
|
|
77260
|
+
}
|
|
77261
|
+
}
|
|
77262
|
+
|
|
77263
|
+
// src/commands/config/get.ts
|
|
77264
|
+
async function decryptConfig(identity) {
|
|
77265
|
+
const configPath = getEncryptedConfigPath();
|
|
77266
|
+
if (!existsSync5(configPath)) {
|
|
77267
|
+
return {};
|
|
77268
|
+
}
|
|
77269
|
+
const encrypted = readFileSync3(configPath);
|
|
77270
|
+
const decrypter = new Decrypter2();
|
|
77271
|
+
decrypter.addIdentity(identity);
|
|
77272
|
+
try {
|
|
77273
|
+
const decrypted = await decrypter.decrypt(encrypted, "text");
|
|
77274
|
+
const config = {};
|
|
77275
|
+
for (const line of decrypted.split("\n")) {
|
|
77276
|
+
const trimmed = line.trim();
|
|
77277
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
77278
|
+
const eqIndex = trimmed.indexOf("=");
|
|
77279
|
+
if (eqIndex > 0) {
|
|
77280
|
+
const key = trimmed.substring(0, eqIndex);
|
|
77281
|
+
const value = trimmed.substring(eqIndex + 1);
|
|
77282
|
+
config[key] = value;
|
|
77283
|
+
}
|
|
77284
|
+
}
|
|
77285
|
+
return config;
|
|
77286
|
+
} catch (error) {
|
|
77287
|
+
throw new Error(
|
|
77288
|
+
`Failed to decrypt config: ${error instanceof Error ? error.message : "unknown error"}`
|
|
77289
|
+
);
|
|
77290
|
+
}
|
|
77291
|
+
}
|
|
77292
|
+
async function configGetAction(ctx, key, options = {}) {
|
|
77293
|
+
const outputJson = options.json === true || ctx.format === "json";
|
|
77294
|
+
const keyPath = getAgeKeyPath();
|
|
77295
|
+
if (!existsSync5(keyPath)) {
|
|
77296
|
+
const result = {
|
|
77297
|
+
success: false,
|
|
77298
|
+
error: "Age key not found. Run: skill config init"
|
|
77299
|
+
};
|
|
77300
|
+
if (outputJson) {
|
|
77301
|
+
ctx.output.data(result);
|
|
77302
|
+
} else {
|
|
77303
|
+
ctx.output.error(result.error);
|
|
77304
|
+
}
|
|
77305
|
+
process.exitCode = EXIT_CODES.usage;
|
|
77306
|
+
return;
|
|
77307
|
+
}
|
|
77308
|
+
try {
|
|
77309
|
+
const identity = readFileSync3(keyPath, "utf8").trim();
|
|
77310
|
+
const config = await decryptConfig(identity);
|
|
77311
|
+
if (!(key in config)) {
|
|
77312
|
+
const result2 = {
|
|
77313
|
+
success: false,
|
|
77314
|
+
key,
|
|
77315
|
+
error: `Key not found: ${key}`
|
|
77316
|
+
};
|
|
77317
|
+
if (outputJson) {
|
|
77318
|
+
ctx.output.data(result2);
|
|
77319
|
+
} else {
|
|
77320
|
+
ctx.output.error(result2.error);
|
|
77321
|
+
}
|
|
77322
|
+
process.exitCode = EXIT_CODES.usage;
|
|
77323
|
+
return;
|
|
77324
|
+
}
|
|
77325
|
+
const result = {
|
|
77326
|
+
success: true,
|
|
77327
|
+
key,
|
|
77328
|
+
value: config[key]
|
|
77329
|
+
};
|
|
77330
|
+
if (outputJson) {
|
|
77331
|
+
ctx.output.data(result);
|
|
77332
|
+
} else {
|
|
77333
|
+
ctx.output.data(config[key]);
|
|
77334
|
+
}
|
|
77335
|
+
} catch (error) {
|
|
77336
|
+
const result = {
|
|
77337
|
+
success: false,
|
|
77338
|
+
key,
|
|
77339
|
+
error: error instanceof Error ? error.message : "Failed to get config"
|
|
77340
|
+
};
|
|
77341
|
+
if (outputJson) {
|
|
77342
|
+
ctx.output.data(result);
|
|
77343
|
+
} else {
|
|
77344
|
+
ctx.output.error(`Failed to get config: ${result.error}`);
|
|
77345
|
+
}
|
|
77346
|
+
process.exitCode = EXIT_CODES.error;
|
|
77347
|
+
}
|
|
77348
|
+
}
|
|
77349
|
+
|
|
77350
|
+
// src/commands/config/list.ts
|
|
77351
|
+
init_esm_shims();
|
|
77352
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
77353
|
+
import { Decrypter as Decrypter3 } from "age-encryption";
|
|
77354
|
+
async function decryptConfig2(identity) {
|
|
77355
|
+
const configPath = getEncryptedConfigPath();
|
|
77356
|
+
if (!existsSync6(configPath)) {
|
|
77357
|
+
return {};
|
|
77358
|
+
}
|
|
77359
|
+
const encrypted = readFileSync4(configPath);
|
|
77360
|
+
const decrypter = new Decrypter3();
|
|
77361
|
+
decrypter.addIdentity(identity);
|
|
77362
|
+
try {
|
|
77363
|
+
const decrypted = await decrypter.decrypt(encrypted, "text");
|
|
77364
|
+
const config = {};
|
|
77365
|
+
for (const line of decrypted.split("\n")) {
|
|
77366
|
+
const trimmed = line.trim();
|
|
77367
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
77368
|
+
const eqIndex = trimmed.indexOf("=");
|
|
77369
|
+
if (eqIndex > 0) {
|
|
77370
|
+
const key = trimmed.substring(0, eqIndex);
|
|
77371
|
+
const value = trimmed.substring(eqIndex + 1);
|
|
77372
|
+
config[key] = value;
|
|
77373
|
+
}
|
|
77374
|
+
}
|
|
77375
|
+
return config;
|
|
77376
|
+
} catch (error) {
|
|
77377
|
+
throw new Error(
|
|
77378
|
+
`Failed to decrypt config: ${error instanceof Error ? error.message : "unknown error"}`
|
|
77379
|
+
);
|
|
77380
|
+
}
|
|
77381
|
+
}
|
|
77382
|
+
async function configListAction(ctx, options = {}) {
|
|
77383
|
+
const outputJson = options.json === true || ctx.format === "json";
|
|
77384
|
+
const keyPath = getAgeKeyPath();
|
|
77385
|
+
if (!existsSync6(keyPath)) {
|
|
77386
|
+
const result = {
|
|
77387
|
+
success: false,
|
|
77388
|
+
error: "Age key not found. Run: skill config init"
|
|
77389
|
+
};
|
|
77390
|
+
if (outputJson) {
|
|
77391
|
+
ctx.output.data(result);
|
|
77392
|
+
} else {
|
|
77393
|
+
ctx.output.error(result.error);
|
|
77394
|
+
}
|
|
77395
|
+
process.exitCode = EXIT_CODES.usage;
|
|
77396
|
+
return;
|
|
77397
|
+
}
|
|
77398
|
+
try {
|
|
77399
|
+
const identity = readFileSync4(keyPath, "utf8").trim();
|
|
77400
|
+
const config = await decryptConfig2(identity);
|
|
77401
|
+
const keys = Object.keys(config);
|
|
77402
|
+
if (keys.length === 0) {
|
|
77403
|
+
const result2 = {
|
|
77404
|
+
success: true,
|
|
77405
|
+
config: {},
|
|
77406
|
+
keys: []
|
|
77407
|
+
};
|
|
77408
|
+
if (outputJson) {
|
|
77409
|
+
ctx.output.data(result2);
|
|
77410
|
+
} else {
|
|
77411
|
+
ctx.output.data("No config overrides set.");
|
|
77412
|
+
ctx.output.data("\nTo add a config: skill config set KEY=value");
|
|
77413
|
+
}
|
|
77414
|
+
return;
|
|
77415
|
+
}
|
|
77416
|
+
const result = {
|
|
77417
|
+
success: true,
|
|
77418
|
+
config: options.showValues ? config : void 0,
|
|
77419
|
+
keys
|
|
77420
|
+
};
|
|
77421
|
+
if (outputJson) {
|
|
77422
|
+
ctx.output.data(result);
|
|
77423
|
+
} else {
|
|
77424
|
+
ctx.output.data("User config overrides:\n");
|
|
77425
|
+
if (options.showValues) {
|
|
77426
|
+
for (const key of keys.sort()) {
|
|
77427
|
+
ctx.output.data(`${key}=${config[key]}`);
|
|
77428
|
+
}
|
|
77429
|
+
} else {
|
|
77430
|
+
for (const key of keys.sort()) {
|
|
77431
|
+
ctx.output.data(`${key}=********`);
|
|
77432
|
+
}
|
|
77433
|
+
ctx.output.data("\nTo view values: skill config list --show-values");
|
|
77434
|
+
}
|
|
77435
|
+
}
|
|
77436
|
+
} catch (error) {
|
|
77437
|
+
const result = {
|
|
77438
|
+
success: false,
|
|
77439
|
+
error: error instanceof Error ? error.message : "Failed to list config"
|
|
77440
|
+
};
|
|
77441
|
+
if (outputJson) {
|
|
77442
|
+
ctx.output.data(result);
|
|
77443
|
+
} else {
|
|
77444
|
+
ctx.output.error(`Failed to list config: ${result.error}`);
|
|
77445
|
+
}
|
|
77446
|
+
process.exitCode = EXIT_CODES.error;
|
|
77447
|
+
}
|
|
77448
|
+
}
|
|
77449
|
+
|
|
77450
|
+
// src/commands/config/index.ts
|
|
77451
|
+
var buildContext2 = async (command, json) => {
|
|
77452
|
+
const opts = typeof command.optsWithGlobals === "function" ? command.optsWithGlobals() : {
|
|
77453
|
+
...command.parent?.opts(),
|
|
77454
|
+
...command.opts()
|
|
77455
|
+
};
|
|
77456
|
+
return createContext({
|
|
77457
|
+
format: json ? "json" : opts.format,
|
|
77458
|
+
verbose: opts.verbose,
|
|
77459
|
+
quiet: opts.quiet
|
|
77460
|
+
});
|
|
77461
|
+
};
|
|
77462
|
+
function registerConfigCommands(program3) {
|
|
77463
|
+
const config = program3.command("config").description("Manage user-specific config overrides (encrypted)");
|
|
77464
|
+
config.command("init").description("Generate age keypair for user config encryption").option("--force", "Overwrite existing keypair").option("--json", "Output as JSON").action(async (options, command) => {
|
|
77465
|
+
const ctx = await buildContext2(command, options.json);
|
|
77466
|
+
await configInitAction(ctx, options);
|
|
77467
|
+
});
|
|
77468
|
+
config.command("set <key-value>").description("Set encrypted config value (format: KEY=value)").option("--json", "Output as JSON").action(async (keyValue, options, command) => {
|
|
77469
|
+
const ctx = await buildContext2(command, options.json);
|
|
77470
|
+
await configSetAction(ctx, keyValue, options);
|
|
77471
|
+
});
|
|
77472
|
+
config.command("get <key>").description("Get decrypted config value").option("--json", "Output as JSON").action(async (key, options, command) => {
|
|
77473
|
+
const ctx = await buildContext2(command, options.json);
|
|
77474
|
+
await configGetAction(ctx, key, options);
|
|
77475
|
+
});
|
|
77476
|
+
config.command("list").description("List all user config overrides").option("--show-values", "Show decrypted values (keys only by default)").option("--json", "Output as JSON").action(async (options, command) => {
|
|
77477
|
+
const ctx = await buildContext2(command, options.json);
|
|
77478
|
+
await configListAction(ctx, options);
|
|
77479
|
+
});
|
|
77480
|
+
}
|
|
77481
|
+
|
|
77018
77482
|
// src/commands/db-status.ts
|
|
77019
77483
|
init_esm_shims();
|
|
77020
77484
|
import "commander";
|
|
@@ -77344,7 +77808,7 @@ function registerDeployCommands(program3) {
|
|
|
77344
77808
|
|
|
77345
77809
|
// src/commands/eval.ts
|
|
77346
77810
|
init_esm_shims();
|
|
77347
|
-
import { access, readFile } from "fs/promises";
|
|
77811
|
+
import { access, readFile as readFile2 } from "fs/promises";
|
|
77348
77812
|
async function runEval(ctx, evalType, datasetPath, options = {}) {
|
|
77349
77813
|
const outputJson = options.json === true || ctx.format === "json";
|
|
77350
77814
|
const { gates } = options;
|
|
@@ -77371,7 +77835,7 @@ async function runEval(ctx, evalType, datasetPath, options = {}) {
|
|
|
77371
77835
|
}
|
|
77372
77836
|
let dataset;
|
|
77373
77837
|
try {
|
|
77374
|
-
const content = await
|
|
77838
|
+
const content = await readFile2(datasetPath, "utf-8");
|
|
77375
77839
|
dataset = JSON.parse(content);
|
|
77376
77840
|
} catch (error) {
|
|
77377
77841
|
throw new CLIError({
|
|
@@ -77763,7 +78227,7 @@ async function checkRedis() {
|
|
|
77763
78227
|
signal: AbortSignal.timeout(5e3)
|
|
77764
78228
|
}).catch(() => null);
|
|
77765
78229
|
const net = await import("net");
|
|
77766
|
-
return new Promise((
|
|
78230
|
+
return new Promise((resolve9) => {
|
|
77767
78231
|
const socket = new net.Socket();
|
|
77768
78232
|
socket.setTimeout(5e3);
|
|
77769
78233
|
socket.on("connect", () => {
|
|
@@ -77773,13 +78237,13 @@ async function checkRedis() {
|
|
|
77773
78237
|
const response2 = data2.toString();
|
|
77774
78238
|
socket.destroy();
|
|
77775
78239
|
if (response2.includes("PONG")) {
|
|
77776
|
-
|
|
78240
|
+
resolve9({
|
|
77777
78241
|
service: "Redis",
|
|
77778
78242
|
healthy: true,
|
|
77779
78243
|
message: "Redis responding to PING"
|
|
77780
78244
|
});
|
|
77781
78245
|
} else {
|
|
77782
|
-
|
|
78246
|
+
resolve9({
|
|
77783
78247
|
service: "Redis",
|
|
77784
78248
|
healthy: false,
|
|
77785
78249
|
message: "Unexpected response"
|
|
@@ -77788,7 +78252,7 @@ async function checkRedis() {
|
|
|
77788
78252
|
});
|
|
77789
78253
|
socket.on("timeout", () => {
|
|
77790
78254
|
socket.destroy();
|
|
77791
|
-
|
|
78255
|
+
resolve9({
|
|
77792
78256
|
service: "Redis",
|
|
77793
78257
|
healthy: false,
|
|
77794
78258
|
message: "Connection timeout"
|
|
@@ -77796,7 +78260,7 @@ async function checkRedis() {
|
|
|
77796
78260
|
});
|
|
77797
78261
|
socket.on("error", (err) => {
|
|
77798
78262
|
socket.destroy();
|
|
77799
|
-
|
|
78263
|
+
resolve9({
|
|
77800
78264
|
service: "Redis",
|
|
77801
78265
|
healthy: false,
|
|
77802
78266
|
message: err.message
|
|
@@ -78037,7 +78501,7 @@ var Helpfulness = ({
|
|
|
78037
78501
|
|
|
78038
78502
|
// src/commands/eval-local/run.ts
|
|
78039
78503
|
import { generateText, stepCountIs, tool as tool2 } from "ai";
|
|
78040
|
-
import { readFile as
|
|
78504
|
+
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
78041
78505
|
import { glob } from "glob";
|
|
78042
78506
|
import { z as z3 } from "zod";
|
|
78043
78507
|
|
|
@@ -78764,14 +79228,14 @@ async function run(ctx, options) {
|
|
|
78764
79228
|
}
|
|
78765
79229
|
let systemPrompt = SUPPORT_AGENT_PROMPT;
|
|
78766
79230
|
if (promptPath) {
|
|
78767
|
-
systemPrompt = await
|
|
79231
|
+
systemPrompt = await readFile3(promptPath, "utf-8");
|
|
78768
79232
|
log(`Using prompt from: ${promptPath}`);
|
|
78769
79233
|
} else {
|
|
78770
79234
|
log("Using production prompt");
|
|
78771
79235
|
}
|
|
78772
79236
|
let scenarios = [];
|
|
78773
79237
|
if (datasetPath) {
|
|
78774
|
-
const datasetContent = await
|
|
79238
|
+
const datasetContent = await readFile3(datasetPath, "utf-8");
|
|
78775
79239
|
const dataset = JSON.parse(datasetContent);
|
|
78776
79240
|
scenarios = dataset.map((item) => {
|
|
78777
79241
|
const trigger = item.triggerMessage || {
|
|
@@ -78804,7 +79268,7 @@ async function run(ctx, options) {
|
|
|
78804
79268
|
}
|
|
78805
79269
|
scenarios = await Promise.all(
|
|
78806
79270
|
scenarioFiles.map(async (file) => {
|
|
78807
|
-
const content = await
|
|
79271
|
+
const content = await readFile3(file, "utf-8");
|
|
78808
79272
|
return JSON.parse(content);
|
|
78809
79273
|
})
|
|
78810
79274
|
);
|
|
@@ -78842,7 +79306,7 @@ async function run(ctx, options) {
|
|
|
78842
79306
|
const summary = aggregateResults(results, totalDuration);
|
|
78843
79307
|
if (baseline) {
|
|
78844
79308
|
try {
|
|
78845
|
-
const baselineContent = await
|
|
79309
|
+
const baselineContent = await readFile3(baseline, "utf-8");
|
|
78846
79310
|
const baselineData = JSON.parse(baselineContent);
|
|
78847
79311
|
printComparison(ctx, summary, baselineData.summary || baselineData);
|
|
78848
79312
|
} catch (e) {
|
|
@@ -79169,14 +79633,14 @@ function printComparison(ctx, current, baseline) {
|
|
|
79169
79633
|
|
|
79170
79634
|
// src/commands/eval-local/score-production.ts
|
|
79171
79635
|
init_esm_shims();
|
|
79172
|
-
import { readFile as
|
|
79636
|
+
import { readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
|
|
79173
79637
|
async function scoreProduction(ctx, options) {
|
|
79174
79638
|
const { dataset: datasetPath, output, verbose, json } = options;
|
|
79175
79639
|
const outputJson = json === true || ctx.format === "json";
|
|
79176
79640
|
const log = (text3) => {
|
|
79177
79641
|
if (!outputJson) ctx.output.data(text3);
|
|
79178
79642
|
};
|
|
79179
|
-
const datasetContent = await
|
|
79643
|
+
const datasetContent = await readFile4(datasetPath, "utf-8");
|
|
79180
79644
|
const dataset = JSON.parse(datasetContent);
|
|
79181
79645
|
log(`
|
|
79182
79646
|
\u{1F4CA} Scoring ${dataset.length} production responses
|
|
@@ -79349,13 +79813,13 @@ async function scoreProduction(ctx, options) {
|
|
|
79349
79813
|
|
|
79350
79814
|
// src/commands/eval-local/seed.ts
|
|
79351
79815
|
init_esm_shims();
|
|
79352
|
-
import { join as
|
|
79816
|
+
import { join as join4 } from "path";
|
|
79353
79817
|
import { glob as glob3 } from "glob";
|
|
79354
79818
|
|
|
79355
79819
|
// src/lib/eval-seed.ts
|
|
79356
79820
|
init_esm_shims();
|
|
79357
|
-
import { join } from "path";
|
|
79358
|
-
import { readFile as
|
|
79821
|
+
import { join as join3 } from "path";
|
|
79822
|
+
import { readFile as readFile5, readdir } from "fs/promises";
|
|
79359
79823
|
import { glob as glob2 } from "glob";
|
|
79360
79824
|
import matter from "gray-matter";
|
|
79361
79825
|
function generateUUID() {
|
|
@@ -79400,7 +79864,7 @@ async function loadJsonFiles(dirPath) {
|
|
|
79400
79864
|
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
79401
79865
|
const items = await Promise.all(
|
|
79402
79866
|
jsonFiles.map(async (file) => {
|
|
79403
|
-
const content = await
|
|
79867
|
+
const content = await readFile5(join3(dirPath, file), "utf-8");
|
|
79404
79868
|
return JSON.parse(content);
|
|
79405
79869
|
})
|
|
79406
79870
|
);
|
|
@@ -79410,10 +79874,10 @@ async function loadJsonFiles(dirPath) {
|
|
|
79410
79874
|
}
|
|
79411
79875
|
}
|
|
79412
79876
|
async function loadKnowledgeFiles(basePath) {
|
|
79413
|
-
const files = await glob2(
|
|
79877
|
+
const files = await glob2(join3(basePath, "**/*.md"));
|
|
79414
79878
|
const docs = [];
|
|
79415
79879
|
for (const filePath of files) {
|
|
79416
|
-
const content = await
|
|
79880
|
+
const content = await readFile5(filePath, "utf-8");
|
|
79417
79881
|
const { data: frontmatter, content: body } = matter(content);
|
|
79418
79882
|
const titleMatch = body.match(/^#\s+(.+)$/m);
|
|
79419
79883
|
const title = titleMatch?.[1] ?? filePath.split("/").pop()?.replace(".md", "") ?? "Untitled";
|
|
@@ -79600,16 +80064,16 @@ async function seed(ctx, options) {
|
|
|
79600
80064
|
await cleanQdrant();
|
|
79601
80065
|
}
|
|
79602
80066
|
log("\u{1F4E6} Seeding apps...");
|
|
79603
|
-
const apps = await loadJsonFiles(
|
|
80067
|
+
const apps = await loadJsonFiles(join4(fixturesPath, "apps"));
|
|
79604
80068
|
result.apps = await seedApps(connection, apps);
|
|
79605
80069
|
log("\u{1F465} Loading customer fixtures...");
|
|
79606
|
-
const customers = await loadJsonFiles(
|
|
80070
|
+
const customers = await loadJsonFiles(join4(fixturesPath, "customers"));
|
|
79607
80071
|
result.customers = customers.length;
|
|
79608
80072
|
log("\u{1F4DA} Seeding knowledge base...");
|
|
79609
|
-
const knowledge = await loadKnowledgeFiles(
|
|
80073
|
+
const knowledge = await loadKnowledgeFiles(join4(fixturesPath, "knowledge"));
|
|
79610
80074
|
result.knowledge = knowledge.length;
|
|
79611
80075
|
result.embeddings = await seedKnowledgeBase(knowledge, !outputJson);
|
|
79612
|
-
const scenarioFiles = await glob3(
|
|
80076
|
+
const scenarioFiles = await glob3(join4(fixturesPath, "scenarios/**/*.json"));
|
|
79613
80077
|
result.scenarios = scenarioFiles.length;
|
|
79614
80078
|
await connection.end();
|
|
79615
80079
|
if (outputJson) {
|
|
@@ -79639,7 +80103,7 @@ async function seed(ctx, options) {
|
|
|
79639
80103
|
}
|
|
79640
80104
|
|
|
79641
80105
|
// src/commands/eval-local/index.ts
|
|
79642
|
-
var
|
|
80106
|
+
var buildContext3 = async (command, json) => {
|
|
79643
80107
|
const opts = typeof command.optsWithGlobals === "function" ? command.optsWithGlobals() : {
|
|
79644
80108
|
...command.parent?.opts(),
|
|
79645
80109
|
...command.opts()
|
|
@@ -79653,11 +80117,11 @@ var buildContext2 = async (command, json) => {
|
|
|
79653
80117
|
function registerEvalLocalCommands(program3) {
|
|
79654
80118
|
const evalLocal = program3.command("eval-local").description("Local evaluation environment commands");
|
|
79655
80119
|
evalLocal.command("health").description("Check health of local eval environment services").option("--json", "Output as JSON").action(async (options, command) => {
|
|
79656
|
-
const ctx = await
|
|
80120
|
+
const ctx = await buildContext3(command, options.json);
|
|
79657
80121
|
await health(ctx, options);
|
|
79658
80122
|
});
|
|
79659
80123
|
evalLocal.command("seed").description("Seed the local eval environment with fixtures").option("--clean", "Drop and recreate all data before seeding").option("--fixtures <path>", "Path to fixtures directory", "fixtures").option("--json", "Output as JSON").action(async (options, command) => {
|
|
79660
|
-
const ctx = await
|
|
80124
|
+
const ctx = await buildContext3(command, options.json);
|
|
79661
80125
|
await seed(ctx, options);
|
|
79662
80126
|
});
|
|
79663
80127
|
evalLocal.command("run").description("Run eval suite against local environment").option("--scenarios <glob>", "Scenario files glob pattern").option("--dataset <file>", "Dataset JSON file (alternative to scenarios)").option("--prompt <file>", "Custom prompt file (default: production)").option("--model <model>", "Model to use", "anthropic/claude-haiku-4-5").option("--limit <number>", "Max scenarios to run", parseInt).option("--output <file>", "Save results to JSON file").option("--baseline <file>", "Compare against baseline results").option(
|
|
@@ -79665,7 +80129,7 @@ function registerEvalLocalCommands(program3) {
|
|
|
79665
80129
|
"Fail if pass rate below threshold",
|
|
79666
80130
|
parseFloat
|
|
79667
80131
|
).option("--verbose", "Show individual scenario results").option("--json", "JSON output for scripting").option("--real-tools", "Use real Docker services instead of mocks").action(async (options, command) => {
|
|
79668
|
-
const ctx = await
|
|
80132
|
+
const ctx = await buildContext3(command, options.json);
|
|
79669
80133
|
await run(ctx, options);
|
|
79670
80134
|
});
|
|
79671
80135
|
evalLocal.command("score-production").description(
|
|
@@ -79674,7 +80138,7 @@ function registerEvalLocalCommands(program3) {
|
|
|
79674
80138
|
"--dataset <file>",
|
|
79675
80139
|
"Dataset JSON file with production responses"
|
|
79676
80140
|
).option("--output <file>", "Save results to JSON file").option("--verbose", "Show individual failures").option("--json", "JSON output for scripting").action(async (options, command) => {
|
|
79677
|
-
const ctx = await
|
|
80141
|
+
const ctx = await buildContext3(command, options.json);
|
|
79678
80142
|
await scoreProduction(ctx, options);
|
|
79679
80143
|
});
|
|
79680
80144
|
}
|
|
@@ -79685,9 +80149,9 @@ init_esm_shims();
|
|
|
79685
80149
|
// src/commands/eval-pipeline/run.ts
|
|
79686
80150
|
init_esm_shims();
|
|
79687
80151
|
import { createHash as createHash2 } from "crypto";
|
|
79688
|
-
import { existsSync as
|
|
79689
|
-
import { join as
|
|
79690
|
-
import { readFile as
|
|
80152
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, rmSync, writeFileSync as writeFileSync5 } from "fs";
|
|
80153
|
+
import { join as join5 } from "path";
|
|
80154
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
79691
80155
|
import { glob as glob4 } from "glob";
|
|
79692
80156
|
|
|
79693
80157
|
// src/commands/eval-pipeline/real-tools.ts
|
|
@@ -80099,12 +80563,12 @@ function getCacheKey(scenarioId, classifySourceHash) {
|
|
|
80099
80563
|
function getClassifySourceHash() {
|
|
80100
80564
|
try {
|
|
80101
80565
|
const possiblePaths = [
|
|
80102
|
-
|
|
80103
|
-
|
|
80566
|
+
join5(process.cwd(), "packages/core/src/pipeline/classify.ts"),
|
|
80567
|
+
join5(process.cwd(), "../core/src/pipeline/classify.ts")
|
|
80104
80568
|
];
|
|
80105
80569
|
for (const path of possiblePaths) {
|
|
80106
|
-
if (
|
|
80107
|
-
const content =
|
|
80570
|
+
if (existsSync7(path)) {
|
|
80571
|
+
const content = readFileSync5(path, "utf-8");
|
|
80108
80572
|
return createHash2("md5").update(content).digest("hex");
|
|
80109
80573
|
}
|
|
80110
80574
|
}
|
|
@@ -80113,10 +80577,10 @@ function getClassifySourceHash() {
|
|
|
80113
80577
|
return createHash2("md5").update(Math.floor(Date.now() / 3e5).toString()).digest("hex");
|
|
80114
80578
|
}
|
|
80115
80579
|
function loadCachedClassify(cacheKey) {
|
|
80116
|
-
const cachePath =
|
|
80580
|
+
const cachePath = join5(CACHE_DIR, `${cacheKey}.json`);
|
|
80117
80581
|
try {
|
|
80118
|
-
if (
|
|
80119
|
-
return JSON.parse(
|
|
80582
|
+
if (existsSync7(cachePath)) {
|
|
80583
|
+
return JSON.parse(readFileSync5(cachePath, "utf-8"));
|
|
80120
80584
|
}
|
|
80121
80585
|
} catch {
|
|
80122
80586
|
}
|
|
@@ -80124,17 +80588,17 @@ function loadCachedClassify(cacheKey) {
|
|
|
80124
80588
|
}
|
|
80125
80589
|
function saveCachedClassify(cacheKey, result) {
|
|
80126
80590
|
try {
|
|
80127
|
-
if (!
|
|
80128
|
-
|
|
80591
|
+
if (!existsSync7(CACHE_DIR)) {
|
|
80592
|
+
mkdirSync2(CACHE_DIR, { recursive: true });
|
|
80129
80593
|
}
|
|
80130
|
-
const cachePath =
|
|
80131
|
-
|
|
80594
|
+
const cachePath = join5(CACHE_DIR, `${cacheKey}.json`);
|
|
80595
|
+
writeFileSync5(cachePath, JSON.stringify(result));
|
|
80132
80596
|
} catch {
|
|
80133
80597
|
}
|
|
80134
80598
|
}
|
|
80135
80599
|
function clearClassifyCache() {
|
|
80136
80600
|
try {
|
|
80137
|
-
if (
|
|
80601
|
+
if (existsSync7(CACHE_DIR)) {
|
|
80138
80602
|
rmSync(CACHE_DIR, { recursive: true, force: true });
|
|
80139
80603
|
}
|
|
80140
80604
|
} catch {
|
|
@@ -80273,7 +80737,7 @@ async function run2(ctx, options) {
|
|
|
80273
80737
|
}
|
|
80274
80738
|
async function loadScenarios(scenarioGlob, datasetPath) {
|
|
80275
80739
|
if (datasetPath) {
|
|
80276
|
-
const content = await
|
|
80740
|
+
const content = await readFile6(datasetPath, "utf-8");
|
|
80277
80741
|
const data2 = JSON.parse(content);
|
|
80278
80742
|
return data2.map((item) => ({
|
|
80279
80743
|
id: item.id || item.conversationId,
|
|
@@ -80297,7 +80761,7 @@ async function loadScenarios(scenarioGlob, datasetPath) {
|
|
|
80297
80761
|
}
|
|
80298
80762
|
return Promise.all(
|
|
80299
80763
|
files.map(async (file) => {
|
|
80300
|
-
const content = await
|
|
80764
|
+
const content = await readFile6(file, "utf-8");
|
|
80301
80765
|
return JSON.parse(content);
|
|
80302
80766
|
})
|
|
80303
80767
|
);
|
|
@@ -81010,7 +81474,7 @@ Latency: ${avgLatency.toFixed(0)}ms avg`);
|
|
|
81010
81474
|
|
|
81011
81475
|
// src/commands/eval-pipeline/seed.ts
|
|
81012
81476
|
init_esm_shims();
|
|
81013
|
-
import { join as
|
|
81477
|
+
import { join as join6 } from "path";
|
|
81014
81478
|
import { glob as glob5 } from "glob";
|
|
81015
81479
|
async function seed2(ctx, options) {
|
|
81016
81480
|
const fixturesPath = options.fixtures || "fixtures";
|
|
@@ -81041,20 +81505,20 @@ async function seed2(ctx, options) {
|
|
|
81041
81505
|
await cleanQdrant();
|
|
81042
81506
|
}
|
|
81043
81507
|
if (!outputJson) ctx.output.message("\u{1F4E6} Seeding apps...");
|
|
81044
|
-
const apps = await loadJsonFiles(
|
|
81508
|
+
const apps = await loadJsonFiles(join6(fixturesPath, "apps"));
|
|
81045
81509
|
result.apps = await seedApps(connection, apps);
|
|
81046
81510
|
const [trustRows] = await connection.execute(
|
|
81047
81511
|
"SELECT COUNT(*) as count FROM SUPPORT_trust_scores"
|
|
81048
81512
|
);
|
|
81049
81513
|
result.trustScores = trustRows[0].count;
|
|
81050
81514
|
if (!outputJson) ctx.output.message("\u{1F465} Loading customer fixtures...");
|
|
81051
|
-
const customers = await loadJsonFiles(
|
|
81515
|
+
const customers = await loadJsonFiles(join6(fixturesPath, "customers"));
|
|
81052
81516
|
result.customers = customers.length;
|
|
81053
81517
|
if (!outputJson) ctx.output.message("\u{1F4DA} Seeding knowledge base...");
|
|
81054
|
-
const knowledge = await loadKnowledgeFiles(
|
|
81518
|
+
const knowledge = await loadKnowledgeFiles(join6(fixturesPath, "knowledge"));
|
|
81055
81519
|
result.knowledge = knowledge.length;
|
|
81056
81520
|
result.embeddings = await seedKnowledgeBase(knowledge, !outputJson);
|
|
81057
|
-
const scenarioFiles = await glob5(
|
|
81521
|
+
const scenarioFiles = await glob5(join6(fixturesPath, "scenarios/**/*.json"));
|
|
81058
81522
|
result.scenarios = scenarioFiles.length;
|
|
81059
81523
|
await connection.end();
|
|
81060
81524
|
if (outputJson) {
|
|
@@ -81126,7 +81590,7 @@ function registerEvalPipelineCommands(program3) {
|
|
|
81126
81590
|
|
|
81127
81591
|
// src/commands/eval-prompt.ts
|
|
81128
81592
|
init_esm_shims();
|
|
81129
|
-
import { existsSync as
|
|
81593
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
81130
81594
|
import { generateText as generateText2, stepCountIs as stepCountIs2, tool as tool4 } from "ai";
|
|
81131
81595
|
import { z as z5 } from "zod";
|
|
81132
81596
|
var leakPatterns = [
|
|
@@ -81313,27 +81777,27 @@ async function runEval2(ctx, options) {
|
|
|
81313
81777
|
try {
|
|
81314
81778
|
let prompt = SUPPORT_AGENT_PROMPT;
|
|
81315
81779
|
if (promptPath) {
|
|
81316
|
-
if (!
|
|
81780
|
+
if (!existsSync8(promptPath)) {
|
|
81317
81781
|
throw new CLIError({
|
|
81318
81782
|
userMessage: `Prompt file not found: ${promptPath}.`,
|
|
81319
81783
|
suggestion: "Verify the prompt path and try again."
|
|
81320
81784
|
});
|
|
81321
81785
|
}
|
|
81322
|
-
prompt =
|
|
81786
|
+
prompt = readFileSync6(promptPath, "utf-8");
|
|
81323
81787
|
if (!outputJson) {
|
|
81324
81788
|
ctx.output.message(`Using prompt from: ${promptPath}`);
|
|
81325
81789
|
}
|
|
81326
81790
|
} else if (!outputJson) {
|
|
81327
81791
|
ctx.output.message("Using production prompt");
|
|
81328
81792
|
}
|
|
81329
|
-
if (!
|
|
81793
|
+
if (!existsSync8(datasetPath)) {
|
|
81330
81794
|
throw new CLIError({
|
|
81331
81795
|
userMessage: `Dataset not found: ${datasetPath}.`,
|
|
81332
81796
|
suggestion: "Provide a valid dataset file path."
|
|
81333
81797
|
});
|
|
81334
81798
|
}
|
|
81335
81799
|
const dataset = JSON.parse(
|
|
81336
|
-
|
|
81800
|
+
readFileSync6(datasetPath, "utf-8")
|
|
81337
81801
|
);
|
|
81338
81802
|
const samples = dataset.slice(0, limit2);
|
|
81339
81803
|
if (!outputJson) {
|
|
@@ -81409,7 +81873,7 @@ async function runEval2(ctx, options) {
|
|
|
81409
81873
|
});
|
|
81410
81874
|
}
|
|
81411
81875
|
if (outputPath) {
|
|
81412
|
-
|
|
81876
|
+
writeFileSync6(outputPath, JSON.stringify(results, null, 2));
|
|
81413
81877
|
if (!outputJson) {
|
|
81414
81878
|
ctx.output.success(`Saved results to ${outputPath}`);
|
|
81415
81879
|
}
|
|
@@ -81436,16 +81900,16 @@ async function comparePrompts(ctx, options) {
|
|
|
81436
81900
|
model = "anthropic/claude-haiku-4-5"
|
|
81437
81901
|
} = options;
|
|
81438
81902
|
try {
|
|
81439
|
-
const baselinePrompt = baseline ?
|
|
81440
|
-
const candidatePrompt =
|
|
81441
|
-
if (!
|
|
81903
|
+
const baselinePrompt = baseline ? readFileSync6(baseline, "utf-8") : SUPPORT_AGENT_PROMPT;
|
|
81904
|
+
const candidatePrompt = readFileSync6(candidate, "utf-8");
|
|
81905
|
+
if (!existsSync8(datasetPath)) {
|
|
81442
81906
|
throw new CLIError({
|
|
81443
81907
|
userMessage: `Dataset not found: ${datasetPath}.`,
|
|
81444
81908
|
suggestion: "Provide a valid dataset file path."
|
|
81445
81909
|
});
|
|
81446
81910
|
}
|
|
81447
81911
|
const dataset = JSON.parse(
|
|
81448
|
-
|
|
81912
|
+
readFileSync6(datasetPath, "utf-8")
|
|
81449
81913
|
);
|
|
81450
81914
|
const samples = dataset.slice(0, limit2);
|
|
81451
81915
|
if (!outputJson) {
|
|
@@ -81586,20 +82050,20 @@ init_esm_shims();
|
|
|
81586
82050
|
|
|
81587
82051
|
// src/commands/faq/classify.ts
|
|
81588
82052
|
init_esm_shims();
|
|
81589
|
-
import { appendFileSync, existsSync as
|
|
81590
|
-
import { dirname as
|
|
82053
|
+
import { appendFileSync, existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
82054
|
+
import { dirname as dirname3, join as join7, resolve as resolve3 } from "path";
|
|
81591
82055
|
import { generateObject } from "ai";
|
|
81592
82056
|
import { z as z6 } from "zod";
|
|
81593
|
-
var PROJECT_ROOT =
|
|
81594
|
-
var DEFAULT_PARQUET_PATH =
|
|
82057
|
+
var PROJECT_ROOT = resolve3(__dirname, "../../../..");
|
|
82058
|
+
var DEFAULT_PARQUET_PATH = join7(
|
|
81595
82059
|
PROJECT_ROOT,
|
|
81596
82060
|
"artifacts/phase-0/embeddings/v2/conversations.parquet"
|
|
81597
82061
|
);
|
|
81598
|
-
var DEFAULT_TAXONOMY_PATH =
|
|
82062
|
+
var DEFAULT_TAXONOMY_PATH = join7(
|
|
81599
82063
|
PROJECT_ROOT,
|
|
81600
82064
|
"artifacts/phase-1/llm-topics/taxonomy.json"
|
|
81601
82065
|
);
|
|
81602
|
-
var DEFAULT_OUTPUT_PATH =
|
|
82066
|
+
var DEFAULT_OUTPUT_PATH = join7(
|
|
81603
82067
|
PROJECT_ROOT,
|
|
81604
82068
|
"artifacts/phase-1/llm-topics/classifications.jsonl"
|
|
81605
82069
|
);
|
|
@@ -81654,10 +82118,10 @@ async function loadConversationsFromParquet(parquetPath) {
|
|
|
81654
82118
|
}
|
|
81655
82119
|
function loadExistingClassifications(outputPath) {
|
|
81656
82120
|
const classifiedIds = /* @__PURE__ */ new Set();
|
|
81657
|
-
if (!
|
|
82121
|
+
if (!existsSync9(outputPath)) {
|
|
81658
82122
|
return classifiedIds;
|
|
81659
82123
|
}
|
|
81660
|
-
const content =
|
|
82124
|
+
const content = readFileSync7(outputPath, "utf-8");
|
|
81661
82125
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
81662
82126
|
for (const line of lines) {
|
|
81663
82127
|
try {
|
|
@@ -81772,7 +82236,7 @@ async function faqClassify(ctx, options) {
|
|
|
81772
82236
|
ctx.output.data(` Dry run: ${options.dryRun ?? false}`);
|
|
81773
82237
|
ctx.output.data("");
|
|
81774
82238
|
}
|
|
81775
|
-
if (!
|
|
82239
|
+
if (!existsSync9(parquetPath)) {
|
|
81776
82240
|
handleFaqClassifyError(
|
|
81777
82241
|
ctx,
|
|
81778
82242
|
new CLIError({
|
|
@@ -81783,7 +82247,7 @@ async function faqClassify(ctx, options) {
|
|
|
81783
82247
|
);
|
|
81784
82248
|
return;
|
|
81785
82249
|
}
|
|
81786
|
-
if (!
|
|
82250
|
+
if (!existsSync9(taxonomyPath)) {
|
|
81787
82251
|
handleFaqClassifyError(
|
|
81788
82252
|
ctx,
|
|
81789
82253
|
new CLIError({
|
|
@@ -81794,12 +82258,12 @@ async function faqClassify(ctx, options) {
|
|
|
81794
82258
|
);
|
|
81795
82259
|
return;
|
|
81796
82260
|
}
|
|
81797
|
-
const outputDir =
|
|
81798
|
-
if (!
|
|
81799
|
-
|
|
82261
|
+
const outputDir = dirname3(outputPath);
|
|
82262
|
+
if (!existsSync9(outputDir)) {
|
|
82263
|
+
mkdirSync3(outputDir, { recursive: true });
|
|
81800
82264
|
}
|
|
81801
82265
|
if (!outputJson) ctx.output.data("\u{1F4DA} Loading taxonomy...");
|
|
81802
|
-
const taxonomy = JSON.parse(
|
|
82266
|
+
const taxonomy = JSON.parse(readFileSync7(taxonomyPath, "utf-8"));
|
|
81803
82267
|
const validTopicIds = new Set(taxonomy.topics.map((t2) => t2.id));
|
|
81804
82268
|
validTopicIds.add("unknown");
|
|
81805
82269
|
if (!outputJson) {
|
|
@@ -81964,51 +82428,51 @@ function registerFaqClassifyCommands(program3) {
|
|
|
81964
82428
|
|
|
81965
82429
|
// src/commands/faq/cluster.ts
|
|
81966
82430
|
init_esm_shims();
|
|
81967
|
-
import { existsSync as
|
|
81968
|
-
import { join as
|
|
82431
|
+
import { existsSync as existsSync11 } from "fs";
|
|
82432
|
+
import { join as join9, resolve as resolve4 } from "path";
|
|
81969
82433
|
|
|
81970
82434
|
// ../core/src/faq/production-clusterer.ts
|
|
81971
82435
|
init_esm_shims();
|
|
81972
|
-
import { existsSync as
|
|
81973
|
-
import { join as
|
|
82436
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
82437
|
+
import { join as join8 } from "path";
|
|
81974
82438
|
function readPhase0Assignments(phase0Path) {
|
|
81975
|
-
const assignmentsPath =
|
|
81976
|
-
if (!
|
|
81977
|
-
const latestPath =
|
|
81978
|
-
if (!
|
|
82439
|
+
const assignmentsPath = join8(phase0Path, "clusters/v1/assignments.json");
|
|
82440
|
+
if (!existsSync10(assignmentsPath)) {
|
|
82441
|
+
const latestPath = join8(phase0Path, "clusters/latest/assignments.json");
|
|
82442
|
+
if (!existsSync10(latestPath)) {
|
|
81979
82443
|
throw new Error(`Phase 0 assignments not found at ${assignmentsPath}`);
|
|
81980
82444
|
}
|
|
81981
|
-
const content2 =
|
|
82445
|
+
const content2 = readFileSync8(latestPath, "utf-8");
|
|
81982
82446
|
return JSON.parse(content2);
|
|
81983
82447
|
}
|
|
81984
|
-
const content =
|
|
82448
|
+
const content = readFileSync8(assignmentsPath, "utf-8");
|
|
81985
82449
|
return JSON.parse(content);
|
|
81986
82450
|
}
|
|
81987
82451
|
function readPhase0Labels(phase0Path) {
|
|
81988
|
-
const labelsPath =
|
|
81989
|
-
if (!
|
|
81990
|
-
const latestPath =
|
|
81991
|
-
if (!
|
|
82452
|
+
const labelsPath = join8(phase0Path, "clusters/v1/labels.json");
|
|
82453
|
+
if (!existsSync10(labelsPath)) {
|
|
82454
|
+
const latestPath = join8(phase0Path, "clusters/latest/labels.json");
|
|
82455
|
+
if (!existsSync10(latestPath)) {
|
|
81992
82456
|
throw new Error(`Phase 0 labels not found at ${labelsPath}`);
|
|
81993
82457
|
}
|
|
81994
|
-
const content2 =
|
|
82458
|
+
const content2 = readFileSync8(latestPath, "utf-8");
|
|
81995
82459
|
const parsed2 = JSON.parse(content2);
|
|
81996
82460
|
return parsed2.clusters || [];
|
|
81997
82461
|
}
|
|
81998
|
-
const content =
|
|
82462
|
+
const content = readFileSync8(labelsPath, "utf-8");
|
|
81999
82463
|
const parsed = JSON.parse(content);
|
|
82000
82464
|
return parsed.clusters || [];
|
|
82001
82465
|
}
|
|
82002
82466
|
function readPhase0Metrics(phase0Path) {
|
|
82003
|
-
const metricsPath =
|
|
82004
|
-
if (!
|
|
82005
|
-
const latestPath =
|
|
82006
|
-
if (!
|
|
82467
|
+
const metricsPath = join8(phase0Path, "clusters/v1/metrics.json");
|
|
82468
|
+
if (!existsSync10(metricsPath)) {
|
|
82469
|
+
const latestPath = join8(phase0Path, "clusters/latest/metrics.json");
|
|
82470
|
+
if (!existsSync10(latestPath)) {
|
|
82007
82471
|
throw new Error(`Phase 0 metrics not found at ${metricsPath}`);
|
|
82008
82472
|
}
|
|
82009
|
-
return JSON.parse(
|
|
82473
|
+
return JSON.parse(readFileSync8(latestPath, "utf-8"));
|
|
82010
82474
|
}
|
|
82011
|
-
return JSON.parse(
|
|
82475
|
+
return JSON.parse(readFileSync8(metricsPath, "utf-8"));
|
|
82012
82476
|
}
|
|
82013
82477
|
function calculateConfidence2(distance) {
|
|
82014
82478
|
if (distance === null) return 0;
|
|
@@ -82123,18 +82587,18 @@ async function generateProductionClustering(options) {
|
|
|
82123
82587
|
return result;
|
|
82124
82588
|
}
|
|
82125
82589
|
function writeProductionArtifacts(result, outputPath) {
|
|
82126
|
-
const versionPath =
|
|
82127
|
-
if (!
|
|
82128
|
-
|
|
82590
|
+
const versionPath = join8(outputPath, result.version);
|
|
82591
|
+
if (!existsSync10(versionPath)) {
|
|
82592
|
+
mkdirSync4(versionPath, { recursive: true });
|
|
82129
82593
|
}
|
|
82130
|
-
const resultPath =
|
|
82131
|
-
|
|
82594
|
+
const resultPath = join8(versionPath, "clustering-result.json");
|
|
82595
|
+
writeFileSync7(resultPath, JSON.stringify(result, null, 2));
|
|
82132
82596
|
console.log(`\u2705 Written: ${resultPath}`);
|
|
82133
|
-
const assignmentsPath =
|
|
82134
|
-
|
|
82597
|
+
const assignmentsPath = join8(versionPath, "assignments.json");
|
|
82598
|
+
writeFileSync7(assignmentsPath, JSON.stringify(result.assignments, null, 2));
|
|
82135
82599
|
console.log(`\u2705 Written: ${assignmentsPath}`);
|
|
82136
|
-
const clustersPath =
|
|
82137
|
-
|
|
82600
|
+
const clustersPath = join8(versionPath, "clusters.json");
|
|
82601
|
+
writeFileSync7(
|
|
82138
82602
|
clustersPath,
|
|
82139
82603
|
JSON.stringify(
|
|
82140
82604
|
{
|
|
@@ -82148,7 +82612,7 @@ function writeProductionArtifacts(result, outputPath) {
|
|
|
82148
82612
|
)
|
|
82149
82613
|
);
|
|
82150
82614
|
console.log(`\u2705 Written: ${clustersPath}`);
|
|
82151
|
-
const summaryPath =
|
|
82615
|
+
const summaryPath = join8(versionPath, "summary.json");
|
|
82152
82616
|
const summary = {
|
|
82153
82617
|
version: result.version,
|
|
82154
82618
|
generatedAt: result.generatedAt,
|
|
@@ -82160,23 +82624,23 @@ function writeProductionArtifacts(result, outputPath) {
|
|
|
82160
82624
|
priorityTier: c.priorityTier
|
|
82161
82625
|
}))
|
|
82162
82626
|
};
|
|
82163
|
-
|
|
82627
|
+
writeFileSync7(summaryPath, JSON.stringify(summary, null, 2));
|
|
82164
82628
|
console.log(`\u2705 Written: ${summaryPath}`);
|
|
82165
|
-
const latestPath =
|
|
82166
|
-
if (
|
|
82629
|
+
const latestPath = join8(outputPath, "latest");
|
|
82630
|
+
if (existsSync10(latestPath)) {
|
|
82167
82631
|
const { rmSync: rmSync2 } = __require("fs");
|
|
82168
82632
|
rmSync2(latestPath, { recursive: true, force: true });
|
|
82169
82633
|
}
|
|
82170
|
-
|
|
82634
|
+
mkdirSync4(latestPath, { recursive: true });
|
|
82171
82635
|
for (const file of [
|
|
82172
82636
|
"clustering-result.json",
|
|
82173
82637
|
"assignments.json",
|
|
82174
82638
|
"clusters.json",
|
|
82175
82639
|
"summary.json"
|
|
82176
82640
|
]) {
|
|
82177
|
-
const src =
|
|
82178
|
-
const dst =
|
|
82179
|
-
|
|
82641
|
+
const src = join8(versionPath, file);
|
|
82642
|
+
const dst = join8(latestPath, file);
|
|
82643
|
+
writeFileSync7(dst, readFileSync8(src));
|
|
82180
82644
|
}
|
|
82181
82645
|
console.log(`\u2705 Updated: ${latestPath}`);
|
|
82182
82646
|
}
|
|
@@ -82227,26 +82691,26 @@ function displayClusteringSummary(result) {
|
|
|
82227
82691
|
}
|
|
82228
82692
|
|
|
82229
82693
|
// src/commands/faq/cluster.ts
|
|
82230
|
-
var PROJECT_ROOT2 =
|
|
82231
|
-
var DEFAULT_PHASE0_PATH =
|
|
82232
|
-
var DEFAULT_OUTPUT_PATH2 =
|
|
82694
|
+
var PROJECT_ROOT2 = resolve4(__dirname, "../../../..");
|
|
82695
|
+
var DEFAULT_PHASE0_PATH = join9(PROJECT_ROOT2, "artifacts/phase-0");
|
|
82696
|
+
var DEFAULT_OUTPUT_PATH2 = join9(PROJECT_ROOT2, "artifacts/phase-1/clustering");
|
|
82233
82697
|
function validatePaths(phase0Path) {
|
|
82234
|
-
const assignmentsPath =
|
|
82235
|
-
const labelsPath =
|
|
82236
|
-
const metricsPath =
|
|
82237
|
-
if (!
|
|
82698
|
+
const assignmentsPath = join9(phase0Path, "clusters/v1/assignments.json");
|
|
82699
|
+
const labelsPath = join9(phase0Path, "clusters/v1/labels.json");
|
|
82700
|
+
const metricsPath = join9(phase0Path, "clusters/v1/metrics.json");
|
|
82701
|
+
if (!existsSync11(assignmentsPath)) {
|
|
82238
82702
|
throw new CLIError({
|
|
82239
82703
|
userMessage: `Phase 0 assignments not found at ${assignmentsPath}.`,
|
|
82240
82704
|
suggestion: "Run Phase 0 clustering first or specify the correct --phase0-path."
|
|
82241
82705
|
});
|
|
82242
82706
|
}
|
|
82243
|
-
if (!
|
|
82707
|
+
if (!existsSync11(labelsPath)) {
|
|
82244
82708
|
throw new CLIError({
|
|
82245
82709
|
userMessage: `Phase 0 labels not found at ${labelsPath}.`,
|
|
82246
82710
|
suggestion: "Verify the --phase0-path points to valid artifacts."
|
|
82247
82711
|
});
|
|
82248
82712
|
}
|
|
82249
|
-
if (!
|
|
82713
|
+
if (!existsSync11(metricsPath)) {
|
|
82250
82714
|
throw new CLIError({
|
|
82251
82715
|
userMessage: `Phase 0 metrics not found at ${metricsPath}.`,
|
|
82252
82716
|
suggestion: "Verify the --phase0-path points to valid artifacts."
|
|
@@ -82284,7 +82748,7 @@ async function faqCluster(ctx, options) {
|
|
|
82284
82748
|
writeProductionArtifacts(result, outputPath);
|
|
82285
82749
|
if (!outputJson) {
|
|
82286
82750
|
ctx.output.data("\n\u2705 Production clustering complete!");
|
|
82287
|
-
ctx.output.data(` Artifacts written to: ${
|
|
82751
|
+
ctx.output.data(` Artifacts written to: ${join9(outputPath, version)}`);
|
|
82288
82752
|
}
|
|
82289
82753
|
} else {
|
|
82290
82754
|
if (!outputJson) ctx.output.data("\n\u{1F9EA} Dry run - no artifacts written");
|
|
@@ -82327,13 +82791,13 @@ function registerFaqClusterCommands(program3) {
|
|
|
82327
82791
|
|
|
82328
82792
|
// src/commands/faq/extract.ts
|
|
82329
82793
|
init_esm_shims();
|
|
82330
|
-
import { existsSync as
|
|
82331
|
-
import { join as
|
|
82794
|
+
import { existsSync as existsSync13 } from "fs";
|
|
82795
|
+
import { join as join11, resolve as resolve5 } from "path";
|
|
82332
82796
|
|
|
82333
82797
|
// ../core/src/faq/extractor.ts
|
|
82334
82798
|
init_esm_shims();
|
|
82335
|
-
import { existsSync as
|
|
82336
|
-
import { join as
|
|
82799
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
82800
|
+
import { join as join10 } from "path";
|
|
82337
82801
|
|
|
82338
82802
|
// ../core/src/faq/review.ts
|
|
82339
82803
|
init_esm_shims();
|
|
@@ -82715,12 +83179,12 @@ function deduplicateCandidates(candidates, threshold) {
|
|
|
82715
83179
|
};
|
|
82716
83180
|
}
|
|
82717
83181
|
function readClusteringResult(path) {
|
|
82718
|
-
const content =
|
|
83182
|
+
const content = readFileSync9(path, "utf-8");
|
|
82719
83183
|
return JSON.parse(content);
|
|
82720
83184
|
}
|
|
82721
83185
|
function readGoldenResponses(path) {
|
|
82722
83186
|
try {
|
|
82723
|
-
const content =
|
|
83187
|
+
const content = readFileSync9(path, "utf-8");
|
|
82724
83188
|
const parsed = JSON.parse(content);
|
|
82725
83189
|
return parsed.responses || parsed;
|
|
82726
83190
|
} catch {
|
|
@@ -82947,14 +83411,14 @@ async function extractFaqCandidates(options) {
|
|
|
82947
83411
|
return result;
|
|
82948
83412
|
}
|
|
82949
83413
|
function writeExtractionArtifacts(result, outputPath) {
|
|
82950
|
-
const versionPath =
|
|
82951
|
-
if (!
|
|
82952
|
-
|
|
83414
|
+
const versionPath = join10(outputPath, result.version);
|
|
83415
|
+
if (!existsSync12(versionPath)) {
|
|
83416
|
+
mkdirSync5(versionPath, { recursive: true });
|
|
82953
83417
|
}
|
|
82954
|
-
const resultPath =
|
|
82955
|
-
|
|
83418
|
+
const resultPath = join10(versionPath, "extraction-result.json");
|
|
83419
|
+
writeFileSync8(resultPath, JSON.stringify(result, null, 2));
|
|
82956
83420
|
console.log(`\u2705 Written: ${resultPath}`);
|
|
82957
|
-
const candidatesPath =
|
|
83421
|
+
const candidatesPath = join10(versionPath, "candidates.json");
|
|
82958
83422
|
const candidatesData = {
|
|
82959
83423
|
version: result.version,
|
|
82960
83424
|
extractedAt: result.extractedAt,
|
|
@@ -82972,10 +83436,10 @@ function writeExtractionArtifacts(result, outputPath) {
|
|
|
82972
83436
|
sourceConversations: c.sourceConversations.slice(0, 5)
|
|
82973
83437
|
}))
|
|
82974
83438
|
};
|
|
82975
|
-
|
|
83439
|
+
writeFileSync8(candidatesPath, JSON.stringify(candidatesData, null, 2));
|
|
82976
83440
|
console.log(`\u2705 Written: ${candidatesPath}`);
|
|
82977
|
-
const statsPath =
|
|
82978
|
-
|
|
83441
|
+
const statsPath = join10(versionPath, "stats.json");
|
|
83442
|
+
writeFileSync8(
|
|
82979
83443
|
statsPath,
|
|
82980
83444
|
JSON.stringify(
|
|
82981
83445
|
{
|
|
@@ -82988,21 +83452,21 @@ function writeExtractionArtifacts(result, outputPath) {
|
|
|
82988
83452
|
)
|
|
82989
83453
|
);
|
|
82990
83454
|
console.log(`\u2705 Written: ${statsPath}`);
|
|
82991
|
-
const latestPath =
|
|
82992
|
-
if (
|
|
83455
|
+
const latestPath = join10(outputPath, "latest");
|
|
83456
|
+
if (existsSync12(latestPath)) {
|
|
82993
83457
|
const { rmSync: rmSync2 } = __require("fs");
|
|
82994
83458
|
rmSync2(latestPath, { recursive: true, force: true });
|
|
82995
83459
|
}
|
|
82996
|
-
|
|
83460
|
+
mkdirSync5(latestPath, { recursive: true });
|
|
82997
83461
|
for (const file of [
|
|
82998
83462
|
"extraction-result.json",
|
|
82999
83463
|
"candidates.json",
|
|
83000
83464
|
"stats.json"
|
|
83001
83465
|
]) {
|
|
83002
|
-
const src =
|
|
83003
|
-
const dst =
|
|
83004
|
-
if (
|
|
83005
|
-
|
|
83466
|
+
const src = join10(versionPath, file);
|
|
83467
|
+
const dst = join10(latestPath, file);
|
|
83468
|
+
if (existsSync12(src)) {
|
|
83469
|
+
writeFileSync8(dst, readFileSync9(src));
|
|
83006
83470
|
}
|
|
83007
83471
|
}
|
|
83008
83472
|
console.log(`\u2705 Updated: ${latestPath}`);
|
|
@@ -83054,25 +83518,25 @@ ${i + 1}. [${confPct}%]${golden} ${candidate.suggestedCategory}`
|
|
|
83054
83518
|
}
|
|
83055
83519
|
|
|
83056
83520
|
// src/commands/faq/extract.ts
|
|
83057
|
-
var PROJECT_ROOT3 =
|
|
83058
|
-
var DEFAULT_CLUSTERING_PATH =
|
|
83521
|
+
var PROJECT_ROOT3 = resolve5(__dirname, "../../../..");
|
|
83522
|
+
var DEFAULT_CLUSTERING_PATH = join11(
|
|
83059
83523
|
PROJECT_ROOT3,
|
|
83060
83524
|
"artifacts/phase-1/clustering/v1/clustering-result.json"
|
|
83061
83525
|
);
|
|
83062
|
-
var DEFAULT_GOLDEN_PATH =
|
|
83526
|
+
var DEFAULT_GOLDEN_PATH = join11(
|
|
83063
83527
|
PROJECT_ROOT3,
|
|
83064
83528
|
"artifacts/phase-0/golden/latest/responses.json"
|
|
83065
83529
|
);
|
|
83066
|
-
var DEFAULT_OUTPUT_PATH3 =
|
|
83530
|
+
var DEFAULT_OUTPUT_PATH3 = join11(PROJECT_ROOT3, "artifacts/phase-1/extraction");
|
|
83067
83531
|
var DEFAULT_CACHE_PATH = `${process.env.HOME}/skill/data/front-cache.db`;
|
|
83068
83532
|
function validatePaths2(ctx, clusteringPath, goldenPath, outputJson) {
|
|
83069
|
-
if (!
|
|
83533
|
+
if (!existsSync13(clusteringPath)) {
|
|
83070
83534
|
throw new CLIError({
|
|
83071
83535
|
userMessage: `Clustering result not found at ${clusteringPath}.`,
|
|
83072
83536
|
suggestion: "Run `bun src/index.ts faq cluster` first to generate clustering."
|
|
83073
83537
|
});
|
|
83074
83538
|
}
|
|
83075
|
-
if (goldenPath && !
|
|
83539
|
+
if (goldenPath && !existsSync13(goldenPath)) {
|
|
83076
83540
|
if (!outputJson) {
|
|
83077
83541
|
ctx.output.warn(`Golden responses not found at ${goldenPath}`);
|
|
83078
83542
|
ctx.output.warn("Golden matching will be disabled.");
|
|
@@ -83101,7 +83565,7 @@ async function faqExtract(ctx, options) {
|
|
|
83101
83565
|
ctx.output.data("");
|
|
83102
83566
|
}
|
|
83103
83567
|
validatePaths2(ctx, clusteringPath, goldenPath, outputJson);
|
|
83104
|
-
if (!
|
|
83568
|
+
if (!existsSync13(cachePath)) {
|
|
83105
83569
|
const cliError = new CLIError({
|
|
83106
83570
|
userMessage: `DuckDB cache not found at ${cachePath}.`,
|
|
83107
83571
|
suggestion: "Run `bun src/index.ts front-cache sync` first to populate cache."
|
|
@@ -83123,7 +83587,7 @@ async function faqExtract(ctx, options) {
|
|
|
83123
83587
|
}
|
|
83124
83588
|
const extractionOptions = {
|
|
83125
83589
|
clusteringPath,
|
|
83126
|
-
goldenPath:
|
|
83590
|
+
goldenPath: existsSync13(goldenPath) ? goldenPath : void 0,
|
|
83127
83591
|
source,
|
|
83128
83592
|
outputPath,
|
|
83129
83593
|
version,
|
|
@@ -83168,7 +83632,7 @@ async function faqExtract(ctx, options) {
|
|
|
83168
83632
|
if (!options.dryRun) {
|
|
83169
83633
|
ctx.output.data(`
|
|
83170
83634
|
\u2705 Extraction complete!`);
|
|
83171
|
-
ctx.output.data(` Artifacts written to: ${
|
|
83635
|
+
ctx.output.data(` Artifacts written to: ${join11(outputPath, version)}`);
|
|
83172
83636
|
if (options.pushRedis && options.app) {
|
|
83173
83637
|
ctx.output.data(
|
|
83174
83638
|
` Candidates pushed to Redis queue: faq:pending:${options.app}`
|
|
@@ -83243,7 +83707,7 @@ function registerFaqExtractCommands(program3) {
|
|
|
83243
83707
|
|
|
83244
83708
|
// src/commands/faq/mine.ts
|
|
83245
83709
|
init_esm_shims();
|
|
83246
|
-
import { writeFileSync as
|
|
83710
|
+
import { writeFileSync as writeFileSync9 } from "fs";
|
|
83247
83711
|
|
|
83248
83712
|
// ../core/src/faq/index.ts
|
|
83249
83713
|
init_esm_shims();
|
|
@@ -83988,7 +84452,7 @@ function consumeBody() {
|
|
|
83988
84452
|
let accum = [];
|
|
83989
84453
|
let accumBytes = 0;
|
|
83990
84454
|
let abort = false;
|
|
83991
|
-
return new Body.Promise(function(
|
|
84455
|
+
return new Body.Promise(function(resolve9, reject) {
|
|
83992
84456
|
let resTimeout;
|
|
83993
84457
|
if (_this4.timeout) {
|
|
83994
84458
|
resTimeout = setTimeout(function() {
|
|
@@ -84022,7 +84486,7 @@ function consumeBody() {
|
|
|
84022
84486
|
}
|
|
84023
84487
|
clearTimeout(resTimeout);
|
|
84024
84488
|
try {
|
|
84025
|
-
|
|
84489
|
+
resolve9(Buffer.concat(accum, accumBytes));
|
|
84026
84490
|
} catch (err) {
|
|
84027
84491
|
reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
|
|
84028
84492
|
}
|
|
@@ -84697,7 +85161,7 @@ function fetch3(url, opts) {
|
|
|
84697
85161
|
throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
|
|
84698
85162
|
}
|
|
84699
85163
|
Body.Promise = fetch3.Promise;
|
|
84700
|
-
return new fetch3.Promise(function(
|
|
85164
|
+
return new fetch3.Promise(function(resolve9, reject) {
|
|
84701
85165
|
const request = new Request2(url, opts);
|
|
84702
85166
|
const options = getNodeRequestOptions(request);
|
|
84703
85167
|
const send = (options.protocol === "https:" ? https : http).request;
|
|
@@ -84830,7 +85294,7 @@ function fetch3(url, opts) {
|
|
|
84830
85294
|
requestOpts.body = void 0;
|
|
84831
85295
|
requestOpts.headers.delete("content-length");
|
|
84832
85296
|
}
|
|
84833
|
-
|
|
85297
|
+
resolve9(fetch3(new Request2(locationURL, requestOpts)));
|
|
84834
85298
|
finalize();
|
|
84835
85299
|
return;
|
|
84836
85300
|
}
|
|
@@ -84851,7 +85315,7 @@ function fetch3(url, opts) {
|
|
|
84851
85315
|
const codings = headers.get("Content-Encoding");
|
|
84852
85316
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
84853
85317
|
response = new Response2(body, response_options);
|
|
84854
|
-
|
|
85318
|
+
resolve9(response);
|
|
84855
85319
|
return;
|
|
84856
85320
|
}
|
|
84857
85321
|
const zlibOptions = {
|
|
@@ -84861,7 +85325,7 @@ function fetch3(url, opts) {
|
|
|
84861
85325
|
if (codings == "gzip" || codings == "x-gzip") {
|
|
84862
85326
|
body = body.pipe(zlib.createGunzip(zlibOptions));
|
|
84863
85327
|
response = new Response2(body, response_options);
|
|
84864
|
-
|
|
85328
|
+
resolve9(response);
|
|
84865
85329
|
return;
|
|
84866
85330
|
}
|
|
84867
85331
|
if (codings == "deflate" || codings == "x-deflate") {
|
|
@@ -84873,12 +85337,12 @@ function fetch3(url, opts) {
|
|
|
84873
85337
|
body = body.pipe(zlib.createInflateRaw());
|
|
84874
85338
|
}
|
|
84875
85339
|
response = new Response2(body, response_options);
|
|
84876
|
-
|
|
85340
|
+
resolve9(response);
|
|
84877
85341
|
});
|
|
84878
85342
|
raw.on("end", function() {
|
|
84879
85343
|
if (!response) {
|
|
84880
85344
|
response = new Response2(body, response_options);
|
|
84881
|
-
|
|
85345
|
+
resolve9(response);
|
|
84882
85346
|
}
|
|
84883
85347
|
});
|
|
84884
85348
|
return;
|
|
@@ -84886,11 +85350,11 @@ function fetch3(url, opts) {
|
|
|
84886
85350
|
if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
|
|
84887
85351
|
body = body.pipe(zlib.createBrotliDecompress());
|
|
84888
85352
|
response = new Response2(body, response_options);
|
|
84889
|
-
|
|
85353
|
+
resolve9(response);
|
|
84890
85354
|
return;
|
|
84891
85355
|
}
|
|
84892
85356
|
response = new Response2(body, response_options);
|
|
84893
|
-
|
|
85357
|
+
resolve9(response);
|
|
84894
85358
|
});
|
|
84895
85359
|
writeToStream(req, request);
|
|
84896
85360
|
});
|
|
@@ -85972,8 +86436,8 @@ function _addRequestID(value, response) {
|
|
|
85972
86436
|
}
|
|
85973
86437
|
var APIPromise = class _APIPromise extends Promise {
|
|
85974
86438
|
constructor(responsePromise, parseResponse2 = defaultParseResponse) {
|
|
85975
|
-
super((
|
|
85976
|
-
|
|
86439
|
+
super((resolve9) => {
|
|
86440
|
+
resolve9(null);
|
|
85977
86441
|
});
|
|
85978
86442
|
this.responsePromise = responsePromise;
|
|
85979
86443
|
this.parseResponse = parseResponse2;
|
|
@@ -86548,7 +87012,7 @@ var startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
86548
87012
|
var isAbsoluteURL = (url) => {
|
|
86549
87013
|
return startsWithSchemeRegexp.test(url);
|
|
86550
87014
|
};
|
|
86551
|
-
var sleep = (ms) => new Promise((
|
|
87015
|
+
var sleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
86552
87016
|
var validatePositiveInteger = (name, n) => {
|
|
86553
87017
|
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
86554
87018
|
throw new OpenAIError(`${name} must be an integer`);
|
|
@@ -87013,12 +87477,12 @@ var EventStream = class {
|
|
|
87013
87477
|
_EventStream_errored.set(this, false);
|
|
87014
87478
|
_EventStream_aborted.set(this, false);
|
|
87015
87479
|
_EventStream_catchingPromiseCreated.set(this, false);
|
|
87016
|
-
__classPrivateFieldSet4(this, _EventStream_connectedPromise, new Promise((
|
|
87017
|
-
__classPrivateFieldSet4(this, _EventStream_resolveConnectedPromise,
|
|
87480
|
+
__classPrivateFieldSet4(this, _EventStream_connectedPromise, new Promise((resolve9, reject) => {
|
|
87481
|
+
__classPrivateFieldSet4(this, _EventStream_resolveConnectedPromise, resolve9, "f");
|
|
87018
87482
|
__classPrivateFieldSet4(this, _EventStream_rejectConnectedPromise, reject, "f");
|
|
87019
87483
|
}), "f");
|
|
87020
|
-
__classPrivateFieldSet4(this, _EventStream_endPromise, new Promise((
|
|
87021
|
-
__classPrivateFieldSet4(this, _EventStream_resolveEndPromise,
|
|
87484
|
+
__classPrivateFieldSet4(this, _EventStream_endPromise, new Promise((resolve9, reject) => {
|
|
87485
|
+
__classPrivateFieldSet4(this, _EventStream_resolveEndPromise, resolve9, "f");
|
|
87022
87486
|
__classPrivateFieldSet4(this, _EventStream_rejectEndPromise, reject, "f");
|
|
87023
87487
|
}), "f");
|
|
87024
87488
|
__classPrivateFieldGet5(this, _EventStream_connectedPromise, "f").catch(() => {
|
|
@@ -87102,11 +87566,11 @@ var EventStream = class {
|
|
|
87102
87566
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
87103
87567
|
*/
|
|
87104
87568
|
emitted(event) {
|
|
87105
|
-
return new Promise((
|
|
87569
|
+
return new Promise((resolve9, reject) => {
|
|
87106
87570
|
__classPrivateFieldSet4(this, _EventStream_catchingPromiseCreated, true, "f");
|
|
87107
87571
|
if (event !== "error")
|
|
87108
87572
|
this.once("error", reject);
|
|
87109
|
-
this.once(event,
|
|
87573
|
+
this.once(event, resolve9);
|
|
87110
87574
|
});
|
|
87111
87575
|
}
|
|
87112
87576
|
async done() {
|
|
@@ -87259,7 +87723,7 @@ var AssistantStream = class _AssistantStream extends EventStream {
|
|
|
87259
87723
|
if (done) {
|
|
87260
87724
|
return { value: void 0, done: true };
|
|
87261
87725
|
}
|
|
87262
|
-
return new Promise((
|
|
87726
|
+
return new Promise((resolve9, reject) => readQueue.push({ resolve: resolve9, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
87263
87727
|
}
|
|
87264
87728
|
const chunk = pushQueue.shift();
|
|
87265
87729
|
return { value: chunk, done: false };
|
|
@@ -88899,7 +89363,7 @@ var ChatCompletionStream = class _ChatCompletionStream extends AbstractChatCompl
|
|
|
88899
89363
|
if (done) {
|
|
88900
89364
|
return { value: void 0, done: true };
|
|
88901
89365
|
}
|
|
88902
|
-
return new Promise((
|
|
89366
|
+
return new Promise((resolve9, reject) => readQueue.push({ resolve: resolve9, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
88903
89367
|
}
|
|
88904
89368
|
const chunk = pushQueue.shift();
|
|
88905
89369
|
return { value: chunk, done: false };
|
|
@@ -90609,7 +91073,7 @@ var ResponseStream = class _ResponseStream extends EventStream {
|
|
|
90609
91073
|
if (done) {
|
|
90610
91074
|
return { value: void 0, done: true };
|
|
90611
91075
|
}
|
|
90612
|
-
return new Promise((
|
|
91076
|
+
return new Promise((resolve9, reject) => readQueue.push({ resolve: resolve9, reject })).then((event2) => event2 ? { value: event2, done: false } : { value: void 0, done: true });
|
|
90613
91077
|
}
|
|
90614
91078
|
const event = pushQueue.shift();
|
|
90615
91079
|
return { value: event, done: false };
|
|
@@ -92060,7 +92524,7 @@ async function faqMine(ctx, options) {
|
|
|
92060
92524
|
}))
|
|
92061
92525
|
};
|
|
92062
92526
|
if (options.export) {
|
|
92063
|
-
|
|
92527
|
+
writeFileSync9(options.export, JSON.stringify(rawData, null, 2), "utf-8");
|
|
92064
92528
|
if (outputJson) {
|
|
92065
92529
|
ctx.output.data({
|
|
92066
92530
|
success: true,
|
|
@@ -92134,7 +92598,7 @@ async function faqMine(ctx, options) {
|
|
|
92134
92598
|
generatedAt: c.generatedAt.toISOString()
|
|
92135
92599
|
}))
|
|
92136
92600
|
};
|
|
92137
|
-
|
|
92601
|
+
writeFileSync9(
|
|
92138
92602
|
options.export,
|
|
92139
92603
|
JSON.stringify(exportData, null, 2),
|
|
92140
92604
|
"utf-8"
|
|
@@ -92197,9 +92661,9 @@ function registerFaqMineCommands(program3) {
|
|
|
92197
92661
|
// src/commands/faq/review.ts
|
|
92198
92662
|
init_esm_shims();
|
|
92199
92663
|
import { spawnSync } from "child_process";
|
|
92200
|
-
import { existsSync as
|
|
92664
|
+
import { existsSync as existsSync14, readFileSync as readFileSync10, unlinkSync, writeFileSync as writeFileSync10 } from "fs";
|
|
92201
92665
|
import { tmpdir } from "os";
|
|
92202
|
-
import { join as
|
|
92666
|
+
import { join as join12 } from "path";
|
|
92203
92667
|
import { confirm as confirm2, select as select2 } from "@inquirer/prompts";
|
|
92204
92668
|
var COLORS2 = {
|
|
92205
92669
|
reset: "\x1B[0m",
|
|
@@ -92260,7 +92724,7 @@ function getEditor() {
|
|
|
92260
92724
|
}
|
|
92261
92725
|
function editInEditor(ctx, question, answer) {
|
|
92262
92726
|
const editor = getEditor();
|
|
92263
|
-
const tmpFile =
|
|
92727
|
+
const tmpFile = join12(tmpdir(), `faq-edit-${Date.now()}.md`);
|
|
92264
92728
|
const content = `# FAQ Edit
|
|
92265
92729
|
|
|
92266
92730
|
## Question
|
|
@@ -92275,7 +92739,7 @@ Save and close the editor when done.
|
|
|
92275
92739
|
The sections are separated by "## Question" and "## Answer" headers.
|
|
92276
92740
|
-->
|
|
92277
92741
|
`;
|
|
92278
|
-
|
|
92742
|
+
writeFileSync10(tmpFile, content, "utf-8");
|
|
92279
92743
|
try {
|
|
92280
92744
|
const result = spawnSync(editor, [tmpFile], {
|
|
92281
92745
|
stdio: "inherit",
|
|
@@ -92285,7 +92749,7 @@ The sections are separated by "## Question" and "## Answer" headers.
|
|
|
92285
92749
|
ctx.output.warn(`${COLORS2.red}Editor exited with error${COLORS2.reset}`);
|
|
92286
92750
|
return null;
|
|
92287
92751
|
}
|
|
92288
|
-
const edited =
|
|
92752
|
+
const edited = readFileSync10(tmpFile, "utf-8");
|
|
92289
92753
|
const questionMatch = edited.match(
|
|
92290
92754
|
/## Question\s*\n([\s\S]*?)(?=\n## Answer|$)/
|
|
92291
92755
|
);
|
|
@@ -92303,7 +92767,7 @@ The sections are separated by "## Question" and "## Answer" headers.
|
|
|
92303
92767
|
answer: editedAnswer
|
|
92304
92768
|
};
|
|
92305
92769
|
} finally {
|
|
92306
|
-
if (
|
|
92770
|
+
if (existsSync14(tmpFile)) {
|
|
92307
92771
|
unlinkSync(tmpFile);
|
|
92308
92772
|
}
|
|
92309
92773
|
}
|
|
@@ -92824,8 +93288,8 @@ var FrontRateLimiter = class {
|
|
|
92824
93288
|
)
|
|
92825
93289
|
);
|
|
92826
93290
|
}
|
|
92827
|
-
return new Promise((
|
|
92828
|
-
const item = { resolve:
|
|
93291
|
+
return new Promise((resolve9, reject) => {
|
|
93292
|
+
const item = { resolve: resolve9, reject, signal };
|
|
92829
93293
|
if (signal) {
|
|
92830
93294
|
const onAbort = () => {
|
|
92831
93295
|
this.removeFromQueue(item);
|
|
@@ -92886,9 +93350,9 @@ var FrontRateLimiter = class {
|
|
|
92886
93350
|
return 0;
|
|
92887
93351
|
}
|
|
92888
93352
|
sleep(ms, signal) {
|
|
92889
|
-
return new Promise((
|
|
93353
|
+
return new Promise((resolve9, reject) => {
|
|
92890
93354
|
if (ms <= 0) {
|
|
92891
|
-
|
|
93355
|
+
resolve9();
|
|
92892
93356
|
return;
|
|
92893
93357
|
}
|
|
92894
93358
|
let settled = false;
|
|
@@ -92896,7 +93360,7 @@ var FrontRateLimiter = class {
|
|
|
92896
93360
|
if (settled) return;
|
|
92897
93361
|
settled = true;
|
|
92898
93362
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
92899
|
-
|
|
93363
|
+
resolve9();
|
|
92900
93364
|
};
|
|
92901
93365
|
const onAbort = () => {
|
|
92902
93366
|
if (settled) return;
|
|
@@ -94498,7 +94962,7 @@ function registerInboxCommand(front) {
|
|
|
94498
94962
|
|
|
94499
94963
|
// src/commands/front/pull-conversations.ts
|
|
94500
94964
|
init_esm_shims();
|
|
94501
|
-
import { writeFileSync as
|
|
94965
|
+
import { writeFileSync as writeFileSync11 } from "fs";
|
|
94502
94966
|
async function pullConversations(ctx, options) {
|
|
94503
94967
|
const { inbox, limit: limit2 = 50, output, filter: filter4 } = options;
|
|
94504
94968
|
const outputJson = options.json === true || ctx.format === "json";
|
|
@@ -94631,7 +95095,7 @@ Built ${samples.length} eval samples`);
|
|
|
94631
95095
|
ctx.output.data(` ${cat}: ${count}`);
|
|
94632
95096
|
}
|
|
94633
95097
|
if (output) {
|
|
94634
|
-
|
|
95098
|
+
writeFileSync11(output, JSON.stringify(samples, null, 2));
|
|
94635
95099
|
ctx.output.data(`
|
|
94636
95100
|
Saved to ${output}`);
|
|
94637
95101
|
} else if (outputJson) {
|
|
@@ -95001,7 +95465,7 @@ function truncate2(str2, len) {
|
|
|
95001
95465
|
return str2.slice(0, len - 3) + "...";
|
|
95002
95466
|
}
|
|
95003
95467
|
function sleep2(ms) {
|
|
95004
|
-
return new Promise((
|
|
95468
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
95005
95469
|
}
|
|
95006
95470
|
async function getConversationCount(front, tagId) {
|
|
95007
95471
|
try {
|
|
@@ -96486,10 +96950,10 @@ async function promptForName(ctx) {
|
|
|
96486
96950
|
input: ctx.stdin,
|
|
96487
96951
|
output: ctx.stdout
|
|
96488
96952
|
});
|
|
96489
|
-
return new Promise((
|
|
96953
|
+
return new Promise((resolve9) => {
|
|
96490
96954
|
rl.question("App name: ", (answer) => {
|
|
96491
96955
|
rl.close();
|
|
96492
|
-
|
|
96956
|
+
resolve9(answer.trim() || "my-app");
|
|
96493
96957
|
});
|
|
96494
96958
|
});
|
|
96495
96959
|
}
|
|
@@ -97349,7 +97813,7 @@ function registerRunsCommands(inngest) {
|
|
|
97349
97813
|
|
|
97350
97814
|
// src/commands/inngest/signal.ts
|
|
97351
97815
|
init_esm_shims();
|
|
97352
|
-
import { readFileSync as
|
|
97816
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
97353
97817
|
import "commander";
|
|
97354
97818
|
async function signalCommand(ctx, signal, options) {
|
|
97355
97819
|
const { data: dataString, dataFile, dev = false } = options;
|
|
@@ -97357,7 +97821,7 @@ async function signalCommand(ctx, signal, options) {
|
|
|
97357
97821
|
let data2 = null;
|
|
97358
97822
|
if (dataFile) {
|
|
97359
97823
|
try {
|
|
97360
|
-
const fileContent =
|
|
97824
|
+
const fileContent = readFileSync11(dataFile, "utf-8");
|
|
97361
97825
|
data2 = JSON.parse(fileContent);
|
|
97362
97826
|
} catch (err) {
|
|
97363
97827
|
const cliError = new CLIError({
|
|
@@ -113472,6 +113936,21 @@ init_esm_shims();
|
|
|
113472
113936
|
// src/commands/linear/assign.ts
|
|
113473
113937
|
init_esm_shims();
|
|
113474
113938
|
|
|
113939
|
+
// src/core/write-gate.ts
|
|
113940
|
+
init_esm_shims();
|
|
113941
|
+
function requirePersonalKey(keyName) {
|
|
113942
|
+
const provenance = getKeyProvenance(keyName);
|
|
113943
|
+
if (provenance === "user") {
|
|
113944
|
+
return;
|
|
113945
|
+
}
|
|
113946
|
+
throw new CLIError({
|
|
113947
|
+
userMessage: `Write operations require a personal API key for ${keyName}.`,
|
|
113948
|
+
exitCode: EXIT_CODES.auth,
|
|
113949
|
+
suggestion: "Run 'skill config init' to set up your personal keys.",
|
|
113950
|
+
debugMessage: `Key provenance for ${keyName}: ${provenance ?? "undefined"}`
|
|
113951
|
+
});
|
|
113952
|
+
}
|
|
113953
|
+
|
|
113475
113954
|
// src/commands/linear/client.ts
|
|
113476
113955
|
init_esm_shims();
|
|
113477
113956
|
import { LinearClient } from "@linear/sdk";
|
|
@@ -113490,14 +113969,22 @@ function getLinearClient() {
|
|
|
113490
113969
|
// src/commands/linear/hateoas.ts
|
|
113491
113970
|
init_esm_shims();
|
|
113492
113971
|
function hateoasWrap2(opts) {
|
|
113493
|
-
|
|
113972
|
+
const response = {
|
|
113494
113973
|
_type: opts.type,
|
|
113495
113974
|
_command: opts.command,
|
|
113496
113975
|
data: opts.data,
|
|
113497
113976
|
_links: opts.links ?? [],
|
|
113498
113977
|
_actions: opts.actions ?? []
|
|
113499
113978
|
};
|
|
113979
|
+
if (opts.meta) {
|
|
113980
|
+
response._meta = opts.meta;
|
|
113981
|
+
}
|
|
113982
|
+
return response;
|
|
113500
113983
|
}
|
|
113984
|
+
var WRITE_ACTION_META = {
|
|
113985
|
+
personal_key_hint: "\u26A0\uFE0F Write operations require a personal LINEAR_API_KEY. Run `skill config init` to set up your keys.",
|
|
113986
|
+
setup_command: "skill config init"
|
|
113987
|
+
};
|
|
113501
113988
|
function issueLinks(identifier, teamKey) {
|
|
113502
113989
|
const links = [
|
|
113503
113990
|
{
|
|
@@ -113525,43 +114012,51 @@ function issueActions(identifier) {
|
|
|
113525
114012
|
{
|
|
113526
114013
|
action: "comment",
|
|
113527
114014
|
command: `skill linear comment ${identifier} --body "<text>"`,
|
|
113528
|
-
description: "Add a comment"
|
|
114015
|
+
description: "Add a comment",
|
|
114016
|
+
requires_personal_key: true
|
|
113529
114017
|
},
|
|
113530
114018
|
{
|
|
113531
114019
|
action: "assign",
|
|
113532
114020
|
command: `skill linear assign ${identifier} --to <user-email>`,
|
|
113533
|
-
description: "Assign this issue"
|
|
114021
|
+
description: "Assign this issue",
|
|
114022
|
+
requires_personal_key: true
|
|
113534
114023
|
},
|
|
113535
114024
|
{
|
|
113536
114025
|
action: "unassign",
|
|
113537
114026
|
command: `skill linear assign ${identifier} --unassign`,
|
|
113538
|
-
description: "Unassign this issue"
|
|
114027
|
+
description: "Unassign this issue",
|
|
114028
|
+
requires_personal_key: true
|
|
113539
114029
|
},
|
|
113540
114030
|
{
|
|
113541
114031
|
action: "update-state",
|
|
113542
114032
|
command: `skill linear state ${identifier} --state "<state-name>"`,
|
|
113543
|
-
description: "Change workflow state"
|
|
114033
|
+
description: "Change workflow state",
|
|
114034
|
+
requires_personal_key: true
|
|
113544
114035
|
},
|
|
113545
114036
|
{
|
|
113546
114037
|
action: "update-priority",
|
|
113547
114038
|
command: `skill linear update ${identifier} --priority <0-4>`,
|
|
113548
|
-
description: "Change priority (0=urgent, 4=none)"
|
|
114039
|
+
description: "Change priority (0=urgent, 4=none)",
|
|
114040
|
+
requires_personal_key: true
|
|
113549
114041
|
},
|
|
113550
114042
|
{
|
|
113551
114043
|
action: "add-label",
|
|
113552
114044
|
command: `skill linear label ${identifier} --add "<label-name>"`,
|
|
113553
|
-
description: "Add a label"
|
|
114045
|
+
description: "Add a label",
|
|
114046
|
+
requires_personal_key: true
|
|
113554
114047
|
},
|
|
113555
114048
|
{
|
|
113556
114049
|
action: "close",
|
|
113557
114050
|
command: `skill linear close ${identifier}`,
|
|
113558
114051
|
description: "Close this issue",
|
|
113559
|
-
destructive: true
|
|
114052
|
+
destructive: true,
|
|
114053
|
+
requires_personal_key: true
|
|
113560
114054
|
},
|
|
113561
114055
|
{
|
|
113562
114056
|
action: "link",
|
|
113563
114057
|
command: `skill linear link ${identifier} --blocks <other-id>`,
|
|
113564
|
-
description: "Link to another issue"
|
|
114058
|
+
description: "Link to another issue",
|
|
114059
|
+
requires_personal_key: true
|
|
113565
114060
|
}
|
|
113566
114061
|
];
|
|
113567
114062
|
}
|
|
@@ -113585,7 +114080,8 @@ function issueListActions(teamKey) {
|
|
|
113585
114080
|
{
|
|
113586
114081
|
action: "create",
|
|
113587
114082
|
command: `skill linear create "<title>"${teamKey ? ` --team ${teamKey}` : ""}`,
|
|
113588
|
-
description: "Create a new issue"
|
|
114083
|
+
description: "Create a new issue",
|
|
114084
|
+
requires_personal_key: true
|
|
113589
114085
|
},
|
|
113590
114086
|
{
|
|
113591
114087
|
action: "search",
|
|
@@ -113674,6 +114170,7 @@ async function assignIssue(ctx, issueId, options) {
|
|
|
113674
114170
|
exitCode: 1
|
|
113675
114171
|
});
|
|
113676
114172
|
}
|
|
114173
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
113677
114174
|
try {
|
|
113678
114175
|
const client = getLinearClient();
|
|
113679
114176
|
const issue = await client.issue(issueId);
|
|
@@ -113757,6 +114254,7 @@ async function assignIssue(ctx, issueId, options) {
|
|
|
113757
114254
|
// src/commands/linear/close.ts
|
|
113758
114255
|
init_esm_shims();
|
|
113759
114256
|
async function closeIssue(ctx, issueId, options = {}) {
|
|
114257
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
113760
114258
|
try {
|
|
113761
114259
|
const client = getLinearClient();
|
|
113762
114260
|
const issue = await client.issue(issueId);
|
|
@@ -113844,6 +114342,7 @@ async function addComment(ctx, issueId, options) {
|
|
|
113844
114342
|
exitCode: 1
|
|
113845
114343
|
});
|
|
113846
114344
|
}
|
|
114345
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
113847
114346
|
try {
|
|
113848
114347
|
const client = getLinearClient();
|
|
113849
114348
|
const issue = await client.issue(issueId);
|
|
@@ -114033,6 +114532,7 @@ async function createIssue(ctx, title, options = {}) {
|
|
|
114033
114532
|
exitCode: 1
|
|
114034
114533
|
});
|
|
114035
114534
|
}
|
|
114535
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
114036
114536
|
try {
|
|
114037
114537
|
const client = getLinearClient();
|
|
114038
114538
|
let teamId;
|
|
@@ -114263,7 +114763,8 @@ async function getIssue(ctx, id) {
|
|
|
114263
114763
|
command: `skill linear issue ${issue.identifier} --json`,
|
|
114264
114764
|
data: issueData,
|
|
114265
114765
|
links: issueLinks(issue.identifier, teamKey),
|
|
114266
|
-
actions: issueActions(issue.identifier)
|
|
114766
|
+
actions: issueActions(issue.identifier),
|
|
114767
|
+
meta: WRITE_ACTION_META
|
|
114267
114768
|
}),
|
|
114268
114769
|
null,
|
|
114269
114770
|
2
|
|
@@ -114330,7 +114831,7 @@ async function getIssue(ctx, id) {
|
|
|
114330
114831
|
}
|
|
114331
114832
|
}
|
|
114332
114833
|
ctx.output.data("");
|
|
114333
|
-
ctx.output.data(" Actions:");
|
|
114834
|
+
ctx.output.data(" Actions (require personal API key):");
|
|
114334
114835
|
ctx.output.data(
|
|
114335
114836
|
` \u2022 Comment: skill linear comment ${issue.identifier} --body "text"`
|
|
114336
114837
|
);
|
|
@@ -114342,6 +114843,9 @@ async function getIssue(ctx, id) {
|
|
|
114342
114843
|
);
|
|
114343
114844
|
ctx.output.data(` \u2022 Close: skill linear close ${issue.identifier}`);
|
|
114344
114845
|
ctx.output.data("");
|
|
114846
|
+
ctx.output.data(" \u26A0\uFE0F Write operations require a personal LINEAR_API_KEY.");
|
|
114847
|
+
ctx.output.data(" Run `skill config init` to set up your keys.");
|
|
114848
|
+
ctx.output.data("");
|
|
114345
114849
|
} catch (error) {
|
|
114346
114850
|
const cliError = error instanceof CLIError ? error : new CLIError({
|
|
114347
114851
|
userMessage: "Failed to fetch Linear issue.",
|
|
@@ -114365,6 +114869,7 @@ async function modifyLabels(ctx, issueId, options) {
|
|
|
114365
114869
|
exitCode: 1
|
|
114366
114870
|
});
|
|
114367
114871
|
}
|
|
114872
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
114368
114873
|
try {
|
|
114369
114874
|
const client = getLinearClient();
|
|
114370
114875
|
const issue = await client.issue(issueId);
|
|
@@ -114612,6 +115117,7 @@ async function linkIssues(ctx, issueId, options) {
|
|
|
114612
115117
|
}
|
|
114613
115118
|
const relationship = relationships[0];
|
|
114614
115119
|
const targetValue = relationship.value;
|
|
115120
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
114615
115121
|
try {
|
|
114616
115122
|
const client = getLinearClient();
|
|
114617
115123
|
const [issue, targetIssue] = await Promise.all([
|
|
@@ -114820,7 +115326,8 @@ async function listIssues(ctx, options = {}) {
|
|
|
114820
115326
|
})),
|
|
114821
115327
|
teamKey
|
|
114822
115328
|
),
|
|
114823
|
-
actions: issueListActions(teamKey)
|
|
115329
|
+
actions: issueListActions(teamKey),
|
|
115330
|
+
meta: WRITE_ACTION_META
|
|
114824
115331
|
}),
|
|
114825
115332
|
null,
|
|
114826
115333
|
2
|
|
@@ -115184,6 +115691,7 @@ async function changeState(ctx, issueId, options) {
|
|
|
115184
115691
|
exitCode: 1
|
|
115185
115692
|
});
|
|
115186
115693
|
}
|
|
115694
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
115187
115695
|
try {
|
|
115188
115696
|
const client = getLinearClient();
|
|
115189
115697
|
const issue = await client.issue(issueId);
|
|
@@ -115434,6 +115942,7 @@ async function updateIssue(ctx, issueId, options) {
|
|
|
115434
115942
|
exitCode: 1
|
|
115435
115943
|
});
|
|
115436
115944
|
}
|
|
115945
|
+
requirePersonalKey("LINEAR_API_KEY");
|
|
115437
115946
|
try {
|
|
115438
115947
|
const client = getLinearClient();
|
|
115439
115948
|
const issue = await client.issue(issueId);
|
|
@@ -116264,7 +116773,7 @@ async function deleteMemory(ctx, id, options) {
|
|
|
116264
116773
|
}
|
|
116265
116774
|
|
|
116266
116775
|
// src/commands/memory/index.ts
|
|
116267
|
-
var
|
|
116776
|
+
var buildContext4 = async (command, json) => {
|
|
116268
116777
|
const opts = typeof command.optsWithGlobals === "function" ? command.optsWithGlobals() : {
|
|
116269
116778
|
...command.parent?.opts(),
|
|
116270
116779
|
...command.opts()
|
|
@@ -116278,42 +116787,42 @@ var buildContext3 = async (command, json) => {
|
|
|
116278
116787
|
function registerMemoryCommands(program3) {
|
|
116279
116788
|
const memory = program3.command("memory").description("Manage semantic memory for agent learning");
|
|
116280
116789
|
memory.command("store").description("Store a new memory").argument("<content>", "Memory content to store").option("--tags <tags>", "Comma-separated tags").option("--collection <collection>", "Collection name (default: learnings)").option("--app <app>", "App slug to associate with memory").option("--json", "Output as JSON").action(async (content, options, command) => {
|
|
116281
|
-
const ctx = await
|
|
116790
|
+
const ctx = await buildContext4(command, options.json);
|
|
116282
116791
|
await store(ctx, content, options);
|
|
116283
116792
|
});
|
|
116284
116793
|
memory.command("find").description("Search memories by semantic similarity").argument("<query>", "Search query text").option("--limit <number>", "Max results (1-100, default: 10)").option("--collection <collection>", "Collection name (default: learnings)").option("--app <app>", "Filter by app slug").option(
|
|
116285
116794
|
"--min-confidence <confidence>",
|
|
116286
116795
|
"Minimum confidence threshold (0-1, default: 0.5)"
|
|
116287
116796
|
).option("--json", "Output as JSON").action(async (query, options, command) => {
|
|
116288
|
-
const ctx = await
|
|
116797
|
+
const ctx = await buildContext4(command, options.json);
|
|
116289
116798
|
await find5(ctx, query, options);
|
|
116290
116799
|
});
|
|
116291
116800
|
memory.command("get").description("Get a specific memory by ID").argument("<id>", "Memory ID").option("--collection <collection>", "Collection name (default: learnings)").option("--json", "Output as JSON").action(async (id, options, command) => {
|
|
116292
|
-
const ctx = await
|
|
116801
|
+
const ctx = await buildContext4(command, options.json);
|
|
116293
116802
|
await get2(ctx, id, options);
|
|
116294
116803
|
});
|
|
116295
116804
|
memory.command("validate").description("Validate a memory (resets decay clock)").argument("<id>", "Memory ID").option("--collection <collection>", "Collection name (default: learnings)").option("--json", "Output as JSON").action(async (id, options, command) => {
|
|
116296
|
-
const ctx = await
|
|
116805
|
+
const ctx = await buildContext4(command, options.json);
|
|
116297
116806
|
await validate2(ctx, id, options);
|
|
116298
116807
|
});
|
|
116299
116808
|
memory.command("upvote").description("Upvote a memory").argument("<id>", "Memory ID").option("--collection <collection>", "Collection name (default: learnings)").option("--reason <reason>", "Optional reason for upvote").option("--json", "Output as JSON").action(async (id, options, command) => {
|
|
116300
|
-
const ctx = await
|
|
116809
|
+
const ctx = await buildContext4(command, options.json);
|
|
116301
116810
|
await upvote(ctx, id, options);
|
|
116302
116811
|
});
|
|
116303
116812
|
memory.command("downvote").description("Downvote a memory").argument("<id>", "Memory ID").option("--collection <collection>", "Collection name (default: learnings)").option("--reason <reason>", "Optional reason for downvote").option("--json", "Output as JSON").action(async (id, options, command) => {
|
|
116304
|
-
const ctx = await
|
|
116813
|
+
const ctx = await buildContext4(command, options.json);
|
|
116305
116814
|
await downvote(ctx, id, options);
|
|
116306
116815
|
});
|
|
116307
116816
|
memory.command("delete").description("Delete a memory").argument("<id>", "Memory ID").option("--collection <collection>", "Collection name (default: learnings)").option("--json", "Output as JSON").action(async (id, options, command) => {
|
|
116308
|
-
const ctx = await
|
|
116817
|
+
const ctx = await buildContext4(command, options.json);
|
|
116309
116818
|
await deleteMemory(ctx, id, options);
|
|
116310
116819
|
});
|
|
116311
116820
|
memory.command("stats").description("Display memory statistics").option("--collection <collection>", "Filter by collection").option("--app <app>", "Filter by app slug").option("--json", "Output as JSON").action(async (options, command) => {
|
|
116312
|
-
const ctx = await
|
|
116821
|
+
const ctx = await buildContext4(command, options.json);
|
|
116313
116822
|
await stats3(ctx, options);
|
|
116314
116823
|
});
|
|
116315
116824
|
memory.command("stale").description("List stale memories needing validation").option("--collection <collection>", "Filter by collection").option("--threshold <threshold>", "Confidence threshold (default: 0.25)").option("--json", "Output as JSON").action(async (options, command) => {
|
|
116316
|
-
const ctx = await
|
|
116825
|
+
const ctx = await buildContext4(command, options.json);
|
|
116317
116826
|
await stale(ctx, options);
|
|
116318
116827
|
});
|
|
116319
116828
|
}
|
|
@@ -116323,10 +116832,10 @@ init_esm_shims();
|
|
|
116323
116832
|
|
|
116324
116833
|
// ../core/src/pipeline/evals/classify.eval.ts
|
|
116325
116834
|
init_esm_shims();
|
|
116326
|
-
import { readFile as
|
|
116835
|
+
import { readFile as readFile7, writeFile as writeFile4 } from "fs/promises";
|
|
116327
116836
|
async function runClassifyEval2(options) {
|
|
116328
116837
|
const { dataset, output, verbose, json, forceLLM, model } = options;
|
|
116329
|
-
const datasetContent = await
|
|
116838
|
+
const datasetContent = await readFile7(dataset, "utf-8");
|
|
116330
116839
|
const scenarios = JSON.parse(datasetContent);
|
|
116331
116840
|
if (!json) {
|
|
116332
116841
|
console.log(`
|
|
@@ -116427,7 +116936,7 @@ Latency: ${(totalDuration / results.length).toFixed(0)}ms avg`
|
|
|
116427
116936
|
return summary;
|
|
116428
116937
|
}
|
|
116429
116938
|
async function buildClassifyDataset(productionDataPath, outputPath) {
|
|
116430
|
-
const content = await
|
|
116939
|
+
const content = await readFile7(productionDataPath, "utf-8");
|
|
116431
116940
|
const production = JSON.parse(content);
|
|
116432
116941
|
const categoryMap = {
|
|
116433
116942
|
"tool-assisted": "support_access",
|
|
@@ -116468,7 +116977,7 @@ async function buildClassifyDataset(productionDataPath, outputPath) {
|
|
|
116468
116977
|
|
|
116469
116978
|
// ../core/src/pipeline/evals/e2e.eval.ts
|
|
116470
116979
|
init_esm_shims();
|
|
116471
|
-
import { readFile as
|
|
116980
|
+
import { readFile as readFile8, writeFile as writeFile5 } from "fs/promises";
|
|
116472
116981
|
async function runE2EEval2(options) {
|
|
116473
116982
|
const {
|
|
116474
116983
|
dataset,
|
|
@@ -116478,7 +116987,7 @@ async function runE2EEval2(options) {
|
|
|
116478
116987
|
limit: limit2,
|
|
116479
116988
|
model = "anthropic/claude-haiku-4-5"
|
|
116480
116989
|
} = options;
|
|
116481
|
-
const content = await
|
|
116990
|
+
const content = await readFile8(dataset, "utf-8");
|
|
116482
116991
|
let scenarios = JSON.parse(content);
|
|
116483
116992
|
if (limit2) {
|
|
116484
116993
|
scenarios = scenarios.slice(0, limit2);
|
|
@@ -116633,7 +117142,7 @@ async function runE2EEval2(options) {
|
|
|
116633
117142
|
|
|
116634
117143
|
// ../core/src/pipeline/evals/validate.eval.ts
|
|
116635
117144
|
init_esm_shims();
|
|
116636
|
-
import { readFile as
|
|
117145
|
+
import { readFile as readFile9, writeFile as writeFile6 } from "fs/promises";
|
|
116637
117146
|
var BUILT_IN_SCENARIOS = [
|
|
116638
117147
|
// Internal leaks
|
|
116639
117148
|
{
|
|
@@ -116765,7 +117274,7 @@ async function runValidateEval2(options) {
|
|
|
116765
117274
|
const { dataset, output, verbose, json } = options;
|
|
116766
117275
|
let scenarios;
|
|
116767
117276
|
if (dataset) {
|
|
116768
|
-
const content = await
|
|
117277
|
+
const content = await readFile9(dataset, "utf-8");
|
|
116769
117278
|
scenarios = JSON.parse(content);
|
|
116770
117279
|
} else {
|
|
116771
117280
|
scenarios = BUILT_IN_SCENARIOS;
|
|
@@ -116872,7 +117381,7 @@ Latency: ${(totalDuration / results.length).toFixed(2)}ms avg`
|
|
|
116872
117381
|
return summary;
|
|
116873
117382
|
}
|
|
116874
117383
|
async function buildValidateDatasetFromProduction(productionResultsPath, outputPath) {
|
|
116875
|
-
const content = await
|
|
117384
|
+
const content = await readFile9(productionResultsPath, "utf-8");
|
|
116876
117385
|
const production = JSON.parse(content);
|
|
116877
117386
|
const scenarios = production.results.filter((r) => !r.passed && r.productionResponse).map((r, i) => ({
|
|
116878
117387
|
id: `prod-fail-${i}`,
|
|
@@ -116895,7 +117404,7 @@ async function buildValidateDatasetFromProduction(productionResultsPath, outputP
|
|
|
116895
117404
|
}
|
|
116896
117405
|
|
|
116897
117406
|
// src/commands/pipeline.ts
|
|
116898
|
-
var
|
|
117407
|
+
var buildContext5 = async (command, json) => {
|
|
116899
117408
|
const opts = typeof command.optsWithGlobals === "function" ? command.optsWithGlobals() : {
|
|
116900
117409
|
...command.parent?.opts(),
|
|
116901
117410
|
...command.opts()
|
|
@@ -116966,7 +117475,7 @@ function registerPipelineCommands(program3) {
|
|
|
116966
117475
|
"Model for LLM classification",
|
|
116967
117476
|
"anthropic/claude-haiku-4-5"
|
|
116968
117477
|
).action(async (opts, command) => {
|
|
116969
|
-
const ctx = await
|
|
117478
|
+
const ctx = await buildContext5(command, opts.json);
|
|
116970
117479
|
try {
|
|
116971
117480
|
await runClassifyEval2({
|
|
116972
117481
|
...opts,
|
|
@@ -116977,7 +117486,7 @@ function registerPipelineCommands(program3) {
|
|
|
116977
117486
|
}
|
|
116978
117487
|
});
|
|
116979
117488
|
pipeline.command("build-classify-dataset").description("Build classify eval dataset from production data").requiredOption("--production <file>", "Production dataset JSON").requiredOption("--output <file>", "Output scenarios JSON").action(async (opts, command) => {
|
|
116980
|
-
const ctx = await
|
|
117489
|
+
const ctx = await buildContext5(command);
|
|
116981
117490
|
try {
|
|
116982
117491
|
await buildClassifyDataset(opts.production, opts.output);
|
|
116983
117492
|
ctx.output.success(`Dataset written to ${opts.output}`);
|
|
@@ -116989,7 +117498,7 @@ function registerPipelineCommands(program3) {
|
|
|
116989
117498
|
"--dataset <file>",
|
|
116990
117499
|
"Path to scenarios JSON (uses built-in if not provided)"
|
|
116991
117500
|
).option("--output <file>", "Save results to JSON").option("--verbose", "Show individual failures").option("--json", "JSON output").action(async (opts, command) => {
|
|
116992
|
-
const ctx = await
|
|
117501
|
+
const ctx = await buildContext5(command, opts.json);
|
|
116993
117502
|
try {
|
|
116994
117503
|
await runValidateEval2({
|
|
116995
117504
|
...opts,
|
|
@@ -117000,7 +117509,7 @@ function registerPipelineCommands(program3) {
|
|
|
117000
117509
|
}
|
|
117001
117510
|
});
|
|
117002
117511
|
pipeline.command("build-validate-dataset").description("Build validate eval dataset from production failures").requiredOption("--production <file>", "Production baseline results JSON").requiredOption("--output <file>", "Output scenarios JSON").action(async (opts, command) => {
|
|
117003
|
-
const ctx = await
|
|
117512
|
+
const ctx = await buildContext5(command);
|
|
117004
117513
|
try {
|
|
117005
117514
|
await buildValidateDatasetFromProduction(opts.production, opts.output);
|
|
117006
117515
|
ctx.output.success(`Dataset written to ${opts.output}`);
|
|
@@ -117013,7 +117522,7 @@ function registerPipelineCommands(program3) {
|
|
|
117013
117522
|
"Model for LLM steps",
|
|
117014
117523
|
"anthropic/claude-haiku-4-5"
|
|
117015
117524
|
).action(async (opts, command) => {
|
|
117016
|
-
const ctx = await
|
|
117525
|
+
const ctx = await buildContext5(command, opts.json);
|
|
117017
117526
|
try {
|
|
117018
117527
|
await runE2EEval2({ ...opts, json: opts.json ?? ctx.format === "json" });
|
|
117019
117528
|
} catch (error) {
|
|
@@ -117021,44 +117530,24 @@ function registerPipelineCommands(program3) {
|
|
|
117021
117530
|
}
|
|
117022
117531
|
});
|
|
117023
117532
|
pipeline.command("run").description("Run pipeline on a single message").requiredOption("--subject <text>", "Message subject").requiredOption("--body <text>", "Message body").option("--app <id>", "App ID", "total-typescript").option("--dry-run", "Don't actually send", true).option("--json", "JSON output").action(async (opts, command) => {
|
|
117024
|
-
const ctx = await
|
|
117533
|
+
const ctx = await buildContext5(command, opts.json);
|
|
117025
117534
|
await runPipelineCommand(ctx, opts);
|
|
117026
117535
|
});
|
|
117027
117536
|
}
|
|
117028
117537
|
|
|
117029
117538
|
// src/commands/plugin-sync.ts
|
|
117030
117539
|
init_esm_shims();
|
|
117031
|
-
import { homedir } from "os";
|
|
117032
|
-
import { dirname as
|
|
117540
|
+
import { homedir as homedir3 } from "os";
|
|
117541
|
+
import { dirname as dirname4, join as join13, resolve as resolve6 } from "path";
|
|
117033
117542
|
import { fileURLToPath } from "url";
|
|
117034
|
-
|
|
117035
|
-
|
|
117036
|
-
init_esm_shims();
|
|
117037
|
-
import { existsSync as existsSync10 } from "fs";
|
|
117038
|
-
import { cp, mkdir, readFile as readFile9 } from "fs/promises";
|
|
117039
|
-
async function ensureDir(path) {
|
|
117040
|
-
await mkdir(path, { recursive: true });
|
|
117041
|
-
}
|
|
117042
|
-
async function pathExists(path) {
|
|
117043
|
-
return existsSync10(path);
|
|
117044
|
-
}
|
|
117045
|
-
async function readJson(path) {
|
|
117046
|
-
const contents2 = await readFile9(path, "utf-8");
|
|
117047
|
-
return JSON.parse(contents2);
|
|
117048
|
-
}
|
|
117049
|
-
async function copy(src, dest) {
|
|
117050
|
-
await cp(src, dest, { recursive: true, force: true });
|
|
117051
|
-
}
|
|
117052
|
-
|
|
117053
|
-
// src/commands/plugin-sync.ts
|
|
117054
|
-
var PLUGIN_SOURCE_DIR = resolve5(
|
|
117055
|
-
dirname3(fileURLToPath(import.meta.url)),
|
|
117543
|
+
var PLUGIN_SOURCE_DIR = resolve6(
|
|
117544
|
+
dirname4(fileURLToPath(import.meta.url)),
|
|
117056
117545
|
"../../plugin"
|
|
117057
117546
|
);
|
|
117058
|
-
var PLUGIN_MANIFEST_RELATIVE =
|
|
117547
|
+
var PLUGIN_MANIFEST_RELATIVE = join13(".claude-plugin", "plugin.json");
|
|
117059
117548
|
var resolveTargetDir = (global2) => {
|
|
117060
|
-
const base =
|
|
117061
|
-
return
|
|
117549
|
+
const base = join13(homedir3(), ".claude", global2 ? "skills" : "plugins");
|
|
117550
|
+
return join13(base, "skill-cli");
|
|
117062
117551
|
};
|
|
117063
117552
|
var readManifest = async (path) => {
|
|
117064
117553
|
const manifest = await readJson(path);
|
|
@@ -117087,7 +117576,7 @@ var writeResult4 = (ctx, payload) => {
|
|
|
117087
117576
|
};
|
|
117088
117577
|
async function executePluginSync(ctx, options) {
|
|
117089
117578
|
try {
|
|
117090
|
-
const sourceManifestPath =
|
|
117579
|
+
const sourceManifestPath = join13(PLUGIN_SOURCE_DIR, PLUGIN_MANIFEST_RELATIVE);
|
|
117091
117580
|
const sourceExists = await pathExists(sourceManifestPath);
|
|
117092
117581
|
if (!sourceExists) {
|
|
117093
117582
|
throw new CLIError({
|
|
@@ -117097,7 +117586,7 @@ async function executePluginSync(ctx, options) {
|
|
|
117097
117586
|
}
|
|
117098
117587
|
const sourceManifest = await readManifest(sourceManifestPath);
|
|
117099
117588
|
const targetDir = resolveTargetDir(options.global);
|
|
117100
|
-
const targetManifestPath =
|
|
117589
|
+
const targetManifestPath = join13(targetDir, PLUGIN_MANIFEST_RELATIVE);
|
|
117101
117590
|
const targetExists = await pathExists(targetManifestPath);
|
|
117102
117591
|
if (targetExists && !options.force) {
|
|
117103
117592
|
const targetManifest = await readManifest(targetManifestPath);
|
|
@@ -117158,7 +117647,7 @@ var registerPluginSyncCommand = (program3) => {
|
|
|
117158
117647
|
|
|
117159
117648
|
// src/commands/responses.ts
|
|
117160
117649
|
init_esm_shims();
|
|
117161
|
-
import { writeFileSync as
|
|
117650
|
+
import { writeFileSync as writeFileSync12 } from "fs";
|
|
117162
117651
|
function formatDate3(date) {
|
|
117163
117652
|
return date.toLocaleString("en-US", {
|
|
117164
117653
|
month: "short",
|
|
@@ -117691,7 +118180,7 @@ async function exportResponses(ctx, options) {
|
|
|
117691
118180
|
}
|
|
117692
118181
|
const outputJson = JSON.stringify(exportData, null, 2);
|
|
117693
118182
|
if (options.output) {
|
|
117694
|
-
|
|
118183
|
+
writeFileSync12(options.output, outputJson, "utf-8");
|
|
117695
118184
|
if (!outputJsonFormat) {
|
|
117696
118185
|
ctx.output.success(
|
|
117697
118186
|
`Exported ${exportData.length} responses to ${options.output}`
|
|
@@ -118339,8 +118828,8 @@ async function wizard(ctx, options = {}) {
|
|
|
118339
118828
|
init_esm_shims();
|
|
118340
118829
|
import { spawn } from "child_process";
|
|
118341
118830
|
import { writeFile as writeFile7 } from "fs/promises";
|
|
118342
|
-
import { homedir as
|
|
118343
|
-
import { dirname as
|
|
118831
|
+
import { homedir as homedir4 } from "os";
|
|
118832
|
+
import { dirname as dirname5, join as join14 } from "path";
|
|
118344
118833
|
var CONFIG_DIR_NAME = "skill-cli";
|
|
118345
118834
|
var AUTO_UPDATE_STATE_FILE = "auto-update.json";
|
|
118346
118835
|
var DEFAULT_PACKAGE = "@skillrecordings/cli";
|
|
@@ -118352,7 +118841,7 @@ var AutoUpdateStore = class {
|
|
|
118352
118841
|
now;
|
|
118353
118842
|
constructor(options = {}) {
|
|
118354
118843
|
const configDir = resolveConfigDir(options.configDir);
|
|
118355
|
-
this.filePath =
|
|
118844
|
+
this.filePath = join14(configDir, AUTO_UPDATE_STATE_FILE);
|
|
118356
118845
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
118357
118846
|
}
|
|
118358
118847
|
getNow() {
|
|
@@ -118370,7 +118859,7 @@ var AutoUpdateStore = class {
|
|
|
118370
118859
|
}
|
|
118371
118860
|
async save(state) {
|
|
118372
118861
|
try {
|
|
118373
|
-
await ensureDir(
|
|
118862
|
+
await ensureDir(dirname5(this.filePath));
|
|
118374
118863
|
await writeFile7(this.filePath, JSON.stringify(state, null, 2), "utf-8");
|
|
118375
118864
|
} catch {
|
|
118376
118865
|
}
|
|
@@ -118380,9 +118869,9 @@ function resolveConfigDir(configDir) {
|
|
|
118380
118869
|
if (configDir) return configDir;
|
|
118381
118870
|
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
118382
118871
|
if (xdgConfigHome && xdgConfigHome.trim() !== "") {
|
|
118383
|
-
return
|
|
118872
|
+
return join14(xdgConfigHome, CONFIG_DIR_NAME);
|
|
118384
118873
|
}
|
|
118385
|
-
return
|
|
118874
|
+
return join14(homedir4(), ".config", CONFIG_DIR_NAME);
|
|
118386
118875
|
}
|
|
118387
118876
|
function isAutoUpdateState(value) {
|
|
118388
118877
|
if (!value || typeof value !== "object") return false;
|
|
@@ -118500,16 +118989,16 @@ async function performUpdate(options = {}) {
|
|
|
118500
118989
|
const packageManager = resolvePackageManager(options.userAgent);
|
|
118501
118990
|
const spawnFn = options.spawnFn ?? spawn;
|
|
118502
118991
|
const [command, args] = packageManager === "bun" ? ["bun", ["add", "-g", packageName]] : ["npm", ["install", "-g", packageName]];
|
|
118503
|
-
const exitCode = await new Promise((
|
|
118992
|
+
const exitCode = await new Promise((resolve9) => {
|
|
118504
118993
|
try {
|
|
118505
118994
|
const child = spawnFn(command, args, {
|
|
118506
118995
|
stdio: "ignore",
|
|
118507
118996
|
env: process.env
|
|
118508
118997
|
});
|
|
118509
|
-
child.on("error", () =>
|
|
118510
|
-
child.on("close", (code) =>
|
|
118998
|
+
child.on("error", () => resolve9(1));
|
|
118999
|
+
child.on("close", (code) => resolve9(code ?? 1));
|
|
118511
119000
|
} catch {
|
|
118512
|
-
|
|
119001
|
+
resolve9(1);
|
|
118513
119002
|
}
|
|
118514
119003
|
});
|
|
118515
119004
|
if (exitCode === 0) {
|
|
@@ -118674,6 +119163,72 @@ var writeHints = (hints, stderr) => {
|
|
|
118674
119163
|
}
|
|
118675
119164
|
};
|
|
118676
119165
|
|
|
119166
|
+
// src/core/skill-link.ts
|
|
119167
|
+
init_esm_shims();
|
|
119168
|
+
import { lstat, readlink, symlink } from "fs/promises";
|
|
119169
|
+
import { homedir as homedir5 } from "os";
|
|
119170
|
+
import { dirname as dirname6, join as join15, resolve as resolve7 } from "path";
|
|
119171
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
119172
|
+
var SKILL_SOURCE_DIR = resolve7(
|
|
119173
|
+
dirname6(fileURLToPath2(import.meta.url)),
|
|
119174
|
+
"../../../../.claude/skills/skill-cli"
|
|
119175
|
+
);
|
|
119176
|
+
var SKILL_TARGET_DIR = join15(homedir5(), ".claude", "skills", "skill-cli");
|
|
119177
|
+
async function autoLinkSkill() {
|
|
119178
|
+
const source = SKILL_SOURCE_DIR;
|
|
119179
|
+
const target = SKILL_TARGET_DIR;
|
|
119180
|
+
try {
|
|
119181
|
+
let stats4;
|
|
119182
|
+
try {
|
|
119183
|
+
stats4 = await lstat(target);
|
|
119184
|
+
} catch (e) {
|
|
119185
|
+
if (e.code === "ENOENT") {
|
|
119186
|
+
const { mkdir: mkdir2 } = await import("fs/promises");
|
|
119187
|
+
await mkdir2(dirname6(target), { recursive: true });
|
|
119188
|
+
await symlink(source, target, "dir");
|
|
119189
|
+
return {
|
|
119190
|
+
status: "linked",
|
|
119191
|
+
source,
|
|
119192
|
+
target,
|
|
119193
|
+
message: `Linked skill-cli to ${target}`
|
|
119194
|
+
};
|
|
119195
|
+
}
|
|
119196
|
+
throw e;
|
|
119197
|
+
}
|
|
119198
|
+
if (stats4.isSymbolicLink()) {
|
|
119199
|
+
const linkTarget = await readlink(target);
|
|
119200
|
+
const resolvedLinkTarget = resolve7(dirname6(target), linkTarget);
|
|
119201
|
+
if (resolvedLinkTarget === source || linkTarget === source) {
|
|
119202
|
+
return {
|
|
119203
|
+
status: "exists",
|
|
119204
|
+
source,
|
|
119205
|
+
target,
|
|
119206
|
+
message: "Skill already linked"
|
|
119207
|
+
};
|
|
119208
|
+
}
|
|
119209
|
+
return {
|
|
119210
|
+
status: "conflict",
|
|
119211
|
+
source,
|
|
119212
|
+
target,
|
|
119213
|
+
message: `Conflict: ${target} is a symlink to ${linkTarget}`
|
|
119214
|
+
};
|
|
119215
|
+
}
|
|
119216
|
+
return {
|
|
119217
|
+
status: "conflict",
|
|
119218
|
+
source,
|
|
119219
|
+
target,
|
|
119220
|
+
message: `Conflict: ${target} already exists`
|
|
119221
|
+
};
|
|
119222
|
+
} catch (error) {
|
|
119223
|
+
return {
|
|
119224
|
+
status: "error",
|
|
119225
|
+
source,
|
|
119226
|
+
target,
|
|
119227
|
+
message: error instanceof Error ? error.message : String(error)
|
|
119228
|
+
};
|
|
119229
|
+
}
|
|
119230
|
+
}
|
|
119231
|
+
|
|
118677
119232
|
// src/core/telemetry.ts
|
|
118678
119233
|
init_esm_shims();
|
|
118679
119234
|
import { Axiom as Axiom2 } from "@axiomhq/js";
|
|
@@ -118721,17 +119276,17 @@ async function sendTelemetryEvent(event) {
|
|
|
118721
119276
|
// src/core/usage-tracker.ts
|
|
118722
119277
|
init_esm_shims();
|
|
118723
119278
|
import { writeFile as writeFile8 } from "fs/promises";
|
|
118724
|
-
import { homedir as
|
|
118725
|
-
import { dirname as
|
|
119279
|
+
import { homedir as homedir6 } from "os";
|
|
119280
|
+
import { dirname as dirname7, join as join16 } from "path";
|
|
118726
119281
|
var CONFIG_DIR_NAME2 = "skill-cli";
|
|
118727
119282
|
var USAGE_FILE_NAME = "usage.json";
|
|
118728
119283
|
function resolveConfigDir2(configDir) {
|
|
118729
119284
|
if (configDir) return configDir;
|
|
118730
119285
|
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
118731
119286
|
if (xdgConfigHome && xdgConfigHome.trim() !== "") {
|
|
118732
|
-
return
|
|
119287
|
+
return join16(xdgConfigHome, CONFIG_DIR_NAME2);
|
|
118733
119288
|
}
|
|
118734
|
-
return
|
|
119289
|
+
return join16(homedir6(), ".config", CONFIG_DIR_NAME2);
|
|
118735
119290
|
}
|
|
118736
119291
|
function createDefaultState(now) {
|
|
118737
119292
|
return {
|
|
@@ -118769,7 +119324,7 @@ var UsageTracker = class {
|
|
|
118769
119324
|
statePromise;
|
|
118770
119325
|
constructor(options = {}) {
|
|
118771
119326
|
const configDir = resolveConfigDir2(options.configDir);
|
|
118772
|
-
this.filePath =
|
|
119327
|
+
this.filePath = join16(configDir, USAGE_FILE_NAME);
|
|
118773
119328
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
118774
119329
|
}
|
|
118775
119330
|
async loadState() {
|
|
@@ -118792,7 +119347,7 @@ var UsageTracker = class {
|
|
|
118792
119347
|
}
|
|
118793
119348
|
async saveState(state) {
|
|
118794
119349
|
try {
|
|
118795
|
-
await ensureDir(
|
|
119350
|
+
await ensureDir(dirname7(this.filePath));
|
|
118796
119351
|
await writeFile8(this.filePath, JSON.stringify(state, null, 2), "utf-8");
|
|
118797
119352
|
} catch {
|
|
118798
119353
|
}
|
|
@@ -119087,14 +119642,14 @@ async function createToolContext() {
|
|
|
119087
119642
|
return ctx;
|
|
119088
119643
|
}
|
|
119089
119644
|
function captureOutput(stream) {
|
|
119090
|
-
return new Promise((
|
|
119645
|
+
return new Promise((resolve9) => {
|
|
119091
119646
|
let buffer = "";
|
|
119092
119647
|
stream.on("data", (chunk) => {
|
|
119093
119648
|
buffer += chunk.toString();
|
|
119094
119649
|
});
|
|
119095
|
-
stream.on("end", () =>
|
|
119096
|
-
stream.on("close", () =>
|
|
119097
|
-
stream.on("finish", () =>
|
|
119650
|
+
stream.on("end", () => resolve9(buffer));
|
|
119651
|
+
stream.on("close", () => resolve9(buffer));
|
|
119652
|
+
stream.on("finish", () => resolve9(buffer));
|
|
119098
119653
|
});
|
|
119099
119654
|
}
|
|
119100
119655
|
function parseJsonOutput(stdout) {
|
|
@@ -119326,33 +119881,21 @@ function createMcpServer(options = {}) {
|
|
|
119326
119881
|
const onSigterm = () => stop();
|
|
119327
119882
|
process.once("SIGTERM", onSigterm);
|
|
119328
119883
|
removeSigterm = () => process.off("SIGTERM", onSigterm);
|
|
119329
|
-
return new Promise((
|
|
119330
|
-
resolveStop =
|
|
119884
|
+
return new Promise((resolve9) => {
|
|
119885
|
+
resolveStop = resolve9;
|
|
119331
119886
|
});
|
|
119332
119887
|
};
|
|
119333
119888
|
return { start, stop };
|
|
119334
119889
|
}
|
|
119335
119890
|
|
|
119336
119891
|
// src/index.ts
|
|
119892
|
+
var cliRoot = resolve8(import.meta.dirname, "..");
|
|
119893
|
+
var plaintextEnv = loadPlaintextEnv(cliRoot);
|
|
119337
119894
|
var envLoaded = false;
|
|
119338
|
-
|
|
119339
|
-
|
|
119340
|
-
|
|
119341
|
-
const content = readFileSync8(resolve6(cliRoot, envFile), "utf8");
|
|
119342
|
-
for (const line of content.split("\n")) {
|
|
119343
|
-
const trimmed = line.trim();
|
|
119344
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
119345
|
-
const eqIdx = trimmed.indexOf("=");
|
|
119346
|
-
if (eqIdx === -1) continue;
|
|
119347
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
119348
|
-
const raw = trimmed.slice(eqIdx + 1).trim();
|
|
119349
|
-
const value = raw.replace(/^["'](.*)["']$/, "$1");
|
|
119350
|
-
if (!process.env[key]) {
|
|
119351
|
-
process.env[key] = value;
|
|
119352
|
-
}
|
|
119353
|
-
}
|
|
119895
|
+
for (const [key, value] of Object.entries(plaintextEnv)) {
|
|
119896
|
+
if (!process.env[key]) {
|
|
119897
|
+
process.env[key] = value;
|
|
119354
119898
|
envLoaded = true;
|
|
119355
|
-
} catch {
|
|
119356
119899
|
}
|
|
119357
119900
|
}
|
|
119358
119901
|
if (!envLoaded && !process.env.DATABASE_URL) {
|
|
@@ -119578,6 +120121,7 @@ registerFaqCommands(program2);
|
|
|
119578
120121
|
registerDeployCommands(program2);
|
|
119579
120122
|
registerKbCommands(program2);
|
|
119580
120123
|
registerAuthCommands(program2, usageState);
|
|
120124
|
+
registerConfigCommands(program2);
|
|
119581
120125
|
registerPluginSyncCommand(program2);
|
|
119582
120126
|
program2.command("mcp").description(
|
|
119583
120127
|
"Start MCP server for AI coding agent integration.\n Exposes 9 Front tools over JSON-RPC stdio for Claude Code, Cursor, etc.\n Tools: inbox, conversation, message, assign, reply, tag, archive, search, report\n Usage: skill mcp (then connect your AI editor to stdin/stdout)"
|
|
@@ -119585,6 +120129,7 @@ program2.command("mcp").description(
|
|
|
119585
120129
|
const server = createMcpServer();
|
|
119586
120130
|
await server.start();
|
|
119587
120131
|
});
|
|
120132
|
+
void autoLinkSkill();
|
|
119588
120133
|
program2.parseAsync().finally(async () => {
|
|
119589
120134
|
const { closeDb: closeDb2 } = await import("./src-6OB6UR3N.js");
|
|
119590
120135
|
await closeDb2();
|