@hasna/assistants 0.6.38 → 0.6.40
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 +1793 -237
- package/dist/index.js.map +20 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12540,6 +12540,11 @@ var init_codes = __esm(() => {
|
|
|
12540
12540
|
VALIDATION_OUT_OF_RANGE: "VALIDATION_OUT_OF_RANGE",
|
|
12541
12541
|
VALIDATION_SCHEMA_ERROR: "VALIDATION_SCHEMA_ERROR",
|
|
12542
12542
|
HOOK_EXECUTION_FAILED: "HOOK_EXECUTION_FAILED",
|
|
12543
|
+
JOB_NOT_FOUND: "JOB_NOT_FOUND",
|
|
12544
|
+
JOB_ALREADY_RUNNING: "JOB_ALREADY_RUNNING",
|
|
12545
|
+
JOB_TIMEOUT: "JOB_TIMEOUT",
|
|
12546
|
+
JOB_CANCELLED: "JOB_CANCELLED",
|
|
12547
|
+
JOB_EXECUTION_FAILED: "JOB_EXECUTION_FAILED",
|
|
12543
12548
|
UNKNOWN_ERROR: "UNKNOWN_ERROR"
|
|
12544
12549
|
};
|
|
12545
12550
|
});
|
|
@@ -47894,8 +47899,8 @@ var require_core3 = __commonJS((exports) => {
|
|
|
47894
47899
|
function many1(p) {
|
|
47895
47900
|
return ab(p, many(p), (head, tail) => [head, ...tail]);
|
|
47896
47901
|
}
|
|
47897
|
-
function ab(pa, pb,
|
|
47898
|
-
return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) =>
|
|
47902
|
+
function ab(pa, pb, join15) {
|
|
47903
|
+
return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join15(ma.value, vb, data, i, j)));
|
|
47899
47904
|
}
|
|
47900
47905
|
function left(pa, pb) {
|
|
47901
47906
|
return ab(pa, pb, (va) => va);
|
|
@@ -47903,8 +47908,8 @@ var require_core3 = __commonJS((exports) => {
|
|
|
47903
47908
|
function right(pa, pb) {
|
|
47904
47909
|
return ab(pa, pb, (va, vb) => vb);
|
|
47905
47910
|
}
|
|
47906
|
-
function abc(pa, pb, pc,
|
|
47907
|
-
return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) =>
|
|
47911
|
+
function abc(pa, pb, pc, join15) {
|
|
47912
|
+
return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join15(ma.value, mb.value, vc, data, i, j))));
|
|
47908
47913
|
}
|
|
47909
47914
|
function middle(pa, pb, pc) {
|
|
47910
47915
|
return abc(pa, pb, pc, (ra, rb) => rb);
|
|
@@ -60830,11 +60835,11 @@ __export(exports_anthropic, {
|
|
|
60830
60835
|
});
|
|
60831
60836
|
import { readFileSync as readFileSync4, existsSync as existsSync9 } from "fs";
|
|
60832
60837
|
import { homedir as homedir11 } from "os";
|
|
60833
|
-
import { join as
|
|
60838
|
+
import { join as join16 } from "path";
|
|
60834
60839
|
function loadApiKeyFromSecrets() {
|
|
60835
60840
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
60836
60841
|
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir11();
|
|
60837
|
-
const secretsPath =
|
|
60842
|
+
const secretsPath = join16(homeDir, ".secrets");
|
|
60838
60843
|
if (existsSync9(secretsPath)) {
|
|
60839
60844
|
try {
|
|
60840
60845
|
const content = readFileSync4(secretsPath, "utf-8");
|
|
@@ -61182,7 +61187,7 @@ var require_dist_cjs = __commonJS((exports) => {
|
|
|
61182
61187
|
|
|
61183
61188
|
// node_modules/.pnpm/@smithy+protocol-http@5.3.8/node_modules/@smithy/protocol-http/dist-cjs/index.js
|
|
61184
61189
|
var require_dist_cjs2 = __commonJS((exports) => {
|
|
61185
|
-
var
|
|
61190
|
+
var types5 = require_dist_cjs();
|
|
61186
61191
|
var getHttpHandlerExtensionConfiguration = (runtimeConfig) => {
|
|
61187
61192
|
return {
|
|
61188
61193
|
setHttpHandler(handler) {
|
|
@@ -61209,7 +61214,7 @@ var require_dist_cjs2 = __commonJS((exports) => {
|
|
|
61209
61214
|
name;
|
|
61210
61215
|
kind;
|
|
61211
61216
|
values;
|
|
61212
|
-
constructor({ name, kind =
|
|
61217
|
+
constructor({ name, kind = types5.FieldPosition.HEADER, values = [] }) {
|
|
61213
61218
|
this.name = name;
|
|
61214
61219
|
this.kind = kind;
|
|
61215
61220
|
this.values = values;
|
|
@@ -61341,8 +61346,8 @@ var require_dist_cjs2 = __commonJS((exports) => {
|
|
|
61341
61346
|
|
|
61342
61347
|
// node_modules/.pnpm/@smithy+util-middleware@4.2.8/node_modules/@smithy/util-middleware/dist-cjs/index.js
|
|
61343
61348
|
var require_dist_cjs3 = __commonJS((exports) => {
|
|
61344
|
-
var
|
|
61345
|
-
var getSmithyContext = (context) => context[
|
|
61349
|
+
var types5 = require_dist_cjs();
|
|
61350
|
+
var getSmithyContext = (context) => context[types5.SMITHY_CONTEXT_KEY] || (context[types5.SMITHY_CONTEXT_KEY] = {});
|
|
61346
61351
|
var normalizeProvider = (input) => {
|
|
61347
61352
|
if (typeof input === "function")
|
|
61348
61353
|
return input;
|
|
@@ -66278,12 +66283,12 @@ var require_protocols = __commonJS((exports) => {
|
|
|
66278
66283
|
|
|
66279
66284
|
// node_modules/.pnpm/@smithy+core@3.22.0/node_modules/@smithy/core/dist-cjs/index.js
|
|
66280
66285
|
var require_dist_cjs16 = __commonJS((exports) => {
|
|
66281
|
-
var
|
|
66286
|
+
var types5 = require_dist_cjs();
|
|
66282
66287
|
var utilMiddleware = require_dist_cjs3();
|
|
66283
66288
|
var middlewareSerde = require_dist_cjs4();
|
|
66284
66289
|
var protocolHttp = require_dist_cjs2();
|
|
66285
66290
|
var protocols = require_protocols();
|
|
66286
|
-
var getSmithyContext = (context) => context[
|
|
66291
|
+
var getSmithyContext = (context) => context[types5.SMITHY_CONTEXT_KEY] || (context[types5.SMITHY_CONTEXT_KEY] = {});
|
|
66287
66292
|
var resolveAuthOptions = (candidateAuthOptions, authSchemePreference) => {
|
|
66288
66293
|
if (!authSchemePreference || authSchemePreference.length === 0) {
|
|
66289
66294
|
return candidateAuthOptions;
|
|
@@ -66498,9 +66503,9 @@ var require_dist_cjs16 = __commonJS((exports) => {
|
|
|
66498
66503
|
throw new Error("request could not be signed with `apiKey` since the `apiKey` is not defined");
|
|
66499
66504
|
}
|
|
66500
66505
|
const clonedRequest = protocolHttp.HttpRequest.clone(httpRequest);
|
|
66501
|
-
if (signingProperties.in ===
|
|
66506
|
+
if (signingProperties.in === types5.HttpApiKeyAuthLocation.QUERY) {
|
|
66502
66507
|
clonedRequest.query[signingProperties.name] = identity.apiKey;
|
|
66503
|
-
} else if (signingProperties.in ===
|
|
66508
|
+
} else if (signingProperties.in === types5.HttpApiKeyAuthLocation.HEADER) {
|
|
66504
66509
|
clonedRequest.headers[signingProperties.name] = signingProperties.scheme ? `${signingProperties.scheme} ${identity.apiKey}` : identity.apiKey;
|
|
66505
66510
|
} else {
|
|
66506
66511
|
throw new Error("request can only be signed with `apiKey` locations `query` or `header`, " + "but found: `" + signingProperties.in + "`");
|
|
@@ -68615,7 +68620,7 @@ var require_dist_cjs20 = __commonJS((exports) => {
|
|
|
68615
68620
|
var require_dist_cjs21 = __commonJS((exports) => {
|
|
68616
68621
|
var middlewareStack = require_dist_cjs20();
|
|
68617
68622
|
var protocols = require_protocols();
|
|
68618
|
-
var
|
|
68623
|
+
var types5 = require_dist_cjs();
|
|
68619
68624
|
var schema = require_schema();
|
|
68620
68625
|
var serde = require_serde();
|
|
68621
68626
|
|
|
@@ -68714,7 +68719,7 @@ var require_dist_cjs21 = __commonJS((exports) => {
|
|
|
68714
68719
|
commandName,
|
|
68715
68720
|
inputFilterSensitiveLog,
|
|
68716
68721
|
outputFilterSensitiveLog,
|
|
68717
|
-
[
|
|
68722
|
+
[types5.SMITHY_CONTEXT_KEY]: {
|
|
68718
68723
|
commandInstance: this,
|
|
68719
68724
|
...smithyContext
|
|
68720
68725
|
},
|
|
@@ -68965,8 +68970,8 @@ var require_dist_cjs21 = __commonJS((exports) => {
|
|
|
68965
68970
|
};
|
|
68966
68971
|
var getChecksumConfiguration = (runtimeConfig) => {
|
|
68967
68972
|
const checksumAlgorithms = [];
|
|
68968
|
-
for (const id in
|
|
68969
|
-
const algorithmId =
|
|
68973
|
+
for (const id in types5.AlgorithmId) {
|
|
68974
|
+
const algorithmId = types5.AlgorithmId[id];
|
|
68970
68975
|
if (runtimeConfig[algorithmId] === undefined) {
|
|
68971
68976
|
continue;
|
|
68972
68977
|
}
|
|
@@ -72690,7 +72695,7 @@ var require_dist_cjs27 = __commonJS((exports) => {
|
|
|
72690
72695
|
|
|
72691
72696
|
// node_modules/.pnpm/@smithy+util-endpoints@3.2.8/node_modules/@smithy/util-endpoints/dist-cjs/index.js
|
|
72692
72697
|
var require_dist_cjs28 = __commonJS((exports) => {
|
|
72693
|
-
var
|
|
72698
|
+
var types5 = require_dist_cjs();
|
|
72694
72699
|
|
|
72695
72700
|
class EndpointCache {
|
|
72696
72701
|
capacity;
|
|
@@ -72813,8 +72818,8 @@ var require_dist_cjs28 = __commonJS((exports) => {
|
|
|
72813
72818
|
var isSet = (value) => value != null;
|
|
72814
72819
|
var not = (value) => !value;
|
|
72815
72820
|
var DEFAULT_PORTS = {
|
|
72816
|
-
[
|
|
72817
|
-
[
|
|
72821
|
+
[types5.EndpointURLScheme.HTTP]: 80,
|
|
72822
|
+
[types5.EndpointURLScheme.HTTPS]: 443
|
|
72818
72823
|
};
|
|
72819
72824
|
var parseURL = (value) => {
|
|
72820
72825
|
const whatwgURL = (() => {
|
|
@@ -72843,7 +72848,7 @@ var require_dist_cjs28 = __commonJS((exports) => {
|
|
|
72843
72848
|
return null;
|
|
72844
72849
|
}
|
|
72845
72850
|
const scheme = protocol.slice(0, -1);
|
|
72846
|
-
if (!Object.values(
|
|
72851
|
+
if (!Object.values(types5.EndpointURLScheme).includes(scheme)) {
|
|
72847
72852
|
return null;
|
|
72848
72853
|
}
|
|
72849
72854
|
const isIp = isIpAddress(hostname);
|
|
@@ -74024,7 +74029,7 @@ var require_readFile = __commonJS((exports) => {
|
|
|
74024
74029
|
var promises_1 = __require("fs/promises");
|
|
74025
74030
|
exports.filePromises = {};
|
|
74026
74031
|
exports.fileIntercept = {};
|
|
74027
|
-
var
|
|
74032
|
+
var readFile10 = (path2, options) => {
|
|
74028
74033
|
if (exports.fileIntercept[path2] !== undefined) {
|
|
74029
74034
|
return exports.fileIntercept[path2];
|
|
74030
74035
|
}
|
|
@@ -74033,7 +74038,7 @@ var require_readFile = __commonJS((exports) => {
|
|
|
74033
74038
|
}
|
|
74034
74039
|
return exports.filePromises[path2];
|
|
74035
74040
|
};
|
|
74036
|
-
exports.readFile =
|
|
74041
|
+
exports.readFile = readFile10;
|
|
74037
74042
|
});
|
|
74038
74043
|
|
|
74039
74044
|
// node_modules/.pnpm/@smithy+shared-ini-file-loader@4.4.3/node_modules/@smithy/shared-ini-file-loader/dist-cjs/index.js
|
|
@@ -74042,8 +74047,8 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74042
74047
|
var getSSOTokenFilepath = require_getSSOTokenFilepath();
|
|
74043
74048
|
var getSSOTokenFromFile = require_getSSOTokenFromFile();
|
|
74044
74049
|
var path2 = __require("path");
|
|
74045
|
-
var
|
|
74046
|
-
var
|
|
74050
|
+
var types5 = require_dist_cjs();
|
|
74051
|
+
var readFile10 = require_readFile();
|
|
74047
74052
|
var ENV_PROFILE = "AWS_PROFILE";
|
|
74048
74053
|
var DEFAULT_PROFILE2 = "default";
|
|
74049
74054
|
var getProfileName = (init) => init.profile || process.env[ENV_PROFILE] || DEFAULT_PROFILE2;
|
|
@@ -74053,10 +74058,10 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74053
74058
|
if (indexOfSeparator === -1) {
|
|
74054
74059
|
return false;
|
|
74055
74060
|
}
|
|
74056
|
-
return Object.values(
|
|
74061
|
+
return Object.values(types5.IniSectionType).includes(key.substring(0, indexOfSeparator));
|
|
74057
74062
|
}).reduce((acc, [key, value]) => {
|
|
74058
74063
|
const indexOfSeparator = key.indexOf(CONFIG_PREFIX_SEPARATOR);
|
|
74059
|
-
const updatedKey = key.substring(0, indexOfSeparator) ===
|
|
74064
|
+
const updatedKey = key.substring(0, indexOfSeparator) === types5.IniSectionType.PROFILE ? key.substring(indexOfSeparator + 1) : key;
|
|
74060
74065
|
acc[updatedKey] = value;
|
|
74061
74066
|
return acc;
|
|
74062
74067
|
}, {
|
|
@@ -74082,7 +74087,7 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74082
74087
|
const matches = prefixKeyRegex.exec(sectionName);
|
|
74083
74088
|
if (matches) {
|
|
74084
74089
|
const [, prefix, , name] = matches;
|
|
74085
|
-
if (Object.values(
|
|
74090
|
+
if (Object.values(types5.IniSectionType).includes(prefix)) {
|
|
74086
74091
|
currentSection = [prefix, name].join(CONFIG_PREFIX_SEPARATOR);
|
|
74087
74092
|
}
|
|
74088
74093
|
} else {
|
|
@@ -74127,10 +74132,10 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74127
74132
|
resolvedConfigFilepath = path2.join(homeDir, configFilepath.slice(2));
|
|
74128
74133
|
}
|
|
74129
74134
|
const parsedFiles = await Promise.all([
|
|
74130
|
-
|
|
74135
|
+
readFile10.readFile(resolvedConfigFilepath, {
|
|
74131
74136
|
ignoreCache: init.ignoreCache
|
|
74132
74137
|
}).then(parseIni).then(getConfigData).catch(swallowError$1),
|
|
74133
|
-
|
|
74138
|
+
readFile10.readFile(resolvedFilepath, {
|
|
74134
74139
|
ignoreCache: init.ignoreCache
|
|
74135
74140
|
}).then(parseIni).catch(swallowError$1)
|
|
74136
74141
|
]);
|
|
@@ -74139,9 +74144,9 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74139
74144
|
credentialsFile: parsedFiles[1]
|
|
74140
74145
|
};
|
|
74141
74146
|
};
|
|
74142
|
-
var getSsoSessionData = (data) => Object.entries(data).filter(([key]) => key.startsWith(
|
|
74147
|
+
var getSsoSessionData = (data) => Object.entries(data).filter(([key]) => key.startsWith(types5.IniSectionType.SSO_SESSION + CONFIG_PREFIX_SEPARATOR)).reduce((acc, [key, value]) => ({ ...acc, [key.substring(key.indexOf(CONFIG_PREFIX_SEPARATOR) + 1)]: value }), {});
|
|
74143
74148
|
var swallowError = () => ({});
|
|
74144
|
-
var loadSsoSessionData = async (init = {}) =>
|
|
74149
|
+
var loadSsoSessionData = async (init = {}) => readFile10.readFile(init.configFilepath ?? getConfigFilepath()).then(parseIni).then(getSsoSessionData).catch(swallowError);
|
|
74145
74150
|
var mergeConfigFiles = (...files) => {
|
|
74146
74151
|
const merged = {};
|
|
74147
74152
|
for (const file of files) {
|
|
@@ -74161,10 +74166,10 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74161
74166
|
};
|
|
74162
74167
|
var externalDataInterceptor = {
|
|
74163
74168
|
getFileRecord() {
|
|
74164
|
-
return
|
|
74169
|
+
return readFile10.fileIntercept;
|
|
74165
74170
|
},
|
|
74166
74171
|
interceptFile(path3, contents) {
|
|
74167
|
-
|
|
74172
|
+
readFile10.fileIntercept[path3] = Promise.resolve(contents);
|
|
74168
74173
|
},
|
|
74169
74174
|
getTokenRecord() {
|
|
74170
74175
|
return getSSOTokenFromFile.tokenIntercept;
|
|
@@ -74182,7 +74187,7 @@ var require_dist_cjs35 = __commonJS((exports) => {
|
|
|
74182
74187
|
Object.defineProperty(exports, "readFile", {
|
|
74183
74188
|
enumerable: true,
|
|
74184
74189
|
get: function() {
|
|
74185
|
-
return
|
|
74190
|
+
return readFile10.readFile;
|
|
74186
74191
|
}
|
|
74187
74192
|
});
|
|
74188
74193
|
exports.CONFIG_PREFIX_SEPARATOR = CONFIG_PREFIX_SEPARATOR;
|
|
@@ -78875,14 +78880,14 @@ var init_validateTokenKey = __esm(() => {
|
|
|
78875
78880
|
|
|
78876
78881
|
// node_modules/.pnpm/@aws-sdk+token-providers@3.980.0/node_modules/@aws-sdk/token-providers/dist-es/writeSSOTokenToFile.js
|
|
78877
78882
|
import { promises as fsPromises } from "fs";
|
|
78878
|
-
var import_shared_ini_file_loader,
|
|
78883
|
+
var import_shared_ini_file_loader, writeFile10, writeSSOTokenToFile = (id, ssoToken) => {
|
|
78879
78884
|
const tokenFilepath = import_shared_ini_file_loader.getSSOTokenFilepath(id);
|
|
78880
78885
|
const tokenString = JSON.stringify(ssoToken, null, 2);
|
|
78881
|
-
return
|
|
78886
|
+
return writeFile10(tokenFilepath, tokenString);
|
|
78882
78887
|
};
|
|
78883
78888
|
var init_writeSSOTokenToFile = __esm(() => {
|
|
78884
78889
|
import_shared_ini_file_loader = __toESM(require_dist_cjs35(), 1);
|
|
78885
|
-
({ writeFile:
|
|
78890
|
+
({ writeFile: writeFile10 } = fsPromises);
|
|
78886
78891
|
});
|
|
78887
78892
|
|
|
78888
78893
|
// node_modules/.pnpm/@aws-sdk+token-providers@3.980.0/node_modules/@aws-sdk/token-providers/dist-es/fromSso.js
|
|
@@ -81519,7 +81524,7 @@ var require_signin = __commonJS((exports) => {
|
|
|
81519
81524
|
import { createHash, createPrivateKey, createPublicKey, sign } from "crypto";
|
|
81520
81525
|
import { promises as fs3 } from "fs";
|
|
81521
81526
|
import { homedir as homedir13 } from "os";
|
|
81522
|
-
import { dirname as dirname9, join as
|
|
81527
|
+
import { dirname as dirname9, join as join23 } from "path";
|
|
81523
81528
|
var import_property_provider18, import_protocol_http10, import_shared_ini_file_loader6, LoginCredentialsFetcher;
|
|
81524
81529
|
var init_LoginCredentialsFetcher = __esm(() => {
|
|
81525
81530
|
import_property_provider18 = __toESM(require_dist_cjs17(), 1);
|
|
@@ -81679,10 +81684,10 @@ var init_LoginCredentialsFetcher = __esm(() => {
|
|
|
81679
81684
|
await fs3.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
|
|
81680
81685
|
}
|
|
81681
81686
|
getTokenFilePath() {
|
|
81682
|
-
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ??
|
|
81687
|
+
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join23(homedir13(), ".aws", "login", "cache");
|
|
81683
81688
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
81684
81689
|
const loginSessionSha256 = createHash("sha256").update(loginSessionBytes).digest("hex");
|
|
81685
|
-
return
|
|
81690
|
+
return join23(directory, `${loginSessionSha256}.json`);
|
|
81686
81691
|
}
|
|
81687
81692
|
derToRawSignature(derSignature) {
|
|
81688
81693
|
let offset = 2;
|
|
@@ -82721,8 +82726,8 @@ function many(p4) {
|
|
|
82721
82726
|
function many1(p4) {
|
|
82722
82727
|
return ab2(p4, many(p4), (head, tail) => [head, ...tail]);
|
|
82723
82728
|
}
|
|
82724
|
-
function ab2(pa, pb,
|
|
82725
|
-
return (data, i4) => mapOuter(pa(data, i4), (ma) => mapInner(pb(data, ma.position), (vb, j4) =>
|
|
82729
|
+
function ab2(pa, pb, join25) {
|
|
82730
|
+
return (data, i4) => mapOuter(pa(data, i4), (ma) => mapInner(pb(data, ma.position), (vb, j4) => join25(ma.value, vb, data, i4, j4)));
|
|
82726
82731
|
}
|
|
82727
82732
|
function left(pa, pb) {
|
|
82728
82733
|
return ab2(pa, pb, (va) => va);
|
|
@@ -82730,8 +82735,8 @@ function left(pa, pb) {
|
|
|
82730
82735
|
function right(pa, pb) {
|
|
82731
82736
|
return ab2(pa, pb, (va, vb) => vb);
|
|
82732
82737
|
}
|
|
82733
|
-
function abc(pa, pb, pc,
|
|
82734
|
-
return (data, i4) => mapOuter(pa(data, i4), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j4) =>
|
|
82738
|
+
function abc(pa, pb, pc, join25) {
|
|
82739
|
+
return (data, i4) => mapOuter(pa(data, i4), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j4) => join25(ma.value, mb.value, vc, data, i4, j4))));
|
|
82735
82740
|
}
|
|
82736
82741
|
function middle(pa, pb, pc) {
|
|
82737
82742
|
return abc(pa, pb, pc, (ra, rb) => rb);
|
|
@@ -110932,7 +110937,7 @@ var ScrollView = import_react26.forwardRef(({
|
|
|
110932
110937
|
|
|
110933
110938
|
// packages/core/src/agent/loop.ts
|
|
110934
110939
|
init_src();
|
|
110935
|
-
import { join as
|
|
110940
|
+
import { join as join26 } from "path";
|
|
110936
110941
|
|
|
110937
110942
|
// packages/core/src/agent/context.ts
|
|
110938
110943
|
init_src();
|
|
@@ -111638,6 +111643,7 @@ var DEFAULT_SYSTEM_PROMPT = `You are Hasna Assistant, a helpful AI assistant run
|
|
|
111638
111643
|
- Be concise and direct in responses
|
|
111639
111644
|
- Ask clarifying questions when requirements are ambiguous
|
|
111640
111645
|
- Explain your reasoning when making architectural decisions
|
|
111646
|
+
- Use the ask_user tool to collect structured answers when you need details
|
|
111641
111647
|
`;
|
|
111642
111648
|
var DEFAULT_CONFIG = {
|
|
111643
111649
|
llm: {
|
|
@@ -111717,6 +111723,12 @@ var DEFAULT_CONFIG = {
|
|
|
111717
111723
|
security: {
|
|
111718
111724
|
maxReadsPerHour: 10
|
|
111719
111725
|
}
|
|
111726
|
+
},
|
|
111727
|
+
jobs: {
|
|
111728
|
+
enabled: true,
|
|
111729
|
+
defaultTimeoutMs: 60000,
|
|
111730
|
+
maxJobAgeMs: 24 * 60 * 60 * 1000,
|
|
111731
|
+
connectors: {}
|
|
111720
111732
|
}
|
|
111721
111733
|
};
|
|
111722
111734
|
function mergeConfig(base2, override) {
|
|
@@ -111814,6 +111826,14 @@ function mergeConfig(base2, override) {
|
|
|
111814
111826
|
...base2.wallet?.security || {},
|
|
111815
111827
|
...override.wallet?.security || {}
|
|
111816
111828
|
}
|
|
111829
|
+
},
|
|
111830
|
+
jobs: {
|
|
111831
|
+
...base2.jobs || {},
|
|
111832
|
+
...override.jobs || {},
|
|
111833
|
+
connectors: {
|
|
111834
|
+
...base2.jobs?.connectors || {},
|
|
111835
|
+
...override.jobs?.connectors || {}
|
|
111836
|
+
}
|
|
111817
111837
|
}
|
|
111818
111838
|
};
|
|
111819
111839
|
}
|
|
@@ -111892,6 +111912,7 @@ async function ensureConfigDir(sessionId) {
|
|
|
111892
111912
|
mkdir(join(configDir, "heartbeats"), { recursive: true }),
|
|
111893
111913
|
mkdir(join(configDir, "state"), { recursive: true }),
|
|
111894
111914
|
mkdir(join(configDir, "energy"), { recursive: true }),
|
|
111915
|
+
mkdir(join(configDir, "jobs"), { recursive: true }),
|
|
111895
111916
|
mkdir(join(configDir, "inbox"), { recursive: true })
|
|
111896
111917
|
];
|
|
111897
111918
|
if (sessionId) {
|
|
@@ -112186,12 +112207,16 @@ class ConnectorBridge {
|
|
|
112186
112207
|
static cache = new Map;
|
|
112187
112208
|
static diskCacheLoaded = false;
|
|
112188
112209
|
cwd;
|
|
112210
|
+
jobManagerGetter = null;
|
|
112189
112211
|
constructor(cwd2) {
|
|
112190
112212
|
this.cwd = cwd2;
|
|
112191
112213
|
if (!ConnectorBridge.diskCacheLoaded) {
|
|
112192
112214
|
ConnectorBridge.loadDiskCache();
|
|
112193
112215
|
}
|
|
112194
112216
|
}
|
|
112217
|
+
setJobManagerGetter(getter) {
|
|
112218
|
+
this.jobManagerGetter = getter;
|
|
112219
|
+
}
|
|
112195
112220
|
getHomeDir() {
|
|
112196
112221
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
112197
112222
|
return envHome && envHome.trim().length > 0 ? envHome : homedir2();
|
|
@@ -112528,9 +112553,21 @@ class ConnectorBridge {
|
|
|
112528
112553
|
const options = input.options || {};
|
|
112529
112554
|
const cwd2 = typeof input.cwd === "string" ? input.cwd : process.cwd();
|
|
112530
112555
|
const timeoutMs = Number(options.timeoutMs || options.timeout || 15000);
|
|
112556
|
+
const jobManager = this.jobManagerGetter?.();
|
|
112557
|
+
if (jobManager && jobManager.shouldRunAsync(connector.name, input)) {
|
|
112558
|
+
const job = await jobManager.startJob(connector.name, command, input, connector.cli);
|
|
112559
|
+
return `Job started in background.
|
|
112560
|
+
|
|
112561
|
+
Job ID: ${job.id}
|
|
112562
|
+
Connector: ${connector.name}
|
|
112563
|
+
Command: ${command}
|
|
112564
|
+
Timeout: ${job.timeoutMs / 1000}s
|
|
112565
|
+
|
|
112566
|
+
Use job_status or job_result to check progress.`;
|
|
112567
|
+
}
|
|
112531
112568
|
const cmdParts = [connector.cli, ...command.split(" "), ...args];
|
|
112532
112569
|
for (const [key, value] of Object.entries(options)) {
|
|
112533
|
-
if (key === "timeoutMs" || key === "timeout")
|
|
112570
|
+
if (key === "timeoutMs" || key === "timeout" || key === "async")
|
|
112534
112571
|
continue;
|
|
112535
112572
|
if (value === true) {
|
|
112536
112573
|
cmdParts.push(`--${key}`);
|
|
@@ -115079,6 +115116,315 @@ class ImageTools {
|
|
|
115079
115116
|
}
|
|
115080
115117
|
}
|
|
115081
115118
|
|
|
115119
|
+
// packages/core/src/tools/skills.ts
|
|
115120
|
+
init_errors();
|
|
115121
|
+
|
|
115122
|
+
// packages/core/src/skills/create.ts
|
|
115123
|
+
import { join as join8 } from "path";
|
|
115124
|
+
import { mkdir as mkdir3, stat, writeFile as writeFile2 } from "fs/promises";
|
|
115125
|
+
function slugify(input) {
|
|
115126
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9\s-_]/g, "").replace(/[\s_]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
115127
|
+
}
|
|
115128
|
+
function normalizeName(rawName) {
|
|
115129
|
+
const trimmed = rawName.trim();
|
|
115130
|
+
if (!trimmed) {
|
|
115131
|
+
throw new Error("Skill name is required.");
|
|
115132
|
+
}
|
|
115133
|
+
const withoutPrefix = trimmed.startsWith("skill-") ? trimmed.slice("skill-".length) : trimmed;
|
|
115134
|
+
if (/skill/i.test(withoutPrefix)) {
|
|
115135
|
+
throw new Error('Skill name should not include the word "skill".');
|
|
115136
|
+
}
|
|
115137
|
+
const slug = slugify(withoutPrefix);
|
|
115138
|
+
if (!slug) {
|
|
115139
|
+
throw new Error("Skill name is invalid after normalization.");
|
|
115140
|
+
}
|
|
115141
|
+
return { skillName: slug, dirName: `skill-${slug}` };
|
|
115142
|
+
}
|
|
115143
|
+
function buildFrontmatter(options, skillName) {
|
|
115144
|
+
const lines = [];
|
|
115145
|
+
lines.push("---");
|
|
115146
|
+
lines.push(`name: ${skillName}`);
|
|
115147
|
+
if (options.description) {
|
|
115148
|
+
lines.push(`description: ${options.description}`);
|
|
115149
|
+
}
|
|
115150
|
+
if (options.allowedTools && options.allowedTools.length > 0) {
|
|
115151
|
+
lines.push("allowed-tools:");
|
|
115152
|
+
for (const tool of options.allowedTools) {
|
|
115153
|
+
lines.push(` - ${tool}`);
|
|
115154
|
+
}
|
|
115155
|
+
}
|
|
115156
|
+
if (options.argumentHint) {
|
|
115157
|
+
lines.push(`argument-hint: ${options.argumentHint}`);
|
|
115158
|
+
}
|
|
115159
|
+
if (options.userInvocable === false) {
|
|
115160
|
+
lines.push("user-invocable: false");
|
|
115161
|
+
}
|
|
115162
|
+
if (options.disableModelInvocation === true) {
|
|
115163
|
+
lines.push("disable-model-invocation: true");
|
|
115164
|
+
}
|
|
115165
|
+
lines.push("---");
|
|
115166
|
+
return lines.join(`
|
|
115167
|
+
`);
|
|
115168
|
+
}
|
|
115169
|
+
function buildDefaultContent() {
|
|
115170
|
+
return [
|
|
115171
|
+
"Describe what this skill does.",
|
|
115172
|
+
"",
|
|
115173
|
+
"Use $ARGUMENTS to accept user input."
|
|
115174
|
+
].join(`
|
|
115175
|
+
`);
|
|
115176
|
+
}
|
|
115177
|
+
function resolveSkillRoot(scope, cwd2) {
|
|
115178
|
+
if (scope === "global") {
|
|
115179
|
+
return join8(getConfigDir(), "shared", "skills");
|
|
115180
|
+
}
|
|
115181
|
+
return join8(cwd2, ".assistants", "skills");
|
|
115182
|
+
}
|
|
115183
|
+
async function pathExists(path) {
|
|
115184
|
+
try {
|
|
115185
|
+
const stats = await stat(path);
|
|
115186
|
+
return stats.isFile() || stats.isDirectory();
|
|
115187
|
+
} catch {
|
|
115188
|
+
return false;
|
|
115189
|
+
}
|
|
115190
|
+
}
|
|
115191
|
+
async function createSkill(options) {
|
|
115192
|
+
const scope = options.scope ?? "project";
|
|
115193
|
+
const { skillName, dirName } = normalizeName(options.name);
|
|
115194
|
+
const root = resolveSkillRoot(scope, options.cwd);
|
|
115195
|
+
const directory = join8(root, dirName);
|
|
115196
|
+
const filePath = join8(directory, "SKILL.md");
|
|
115197
|
+
if (!options.overwrite && await pathExists(filePath)) {
|
|
115198
|
+
throw new Error(`Skill already exists at ${filePath}`);
|
|
115199
|
+
}
|
|
115200
|
+
await mkdir3(directory, { recursive: true });
|
|
115201
|
+
const frontmatter = buildFrontmatter(options, skillName);
|
|
115202
|
+
const content = options.content && options.content.trim().length > 0 ? options.content.trim() : buildDefaultContent();
|
|
115203
|
+
const body = `${frontmatter}
|
|
115204
|
+
|
|
115205
|
+
${content}
|
|
115206
|
+
`;
|
|
115207
|
+
await writeFile2(filePath, body);
|
|
115208
|
+
return {
|
|
115209
|
+
name: skillName,
|
|
115210
|
+
directory,
|
|
115211
|
+
filePath,
|
|
115212
|
+
scope
|
|
115213
|
+
};
|
|
115214
|
+
}
|
|
115215
|
+
|
|
115216
|
+
// packages/core/src/tools/skills.ts
|
|
115217
|
+
function normalizeScope(input) {
|
|
115218
|
+
if (!input)
|
|
115219
|
+
return null;
|
|
115220
|
+
const value = String(input).trim().toLowerCase();
|
|
115221
|
+
if (value === "project" || value === "global")
|
|
115222
|
+
return value;
|
|
115223
|
+
return null;
|
|
115224
|
+
}
|
|
115225
|
+
function normalizeAllowedTools(input) {
|
|
115226
|
+
if (!input)
|
|
115227
|
+
return;
|
|
115228
|
+
if (Array.isArray(input)) {
|
|
115229
|
+
const tools = input.map((tool) => String(tool).trim()).filter(Boolean);
|
|
115230
|
+
return tools.length > 0 ? tools : undefined;
|
|
115231
|
+
}
|
|
115232
|
+
if (typeof input === "string") {
|
|
115233
|
+
const tools = input.split(",").map((tool) => tool.trim()).filter(Boolean);
|
|
115234
|
+
return tools.length > 0 ? tools : undefined;
|
|
115235
|
+
}
|
|
115236
|
+
return;
|
|
115237
|
+
}
|
|
115238
|
+
|
|
115239
|
+
class SkillTool {
|
|
115240
|
+
static tool = {
|
|
115241
|
+
name: "skill_create",
|
|
115242
|
+
description: "Create a skill (SKILL.md). Requires explicit scope (project or global).",
|
|
115243
|
+
parameters: {
|
|
115244
|
+
type: "object",
|
|
115245
|
+
properties: {
|
|
115246
|
+
name: {
|
|
115247
|
+
type: "string",
|
|
115248
|
+
description: 'Skill name without the "skill-" prefix.'
|
|
115249
|
+
},
|
|
115250
|
+
scope: {
|
|
115251
|
+
type: "string",
|
|
115252
|
+
description: "Where to create the skill.",
|
|
115253
|
+
enum: ["project", "global"]
|
|
115254
|
+
},
|
|
115255
|
+
description: {
|
|
115256
|
+
type: "string",
|
|
115257
|
+
description: "Short description for the skill."
|
|
115258
|
+
},
|
|
115259
|
+
content: {
|
|
115260
|
+
type: "string",
|
|
115261
|
+
description: "Skill body content (markdown)."
|
|
115262
|
+
},
|
|
115263
|
+
allowed_tools: {
|
|
115264
|
+
type: "array",
|
|
115265
|
+
description: "Allowed tools for the skill (array or comma-separated string).",
|
|
115266
|
+
items: { type: "string", description: "Tool name" }
|
|
115267
|
+
},
|
|
115268
|
+
argument_hint: {
|
|
115269
|
+
type: "string",
|
|
115270
|
+
description: "Argument hint for invocation."
|
|
115271
|
+
},
|
|
115272
|
+
overwrite: {
|
|
115273
|
+
type: "boolean",
|
|
115274
|
+
description: "Overwrite if skill already exists.",
|
|
115275
|
+
default: false
|
|
115276
|
+
},
|
|
115277
|
+
cwd: {
|
|
115278
|
+
type: "string",
|
|
115279
|
+
description: "Working directory for project scope (autofilled)."
|
|
115280
|
+
}
|
|
115281
|
+
},
|
|
115282
|
+
required: ["name"]
|
|
115283
|
+
}
|
|
115284
|
+
};
|
|
115285
|
+
static executor = async (input) => {
|
|
115286
|
+
const rawName = String(input.name || "").trim();
|
|
115287
|
+
if (!rawName) {
|
|
115288
|
+
throw new ToolExecutionError("Skill name is required.", {
|
|
115289
|
+
toolName: "skill_create",
|
|
115290
|
+
toolInput: input,
|
|
115291
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
115292
|
+
recoverable: true,
|
|
115293
|
+
retryable: false,
|
|
115294
|
+
suggestion: 'Provide a skill name without the "skill-" prefix.'
|
|
115295
|
+
});
|
|
115296
|
+
}
|
|
115297
|
+
const scope = normalizeScope(input.scope);
|
|
115298
|
+
if (!scope) {
|
|
115299
|
+
throw new ToolExecutionError("Scope is required (project or global).", {
|
|
115300
|
+
toolName: "skill_create",
|
|
115301
|
+
toolInput: input,
|
|
115302
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
115303
|
+
recoverable: true,
|
|
115304
|
+
retryable: false,
|
|
115305
|
+
suggestion: "Ask the user: project (default) or global?"
|
|
115306
|
+
});
|
|
115307
|
+
}
|
|
115308
|
+
const cwd2 = String(input.cwd || process.cwd());
|
|
115309
|
+
const allowedTools = normalizeAllowedTools(input.allowed_tools ?? input.allowedTools);
|
|
115310
|
+
const result = await createSkill({
|
|
115311
|
+
name: rawName,
|
|
115312
|
+
scope,
|
|
115313
|
+
description: input.description ? String(input.description) : undefined,
|
|
115314
|
+
content: input.content ? String(input.content) : undefined,
|
|
115315
|
+
allowedTools,
|
|
115316
|
+
argumentHint: input.argument_hint ? String(input.argument_hint) : undefined,
|
|
115317
|
+
overwrite: Boolean(input.overwrite),
|
|
115318
|
+
cwd: cwd2
|
|
115319
|
+
});
|
|
115320
|
+
return [
|
|
115321
|
+
`Created skill "${result.name}" (${result.scope}).`,
|
|
115322
|
+
`Location: ${result.filePath}`,
|
|
115323
|
+
`Invoke with: $${result.name} [args] or /${result.name} [args]`
|
|
115324
|
+
].join(`
|
|
115325
|
+
`);
|
|
115326
|
+
};
|
|
115327
|
+
}
|
|
115328
|
+
|
|
115329
|
+
// packages/core/src/tools/ask-user.ts
|
|
115330
|
+
init_errors();
|
|
115331
|
+
function createAskUserTool(getHandler) {
|
|
115332
|
+
const tool = {
|
|
115333
|
+
name: "ask_user",
|
|
115334
|
+
description: "Ask the user clarifying questions and return structured answers.",
|
|
115335
|
+
parameters: {
|
|
115336
|
+
type: "object",
|
|
115337
|
+
properties: {
|
|
115338
|
+
title: {
|
|
115339
|
+
type: "string",
|
|
115340
|
+
description: "Short title shown above the questions."
|
|
115341
|
+
},
|
|
115342
|
+
description: {
|
|
115343
|
+
type: "string",
|
|
115344
|
+
description: "Optional context for the user."
|
|
115345
|
+
},
|
|
115346
|
+
questions: {
|
|
115347
|
+
type: "array",
|
|
115348
|
+
description: "Questions to ask the user.",
|
|
115349
|
+
items: {
|
|
115350
|
+
type: "object",
|
|
115351
|
+
properties: {
|
|
115352
|
+
id: { type: "string", description: "Stable id for this question." },
|
|
115353
|
+
question: { type: "string", description: "The question text." },
|
|
115354
|
+
options: { type: "array", items: { type: "string", description: "Option label" } },
|
|
115355
|
+
placeholder: { type: "string", description: "Placeholder text for input." },
|
|
115356
|
+
multiline: { type: "boolean", description: "Whether the answer can be multi-line." },
|
|
115357
|
+
required: { type: "boolean", description: "Whether the answer is required." }
|
|
115358
|
+
},
|
|
115359
|
+
required: ["id", "question"]
|
|
115360
|
+
}
|
|
115361
|
+
}
|
|
115362
|
+
},
|
|
115363
|
+
required: ["questions"]
|
|
115364
|
+
}
|
|
115365
|
+
};
|
|
115366
|
+
const executor = async (input) => {
|
|
115367
|
+
const handler = getHandler();
|
|
115368
|
+
if (!handler) {
|
|
115369
|
+
throw new ToolExecutionError("User input is not available in this environment.", {
|
|
115370
|
+
toolName: "ask_user",
|
|
115371
|
+
toolInput: input,
|
|
115372
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
115373
|
+
recoverable: true,
|
|
115374
|
+
retryable: false,
|
|
115375
|
+
suggestion: "Ask the user directly in chat."
|
|
115376
|
+
});
|
|
115377
|
+
}
|
|
115378
|
+
const questions = Array.isArray(input.questions) ? input.questions : [];
|
|
115379
|
+
if (questions.length === 0) {
|
|
115380
|
+
throw new ToolExecutionError("ask_user requires at least one question.", {
|
|
115381
|
+
toolName: "ask_user",
|
|
115382
|
+
toolInput: input,
|
|
115383
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
115384
|
+
recoverable: true,
|
|
115385
|
+
retryable: false,
|
|
115386
|
+
suggestion: "Provide an array of questions with id and question fields."
|
|
115387
|
+
});
|
|
115388
|
+
}
|
|
115389
|
+
if (questions.length > 6) {
|
|
115390
|
+
throw new ToolExecutionError("ask_user supports up to 6 questions at a time.", {
|
|
115391
|
+
toolName: "ask_user",
|
|
115392
|
+
toolInput: input,
|
|
115393
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
115394
|
+
recoverable: true,
|
|
115395
|
+
retryable: false,
|
|
115396
|
+
suggestion: "Split into multiple ask_user calls."
|
|
115397
|
+
});
|
|
115398
|
+
}
|
|
115399
|
+
const request = {
|
|
115400
|
+
title: input.title ? String(input.title) : undefined,
|
|
115401
|
+
description: input.description ? String(input.description) : undefined,
|
|
115402
|
+
questions: questions.map((entry) => ({
|
|
115403
|
+
id: String(entry.id || ""),
|
|
115404
|
+
question: String(entry.question || ""),
|
|
115405
|
+
options: Array.isArray(entry.options) ? entry.options.map((opt) => String(opt)) : undefined,
|
|
115406
|
+
placeholder: entry.placeholder ? String(entry.placeholder) : undefined,
|
|
115407
|
+
multiline: Boolean(entry.multiline),
|
|
115408
|
+
required: entry.required !== undefined ? Boolean(entry.required) : undefined
|
|
115409
|
+
}))
|
|
115410
|
+
};
|
|
115411
|
+
for (const q of request.questions) {
|
|
115412
|
+
if (!q.id || !q.question) {
|
|
115413
|
+
throw new ToolExecutionError("Each ask_user question must include id and question.", {
|
|
115414
|
+
toolName: "ask_user",
|
|
115415
|
+
toolInput: input,
|
|
115416
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
115417
|
+
recoverable: true,
|
|
115418
|
+
retryable: false
|
|
115419
|
+
});
|
|
115420
|
+
}
|
|
115421
|
+
}
|
|
115422
|
+
const response = await handler(request);
|
|
115423
|
+
return JSON.stringify(response.answers ?? {}, null, 2);
|
|
115424
|
+
};
|
|
115425
|
+
return { tool, executor };
|
|
115426
|
+
}
|
|
115427
|
+
|
|
115082
115428
|
// packages/core/src/agent/subagent.ts
|
|
115083
115429
|
init_src();
|
|
115084
115430
|
var DEFAULT_HOOK_TOOLS = ["read", "glob", "grep"];
|
|
@@ -115115,7 +115461,7 @@ Respond with ALLOW or DENY on the first line, followed by a short reason.`,
|
|
|
115115
115461
|
|
|
115116
115462
|
// packages/core/src/skills/loader.ts
|
|
115117
115463
|
init_src();
|
|
115118
|
-
import { join as
|
|
115464
|
+
import { join as join9, basename, dirname as dirname4 } from "path";
|
|
115119
115465
|
import { homedir as homedir7 } from "os";
|
|
115120
115466
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
115121
115467
|
|
|
@@ -115124,20 +115470,20 @@ class SkillLoader {
|
|
|
115124
115470
|
async loadAll(projectDir = process.cwd()) {
|
|
115125
115471
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
115126
115472
|
const userHome = envHome && envHome.trim().length > 0 ? envHome : homedir7();
|
|
115127
|
-
const userSkillsDir =
|
|
115473
|
+
const userSkillsDir = join9(userHome, ".assistants", "shared", "skills");
|
|
115128
115474
|
await this.loadFromDirectory(userSkillsDir);
|
|
115129
|
-
const projectSkillsDir =
|
|
115475
|
+
const projectSkillsDir = join9(projectDir, ".assistants", "skills");
|
|
115130
115476
|
await this.loadFromDirectory(projectSkillsDir);
|
|
115131
115477
|
const nestedGlob = new Glob2("**/.assistants/skills/*/SKILL.md");
|
|
115132
115478
|
for await (const file of nestedGlob.scan({ cwd: projectDir, dot: true })) {
|
|
115133
|
-
await this.loadSkillFile(
|
|
115479
|
+
await this.loadSkillFile(join9(projectDir, file));
|
|
115134
115480
|
}
|
|
115135
115481
|
}
|
|
115136
115482
|
async loadFromDirectory(dir) {
|
|
115137
115483
|
try {
|
|
115138
|
-
const { stat } = await import("fs/promises");
|
|
115484
|
+
const { stat: stat2 } = await import("fs/promises");
|
|
115139
115485
|
try {
|
|
115140
|
-
const stats = await
|
|
115486
|
+
const stats = await stat2(dir);
|
|
115141
115487
|
if (!stats.isDirectory())
|
|
115142
115488
|
return;
|
|
115143
115489
|
} catch {
|
|
@@ -115146,13 +115492,13 @@ class SkillLoader {
|
|
|
115146
115492
|
const filesToLoad = [];
|
|
115147
115493
|
const skillPrefixGlob = new Glob2("skill-*/SKILL.md");
|
|
115148
115494
|
for await (const file of skillPrefixGlob.scan({ cwd: dir })) {
|
|
115149
|
-
filesToLoad.push(
|
|
115495
|
+
filesToLoad.push(join9(dir, file));
|
|
115150
115496
|
}
|
|
115151
115497
|
const regularGlob = new Glob2("*/SKILL.md");
|
|
115152
115498
|
for await (const file of regularGlob.scan({ cwd: dir })) {
|
|
115153
115499
|
const dirName = file.split(/[\\/]/)[0];
|
|
115154
115500
|
if (!dirName.startsWith("skill-")) {
|
|
115155
|
-
filesToLoad.push(
|
|
115501
|
+
filesToLoad.push(join9(dir, file));
|
|
115156
115502
|
}
|
|
115157
115503
|
}
|
|
115158
115504
|
const loadTasks = [];
|
|
@@ -115803,14 +116149,14 @@ init_src();
|
|
|
115803
116149
|
|
|
115804
116150
|
// packages/core/src/sessions/verification.ts
|
|
115805
116151
|
init_src();
|
|
115806
|
-
import { join as
|
|
116152
|
+
import { join as join10 } from "path";
|
|
115807
116153
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4, readdirSync as readdirSync2 } from "fs";
|
|
115808
116154
|
|
|
115809
116155
|
class VerificationSessionStore {
|
|
115810
116156
|
basePath;
|
|
115811
116157
|
maxSessions;
|
|
115812
116158
|
constructor(basePath, maxSessions = 100) {
|
|
115813
|
-
this.basePath =
|
|
116159
|
+
this.basePath = join10(basePath, "verifications");
|
|
115814
116160
|
this.maxSessions = maxSessions;
|
|
115815
116161
|
this.ensureDirectory();
|
|
115816
116162
|
}
|
|
@@ -115836,11 +116182,11 @@ class VerificationSessionStore {
|
|
|
115836
116182
|
return session;
|
|
115837
116183
|
}
|
|
115838
116184
|
save(session) {
|
|
115839
|
-
const filePath =
|
|
116185
|
+
const filePath = join10(this.basePath, `${session.id}.json`);
|
|
115840
116186
|
writeFileSync4(filePath, JSON.stringify(session, null, 2));
|
|
115841
116187
|
}
|
|
115842
116188
|
get(id) {
|
|
115843
|
-
const filePath =
|
|
116189
|
+
const filePath = join10(this.basePath, `${id}.json`);
|
|
115844
116190
|
if (!existsSync6(filePath)) {
|
|
115845
116191
|
return null;
|
|
115846
116192
|
}
|
|
@@ -115856,7 +116202,7 @@ class VerificationSessionStore {
|
|
|
115856
116202
|
const files = this.listFiles();
|
|
115857
116203
|
for (const file of files) {
|
|
115858
116204
|
try {
|
|
115859
|
-
const content = readFileSync3(
|
|
116205
|
+
const content = readFileSync3(join10(this.basePath, file), "utf-8");
|
|
115860
116206
|
const session = JSON.parse(content);
|
|
115861
116207
|
if (session.parentSessionId === parentSessionId) {
|
|
115862
116208
|
sessions.push(session);
|
|
@@ -115872,7 +116218,7 @@ class VerificationSessionStore {
|
|
|
115872
116218
|
const files = this.listFiles();
|
|
115873
116219
|
for (const file of files) {
|
|
115874
116220
|
try {
|
|
115875
|
-
const content = readFileSync3(
|
|
116221
|
+
const content = readFileSync3(join10(this.basePath, file), "utf-8");
|
|
115876
116222
|
const session = JSON.parse(content);
|
|
115877
116223
|
sessions.push(session);
|
|
115878
116224
|
} catch {
|
|
@@ -115902,7 +116248,7 @@ class VerificationSessionStore {
|
|
|
115902
116248
|
const sessions = [];
|
|
115903
116249
|
for (const file of files) {
|
|
115904
116250
|
try {
|
|
115905
|
-
const content = readFileSync3(
|
|
116251
|
+
const content = readFileSync3(join10(this.basePath, file), "utf-8");
|
|
115906
116252
|
const session = JSON.parse(content);
|
|
115907
116253
|
sessions.push({
|
|
115908
116254
|
file,
|
|
@@ -115917,7 +116263,7 @@ class VerificationSessionStore {
|
|
|
115917
116263
|
for (const item of toRemove) {
|
|
115918
116264
|
try {
|
|
115919
116265
|
const { unlinkSync: unlinkSync2 } = __require("fs");
|
|
115920
|
-
unlinkSync2(
|
|
116266
|
+
unlinkSync2(join10(this.basePath, item.file));
|
|
115921
116267
|
} catch {
|
|
115922
116268
|
continue;
|
|
115923
116269
|
}
|
|
@@ -115928,7 +116274,7 @@ class VerificationSessionStore {
|
|
|
115928
116274
|
for (const file of files) {
|
|
115929
116275
|
try {
|
|
115930
116276
|
const { unlinkSync: unlinkSync2 } = __require("fs");
|
|
115931
|
-
unlinkSync2(
|
|
116277
|
+
unlinkSync2(join10(this.basePath, file));
|
|
115932
116278
|
} catch {
|
|
115933
116279
|
continue;
|
|
115934
116280
|
}
|
|
@@ -116081,7 +116427,7 @@ function createScopeVerificationHook() {
|
|
|
116081
116427
|
}
|
|
116082
116428
|
// packages/core/src/commands/loader.ts
|
|
116083
116429
|
import { existsSync as existsSync7, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
|
|
116084
|
-
import { join as
|
|
116430
|
+
import { join as join11, basename as basename2, extname as extname2 } from "path";
|
|
116085
116431
|
import { homedir as homedir8 } from "os";
|
|
116086
116432
|
|
|
116087
116433
|
class CommandLoader {
|
|
@@ -116094,9 +116440,9 @@ class CommandLoader {
|
|
|
116094
116440
|
this.commands.clear();
|
|
116095
116441
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
116096
116442
|
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir8();
|
|
116097
|
-
const globalDir =
|
|
116443
|
+
const globalDir = join11(homeDir, ".assistants", "commands");
|
|
116098
116444
|
await this.loadFromDirectory(globalDir, "global");
|
|
116099
|
-
const projectDir =
|
|
116445
|
+
const projectDir = join11(this.cwd, ".assistants", "commands");
|
|
116100
116446
|
await this.loadFromDirectory(projectDir, "project");
|
|
116101
116447
|
}
|
|
116102
116448
|
async loadFromDirectory(dir, source, prefix = "") {
|
|
@@ -116104,12 +116450,12 @@ class CommandLoader {
|
|
|
116104
116450
|
return;
|
|
116105
116451
|
const entries = readdirSync3(dir);
|
|
116106
116452
|
for (const entry of entries) {
|
|
116107
|
-
const fullPath =
|
|
116108
|
-
const
|
|
116109
|
-
if (
|
|
116453
|
+
const fullPath = join11(dir, entry);
|
|
116454
|
+
const stat2 = statSync2(fullPath);
|
|
116455
|
+
if (stat2.isDirectory()) {
|
|
116110
116456
|
const newPrefix = prefix ? `${prefix}:${entry}` : entry;
|
|
116111
116457
|
await this.loadFromDirectory(fullPath, source, newPrefix);
|
|
116112
|
-
} else if (
|
|
116458
|
+
} else if (stat2.isFile() && extname2(entry) === ".md") {
|
|
116113
116459
|
const command = await this.loadCommandFile(fullPath, prefix);
|
|
116114
116460
|
if (command) {
|
|
116115
116461
|
this.commands.set(command.name, command);
|
|
@@ -116340,18 +116686,18 @@ ${stderr}`;
|
|
|
116340
116686
|
}
|
|
116341
116687
|
}
|
|
116342
116688
|
// packages/core/src/commands/builtin.ts
|
|
116343
|
-
import { join as
|
|
116689
|
+
import { join as join15 } from "path";
|
|
116344
116690
|
import { homedir as homedir10, platform as platform2, release, arch } from "os";
|
|
116345
116691
|
import { existsSync as existsSync8, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
116346
116692
|
init_src();
|
|
116347
116693
|
|
|
116348
116694
|
// packages/core/src/projects/store.ts
|
|
116349
116695
|
init_src();
|
|
116350
|
-
import { join as
|
|
116351
|
-
import { mkdir as
|
|
116696
|
+
import { join as join12 } from "path";
|
|
116697
|
+
import { mkdir as mkdir4, readdir as readdir2, readFile as readFile2, unlink as unlink2, writeFile as writeFile3 } from "fs/promises";
|
|
116352
116698
|
var SAFE_ID_PATTERN2 = /^[a-zA-Z0-9_-]+$/;
|
|
116353
116699
|
function projectsDir(cwd2) {
|
|
116354
|
-
return
|
|
116700
|
+
return join12(cwd2, ".assistants", "projects");
|
|
116355
116701
|
}
|
|
116356
116702
|
function isSafeId2(id) {
|
|
116357
116703
|
return SAFE_ID_PATTERN2.test(id);
|
|
@@ -116359,12 +116705,12 @@ function isSafeId2(id) {
|
|
|
116359
116705
|
function projectPath(cwd2, id) {
|
|
116360
116706
|
if (!isSafeId2(id))
|
|
116361
116707
|
return null;
|
|
116362
|
-
return
|
|
116708
|
+
return join12(projectsDir(cwd2), `${id}.json`);
|
|
116363
116709
|
}
|
|
116364
116710
|
async function ensureProjectsDir(cwd2) {
|
|
116365
|
-
await
|
|
116711
|
+
await mkdir4(projectsDir(cwd2), { recursive: true });
|
|
116366
116712
|
}
|
|
116367
|
-
function
|
|
116713
|
+
function normalizeName2(name) {
|
|
116368
116714
|
return name.trim().toLowerCase();
|
|
116369
116715
|
}
|
|
116370
116716
|
async function listProjects(cwd2) {
|
|
@@ -116376,7 +116722,7 @@ async function listProjects(cwd2) {
|
|
|
116376
116722
|
if (!file.endsWith(".json"))
|
|
116377
116723
|
continue;
|
|
116378
116724
|
try {
|
|
116379
|
-
const raw = await readFile2(
|
|
116725
|
+
const raw = await readFile2(join12(dir, file), "utf-8");
|
|
116380
116726
|
const parsed = JSON.parse(raw);
|
|
116381
116727
|
if (parsed?.id && parsed?.name) {
|
|
116382
116728
|
projects.push(parsed);
|
|
@@ -116403,9 +116749,9 @@ async function readProject(cwd2, id) {
|
|
|
116403
116749
|
}
|
|
116404
116750
|
}
|
|
116405
116751
|
async function findProjectByName(cwd2, name) {
|
|
116406
|
-
const normalized =
|
|
116752
|
+
const normalized = normalizeName2(name);
|
|
116407
116753
|
const projects = await listProjects(cwd2);
|
|
116408
|
-
return projects.find((project) =>
|
|
116754
|
+
return projects.find((project) => normalizeName2(project.name) === normalized) || null;
|
|
116409
116755
|
}
|
|
116410
116756
|
async function saveProject(cwd2, project) {
|
|
116411
116757
|
await ensureProjectsDir(cwd2);
|
|
@@ -116413,7 +116759,7 @@ async function saveProject(cwd2, project) {
|
|
|
116413
116759
|
if (!path) {
|
|
116414
116760
|
throw new Error(`Invalid project id: ${project.id}`);
|
|
116415
116761
|
}
|
|
116416
|
-
await
|
|
116762
|
+
await writeFile3(path, JSON.stringify(project, null, 2), "utf-8");
|
|
116417
116763
|
}
|
|
116418
116764
|
async function deleteProject(cwd2, id) {
|
|
116419
116765
|
try {
|
|
@@ -116455,14 +116801,14 @@ async function ensureDefaultProject(cwd2) {
|
|
|
116455
116801
|
return createProject(cwd2, "default", "Default project for this folder");
|
|
116456
116802
|
}
|
|
116457
116803
|
function hasProjectNameConflict(projects, name) {
|
|
116458
|
-
const normalized =
|
|
116459
|
-
return projects.some((project) =>
|
|
116804
|
+
const normalized = normalizeName2(name);
|
|
116805
|
+
return projects.some((project) => normalizeName2(project.name) === normalized);
|
|
116460
116806
|
}
|
|
116461
116807
|
|
|
116462
116808
|
// packages/core/src/projects/context.ts
|
|
116463
116809
|
import { readFile as readFile3 } from "fs/promises";
|
|
116464
116810
|
import { homedir as homedir9 } from "os";
|
|
116465
|
-
import { resolve as resolve4, join as
|
|
116811
|
+
import { resolve as resolve4, join as join13 } from "path";
|
|
116466
116812
|
var DEFAULT_MAX_FILE_BYTES = 12000;
|
|
116467
116813
|
function singleLine(value) {
|
|
116468
116814
|
return value.replace(/[\r\n]+/g, " ").trim();
|
|
@@ -116481,7 +116827,7 @@ function normalizeEntryLabel(entry) {
|
|
|
116481
116827
|
}
|
|
116482
116828
|
async function renderFileEntry(entry, options) {
|
|
116483
116829
|
const rawPath = entry.value.trim();
|
|
116484
|
-
const expandedPath = rawPath === "~" ? homedir9() : rawPath.startsWith("~/") ?
|
|
116830
|
+
const expandedPath = rawPath === "~" ? homedir9() : rawPath.startsWith("~/") ? join13(homedir9(), rawPath.slice(2)) : rawPath;
|
|
116485
116831
|
const resolved = resolve4(options.cwd, expandedPath);
|
|
116486
116832
|
const validation = await validatePath(resolved, { allowedPaths: [options.cwd] });
|
|
116487
116833
|
if (!validation.valid) {
|
|
@@ -116567,7 +116913,617 @@ async function buildProjectContext(project, options) {
|
|
|
116567
116913
|
return lines.join(`
|
|
116568
116914
|
`);
|
|
116569
116915
|
}
|
|
116916
|
+
// packages/core/src/jobs/job-manager.ts
|
|
116917
|
+
init_src();
|
|
116918
|
+
|
|
116919
|
+
// packages/core/src/jobs/job-store.ts
|
|
116920
|
+
import { join as join14 } from "path";
|
|
116921
|
+
import { mkdir as mkdir5, readdir as readdir3, readFile as readFile4, unlink as unlink3, writeFile as writeFile4 } from "fs/promises";
|
|
116922
|
+
var SAFE_ID_PATTERN3 = /^[a-zA-Z0-9_-]+$/;
|
|
116923
|
+
function jobsDir() {
|
|
116924
|
+
return join14(getConfigDir(), "jobs");
|
|
116925
|
+
}
|
|
116926
|
+
function isSafeId3(id) {
|
|
116927
|
+
return SAFE_ID_PATTERN3.test(id);
|
|
116928
|
+
}
|
|
116929
|
+
function jobPath(id) {
|
|
116930
|
+
if (!isSafeId3(id))
|
|
116931
|
+
return null;
|
|
116932
|
+
return join14(jobsDir(), `${id}.json`);
|
|
116933
|
+
}
|
|
116934
|
+
async function ensureDir() {
|
|
116935
|
+
await mkdir5(jobsDir(), { recursive: true });
|
|
116936
|
+
}
|
|
116937
|
+
async function saveJob(job) {
|
|
116938
|
+
await ensureDir();
|
|
116939
|
+
const path = jobPath(job.id);
|
|
116940
|
+
if (!path) {
|
|
116941
|
+
throw new Error(`Invalid job id: ${job.id}`);
|
|
116942
|
+
}
|
|
116943
|
+
await writeFile4(path, JSON.stringify(job, null, 2), "utf-8");
|
|
116944
|
+
}
|
|
116945
|
+
async function readJob(id) {
|
|
116946
|
+
try {
|
|
116947
|
+
const path = jobPath(id);
|
|
116948
|
+
if (!path)
|
|
116949
|
+
return null;
|
|
116950
|
+
const raw = await readFile4(path, "utf-8");
|
|
116951
|
+
const job = JSON.parse(raw);
|
|
116952
|
+
if (!job?.id)
|
|
116953
|
+
return null;
|
|
116954
|
+
return job;
|
|
116955
|
+
} catch {
|
|
116956
|
+
return null;
|
|
116957
|
+
}
|
|
116958
|
+
}
|
|
116959
|
+
async function deleteJob(id) {
|
|
116960
|
+
try {
|
|
116961
|
+
const path = jobPath(id);
|
|
116962
|
+
if (!path)
|
|
116963
|
+
return false;
|
|
116964
|
+
await unlink3(path);
|
|
116965
|
+
return true;
|
|
116966
|
+
} catch {
|
|
116967
|
+
return false;
|
|
116968
|
+
}
|
|
116969
|
+
}
|
|
116970
|
+
async function listJobs() {
|
|
116971
|
+
try {
|
|
116972
|
+
const dir = jobsDir();
|
|
116973
|
+
const files = await readdir3(dir);
|
|
116974
|
+
const jobs = [];
|
|
116975
|
+
for (const file of files) {
|
|
116976
|
+
if (!file.endsWith(".json"))
|
|
116977
|
+
continue;
|
|
116978
|
+
try {
|
|
116979
|
+
const raw = await readFile4(join14(dir, file), "utf-8");
|
|
116980
|
+
const job = JSON.parse(raw);
|
|
116981
|
+
if (job?.id)
|
|
116982
|
+
jobs.push(job);
|
|
116983
|
+
} catch {}
|
|
116984
|
+
}
|
|
116985
|
+
return jobs;
|
|
116986
|
+
} catch {
|
|
116987
|
+
return [];
|
|
116988
|
+
}
|
|
116989
|
+
}
|
|
116990
|
+
async function listJobsForSession(sessionId) {
|
|
116991
|
+
const jobs = await listJobs();
|
|
116992
|
+
return jobs.filter((job) => job.sessionId === sessionId);
|
|
116993
|
+
}
|
|
116994
|
+
async function listJobsByStatus(status) {
|
|
116995
|
+
const jobs = await listJobs();
|
|
116996
|
+
return jobs.filter((job) => job.status === status);
|
|
116997
|
+
}
|
|
116998
|
+
async function updateJob(id, updater) {
|
|
116999
|
+
const job = await readJob(id);
|
|
117000
|
+
if (!job)
|
|
117001
|
+
return null;
|
|
117002
|
+
const updated = updater(job);
|
|
117003
|
+
await saveJob(updated);
|
|
117004
|
+
return updated;
|
|
117005
|
+
}
|
|
117006
|
+
async function cleanupOldJobs(maxAgeMs) {
|
|
117007
|
+
const jobs = await listJobs();
|
|
117008
|
+
const now2 = Date.now();
|
|
117009
|
+
let cleaned = 0;
|
|
117010
|
+
for (const job of jobs) {
|
|
117011
|
+
if (["completed", "failed", "timeout", "cancelled"].includes(job.status) && now2 - job.createdAt > maxAgeMs) {
|
|
117012
|
+
const deleted = await deleteJob(job.id);
|
|
117013
|
+
if (deleted)
|
|
117014
|
+
cleaned++;
|
|
117015
|
+
}
|
|
117016
|
+
}
|
|
117017
|
+
return cleaned;
|
|
117018
|
+
}
|
|
117019
|
+
async function cleanupSessionJobs(sessionId) {
|
|
117020
|
+
const jobs = await listJobsForSession(sessionId);
|
|
117021
|
+
let cleaned = 0;
|
|
117022
|
+
for (const job of jobs) {
|
|
117023
|
+
if (["completed", "failed", "timeout", "cancelled"].includes(job.status)) {
|
|
117024
|
+
const deleted = await deleteJob(job.id);
|
|
117025
|
+
if (deleted)
|
|
117026
|
+
cleaned++;
|
|
117027
|
+
}
|
|
117028
|
+
}
|
|
117029
|
+
return cleaned;
|
|
117030
|
+
}
|
|
116570
117031
|
|
|
117032
|
+
// packages/core/src/jobs/job-manager.ts
|
|
117033
|
+
init_codes();
|
|
117034
|
+
var DEFAULT_TIMEOUT_MS = 60000;
|
|
117035
|
+
var DEFAULT_MAX_JOB_AGE_MS = 24 * 60 * 60 * 1000;
|
|
117036
|
+
|
|
117037
|
+
class JobManager {
|
|
117038
|
+
config;
|
|
117039
|
+
sessionId;
|
|
117040
|
+
runningJobs = new Map;
|
|
117041
|
+
timedOutJobs = new Set;
|
|
117042
|
+
cancelledJobs = new Set;
|
|
117043
|
+
completionCallbacks = [];
|
|
117044
|
+
constructor(config = {}, sessionId) {
|
|
117045
|
+
this.config = config;
|
|
117046
|
+
this.sessionId = sessionId;
|
|
117047
|
+
}
|
|
117048
|
+
onJobComplete(callback) {
|
|
117049
|
+
this.completionCallbacks.push(callback);
|
|
117050
|
+
}
|
|
117051
|
+
isEnabled() {
|
|
117052
|
+
return this.config.enabled !== false;
|
|
117053
|
+
}
|
|
117054
|
+
shouldRunAsync(connectorName, input) {
|
|
117055
|
+
if (!this.isEnabled())
|
|
117056
|
+
return false;
|
|
117057
|
+
if (input.async === false)
|
|
117058
|
+
return false;
|
|
117059
|
+
if (input.async === true)
|
|
117060
|
+
return true;
|
|
117061
|
+
const connectorConfig = this.config.connectors?.[connectorName];
|
|
117062
|
+
return connectorConfig?.enabled === true;
|
|
117063
|
+
}
|
|
117064
|
+
getTimeout(connectorName) {
|
|
117065
|
+
const connectorConfig = this.config.connectors?.[connectorName];
|
|
117066
|
+
return connectorConfig?.timeoutMs ?? this.config.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
117067
|
+
}
|
|
117068
|
+
async startJob(connectorName, command, input, cli) {
|
|
117069
|
+
const jobId = generateId();
|
|
117070
|
+
const timeoutMs = this.getTimeout(connectorName);
|
|
117071
|
+
const now2 = Date.now();
|
|
117072
|
+
const job = {
|
|
117073
|
+
id: jobId,
|
|
117074
|
+
sessionId: this.sessionId,
|
|
117075
|
+
connectorName,
|
|
117076
|
+
command,
|
|
117077
|
+
input,
|
|
117078
|
+
status: "pending",
|
|
117079
|
+
createdAt: now2,
|
|
117080
|
+
timeoutMs
|
|
117081
|
+
};
|
|
117082
|
+
await saveJob(job);
|
|
117083
|
+
this.executeAsync(job, cli);
|
|
117084
|
+
return job;
|
|
117085
|
+
}
|
|
117086
|
+
async executeAsync(job, cli) {
|
|
117087
|
+
const runningJob = await updateJob(job.id, (j) => ({
|
|
117088
|
+
...j,
|
|
117089
|
+
status: "running",
|
|
117090
|
+
startedAt: Date.now()
|
|
117091
|
+
}));
|
|
117092
|
+
if (!runningJob)
|
|
117093
|
+
return;
|
|
117094
|
+
const args = job.input.args || [];
|
|
117095
|
+
const options = job.input.options || {};
|
|
117096
|
+
const cwd2 = typeof job.input.cwd === "string" ? job.input.cwd : process.cwd();
|
|
117097
|
+
const cmdParts = [cli, ...job.command.split(" "), ...args];
|
|
117098
|
+
for (const [key, value] of Object.entries(options)) {
|
|
117099
|
+
if (key === "timeoutMs" || key === "timeout" || key === "async")
|
|
117100
|
+
continue;
|
|
117101
|
+
if (value === true) {
|
|
117102
|
+
cmdParts.push(`--${key}`);
|
|
117103
|
+
} else if (value !== false && value !== undefined) {
|
|
117104
|
+
cmdParts.push(`--${key}`, String(value));
|
|
117105
|
+
}
|
|
117106
|
+
}
|
|
117107
|
+
try {
|
|
117108
|
+
const proc = Bun.spawn(cmdParts, {
|
|
117109
|
+
cwd: cwd2,
|
|
117110
|
+
stdin: "ignore",
|
|
117111
|
+
stdout: "pipe",
|
|
117112
|
+
stderr: "pipe"
|
|
117113
|
+
});
|
|
117114
|
+
const timer = setTimeout(() => {
|
|
117115
|
+
this.handleTimeout(job.id, proc);
|
|
117116
|
+
}, job.timeoutMs);
|
|
117117
|
+
this.runningJobs.set(job.id, { proc, timer });
|
|
117118
|
+
const [stdout, stderr] = await Promise.all([
|
|
117119
|
+
new Response(proc.stdout).text(),
|
|
117120
|
+
new Response(proc.stderr).text()
|
|
117121
|
+
]);
|
|
117122
|
+
const exitCode = await proc.exited;
|
|
117123
|
+
clearTimeout(timer);
|
|
117124
|
+
this.runningJobs.delete(job.id);
|
|
117125
|
+
if (this.timedOutJobs.has(job.id)) {
|
|
117126
|
+
this.timedOutJobs.delete(job.id);
|
|
117127
|
+
return;
|
|
117128
|
+
}
|
|
117129
|
+
if (this.cancelledJobs.has(job.id)) {
|
|
117130
|
+
this.cancelledJobs.delete(job.id);
|
|
117131
|
+
return;
|
|
117132
|
+
}
|
|
117133
|
+
const currentJob = await readJob(job.id);
|
|
117134
|
+
if (!currentJob || currentJob.status === "cancelled") {
|
|
117135
|
+
return;
|
|
117136
|
+
}
|
|
117137
|
+
const completedJob = await updateJob(job.id, (j) => ({
|
|
117138
|
+
...j,
|
|
117139
|
+
status: exitCode === 0 ? "completed" : "failed",
|
|
117140
|
+
completedAt: Date.now(),
|
|
117141
|
+
result: {
|
|
117142
|
+
content: stdout.trim() || stderr.trim() || "Command completed",
|
|
117143
|
+
exitCode
|
|
117144
|
+
},
|
|
117145
|
+
error: exitCode !== 0 ? {
|
|
117146
|
+
code: ErrorCodes.CONNECTOR_EXECUTION_FAILED,
|
|
117147
|
+
message: stderr.trim() || `Exit code: ${exitCode}`
|
|
117148
|
+
} : undefined
|
|
117149
|
+
}));
|
|
117150
|
+
if (completedJob) {
|
|
117151
|
+
this.notifyCompletion(completedJob);
|
|
117152
|
+
}
|
|
117153
|
+
} catch (error) {
|
|
117154
|
+
const running = this.runningJobs.get(job.id);
|
|
117155
|
+
if (running) {
|
|
117156
|
+
clearTimeout(running.timer);
|
|
117157
|
+
this.runningJobs.delete(job.id);
|
|
117158
|
+
}
|
|
117159
|
+
if (this.timedOutJobs.has(job.id)) {
|
|
117160
|
+
this.timedOutJobs.delete(job.id);
|
|
117161
|
+
return;
|
|
117162
|
+
}
|
|
117163
|
+
if (this.cancelledJobs.has(job.id)) {
|
|
117164
|
+
this.cancelledJobs.delete(job.id);
|
|
117165
|
+
return;
|
|
117166
|
+
}
|
|
117167
|
+
const failedJob = await updateJob(job.id, (j) => ({
|
|
117168
|
+
...j,
|
|
117169
|
+
status: "failed",
|
|
117170
|
+
completedAt: Date.now(),
|
|
117171
|
+
error: {
|
|
117172
|
+
code: ErrorCodes.CONNECTOR_EXECUTION_FAILED,
|
|
117173
|
+
message: error instanceof Error ? error.message : String(error)
|
|
117174
|
+
}
|
|
117175
|
+
}));
|
|
117176
|
+
if (failedJob) {
|
|
117177
|
+
this.notifyCompletion(failedJob);
|
|
117178
|
+
}
|
|
117179
|
+
}
|
|
117180
|
+
}
|
|
117181
|
+
async handleTimeout(jobId, proc) {
|
|
117182
|
+
this.timedOutJobs.add(jobId);
|
|
117183
|
+
try {
|
|
117184
|
+
proc.kill();
|
|
117185
|
+
} catch {}
|
|
117186
|
+
this.runningJobs.delete(jobId);
|
|
117187
|
+
const job = await readJob(jobId);
|
|
117188
|
+
if (!job)
|
|
117189
|
+
return;
|
|
117190
|
+
const timedOutJob = await updateJob(jobId, (j) => ({
|
|
117191
|
+
...j,
|
|
117192
|
+
status: "timeout",
|
|
117193
|
+
completedAt: Date.now(),
|
|
117194
|
+
error: {
|
|
117195
|
+
code: "JOB_TIMEOUT",
|
|
117196
|
+
message: `Job timed out after ${Math.round(j.timeoutMs / 1000)} seconds`
|
|
117197
|
+
}
|
|
117198
|
+
}));
|
|
117199
|
+
if (timedOutJob) {
|
|
117200
|
+
this.notifyCompletion(timedOutJob);
|
|
117201
|
+
}
|
|
117202
|
+
}
|
|
117203
|
+
notifyCompletion(job) {
|
|
117204
|
+
const event = {
|
|
117205
|
+
jobId: job.id,
|
|
117206
|
+
status: job.status,
|
|
117207
|
+
connector: job.connectorName,
|
|
117208
|
+
summary: job.result?.content?.slice(0, 200) || job.error?.message || "Job completed"
|
|
117209
|
+
};
|
|
117210
|
+
for (const callback of this.completionCallbacks) {
|
|
117211
|
+
try {
|
|
117212
|
+
callback(event);
|
|
117213
|
+
} catch {}
|
|
117214
|
+
}
|
|
117215
|
+
}
|
|
117216
|
+
async getJobStatus(jobId) {
|
|
117217
|
+
return readJob(jobId);
|
|
117218
|
+
}
|
|
117219
|
+
async getJobResult(jobId, waitMs) {
|
|
117220
|
+
const job = await readJob(jobId);
|
|
117221
|
+
if (!job)
|
|
117222
|
+
return null;
|
|
117223
|
+
if (["completed", "failed", "timeout", "cancelled"].includes(job.status)) {
|
|
117224
|
+
return job;
|
|
117225
|
+
}
|
|
117226
|
+
if (!waitMs || waitMs <= 0) {
|
|
117227
|
+
return job;
|
|
117228
|
+
}
|
|
117229
|
+
const startTime = Date.now();
|
|
117230
|
+
const pollInterval = 500;
|
|
117231
|
+
while (Date.now() - startTime < waitMs) {
|
|
117232
|
+
await new Promise((resolve5) => setTimeout(resolve5, pollInterval));
|
|
117233
|
+
const currentJob = await readJob(jobId);
|
|
117234
|
+
if (!currentJob)
|
|
117235
|
+
return null;
|
|
117236
|
+
if (["completed", "failed", "timeout", "cancelled"].includes(currentJob.status)) {
|
|
117237
|
+
return currentJob;
|
|
117238
|
+
}
|
|
117239
|
+
}
|
|
117240
|
+
return readJob(jobId);
|
|
117241
|
+
}
|
|
117242
|
+
async cancelJob(jobId) {
|
|
117243
|
+
const job = await readJob(jobId);
|
|
117244
|
+
if (!job)
|
|
117245
|
+
return false;
|
|
117246
|
+
if (!["pending", "running"].includes(job.status)) {
|
|
117247
|
+
return false;
|
|
117248
|
+
}
|
|
117249
|
+
this.cancelledJobs.add(jobId);
|
|
117250
|
+
const running = this.runningJobs.get(jobId);
|
|
117251
|
+
if (running) {
|
|
117252
|
+
clearTimeout(running.timer);
|
|
117253
|
+
try {
|
|
117254
|
+
running.proc.kill();
|
|
117255
|
+
} catch {}
|
|
117256
|
+
this.runningJobs.delete(jobId);
|
|
117257
|
+
}
|
|
117258
|
+
const cancelled = await updateJob(jobId, (j) => ({
|
|
117259
|
+
...j,
|
|
117260
|
+
status: "cancelled",
|
|
117261
|
+
completedAt: Date.now(),
|
|
117262
|
+
error: {
|
|
117263
|
+
code: "JOB_CANCELLED",
|
|
117264
|
+
message: "Job was cancelled by user"
|
|
117265
|
+
}
|
|
117266
|
+
}));
|
|
117267
|
+
if (cancelled) {
|
|
117268
|
+
this.notifyCompletion(cancelled);
|
|
117269
|
+
}
|
|
117270
|
+
return cancelled !== null;
|
|
117271
|
+
}
|
|
117272
|
+
async listSessionJobs() {
|
|
117273
|
+
return listJobsForSession(this.sessionId);
|
|
117274
|
+
}
|
|
117275
|
+
async listRunningJobs() {
|
|
117276
|
+
return listJobsByStatus("running");
|
|
117277
|
+
}
|
|
117278
|
+
async cleanup() {
|
|
117279
|
+
const maxAge = this.config.maxJobAgeMs ?? DEFAULT_MAX_JOB_AGE_MS;
|
|
117280
|
+
return cleanupOldJobs(maxAge);
|
|
117281
|
+
}
|
|
117282
|
+
async shutdown() {
|
|
117283
|
+
for (const [jobId, running] of this.runningJobs) {
|
|
117284
|
+
this.cancelledJobs.add(jobId);
|
|
117285
|
+
clearTimeout(running.timer);
|
|
117286
|
+
try {
|
|
117287
|
+
running.proc.kill();
|
|
117288
|
+
} catch {}
|
|
117289
|
+
await updateJob(jobId, (j) => ({
|
|
117290
|
+
...j,
|
|
117291
|
+
status: "cancelled",
|
|
117292
|
+
completedAt: Date.now(),
|
|
117293
|
+
error: {
|
|
117294
|
+
code: "JOB_CANCELLED",
|
|
117295
|
+
message: "Job was cancelled due to session shutdown"
|
|
117296
|
+
}
|
|
117297
|
+
}));
|
|
117298
|
+
}
|
|
117299
|
+
this.runningJobs.clear();
|
|
117300
|
+
}
|
|
117301
|
+
}
|
|
117302
|
+
// packages/core/src/jobs/tools.ts
|
|
117303
|
+
function createJobTools(getJobManager) {
|
|
117304
|
+
return [
|
|
117305
|
+
{
|
|
117306
|
+
tool: jobStatusTool,
|
|
117307
|
+
executor: createJobStatusExecutor(getJobManager)
|
|
117308
|
+
},
|
|
117309
|
+
{
|
|
117310
|
+
tool: jobResultTool,
|
|
117311
|
+
executor: createJobResultExecutor(getJobManager)
|
|
117312
|
+
},
|
|
117313
|
+
{
|
|
117314
|
+
tool: jobCancelTool,
|
|
117315
|
+
executor: createJobCancelExecutor(getJobManager)
|
|
117316
|
+
},
|
|
117317
|
+
{
|
|
117318
|
+
tool: jobListTool,
|
|
117319
|
+
executor: createJobListExecutor(getJobManager)
|
|
117320
|
+
}
|
|
117321
|
+
];
|
|
117322
|
+
}
|
|
117323
|
+
var jobStatusTool = {
|
|
117324
|
+
name: "job_status",
|
|
117325
|
+
description: "Check the status of a background job. Returns the current status (pending, running, completed, failed, timeout, cancelled) and any available result or error.",
|
|
117326
|
+
parameters: {
|
|
117327
|
+
type: "object",
|
|
117328
|
+
properties: {
|
|
117329
|
+
job_id: {
|
|
117330
|
+
type: "string",
|
|
117331
|
+
description: "The ID of the job to check"
|
|
117332
|
+
}
|
|
117333
|
+
},
|
|
117334
|
+
required: ["job_id"]
|
|
117335
|
+
}
|
|
117336
|
+
};
|
|
117337
|
+
function createJobStatusExecutor(getJobManager) {
|
|
117338
|
+
return async (input) => {
|
|
117339
|
+
const manager = getJobManager();
|
|
117340
|
+
if (!manager) {
|
|
117341
|
+
return "Jobs system is not enabled";
|
|
117342
|
+
}
|
|
117343
|
+
const jobId = input.job_id;
|
|
117344
|
+
if (!jobId) {
|
|
117345
|
+
return "Error: job_id is required";
|
|
117346
|
+
}
|
|
117347
|
+
const job = await manager.getJobStatus(jobId);
|
|
117348
|
+
if (!job) {
|
|
117349
|
+
return `Job not found: ${jobId}`;
|
|
117350
|
+
}
|
|
117351
|
+
const parts = [
|
|
117352
|
+
`Job ID: ${job.id}`,
|
|
117353
|
+
`Status: ${job.status}`,
|
|
117354
|
+
`Connector: ${job.connectorName}`,
|
|
117355
|
+
`Command: ${job.command}`,
|
|
117356
|
+
`Created: ${new Date(job.createdAt).toISOString()}`
|
|
117357
|
+
];
|
|
117358
|
+
if (job.startedAt) {
|
|
117359
|
+
parts.push(`Started: ${new Date(job.startedAt).toISOString()}`);
|
|
117360
|
+
}
|
|
117361
|
+
if (job.completedAt) {
|
|
117362
|
+
parts.push(`Completed: ${new Date(job.completedAt).toISOString()}`);
|
|
117363
|
+
const duration = job.completedAt - (job.startedAt || job.createdAt);
|
|
117364
|
+
parts.push(`Duration: ${(duration / 1000).toFixed(1)}s`);
|
|
117365
|
+
}
|
|
117366
|
+
if (job.status === "running") {
|
|
117367
|
+
const elapsed = Date.now() - (job.startedAt || job.createdAt);
|
|
117368
|
+
const remaining = job.timeoutMs - elapsed;
|
|
117369
|
+
parts.push(`Elapsed: ${(elapsed / 1000).toFixed(1)}s`);
|
|
117370
|
+
parts.push(`Timeout in: ${Math.max(0, remaining / 1000).toFixed(1)}s`);
|
|
117371
|
+
}
|
|
117372
|
+
if (job.result) {
|
|
117373
|
+
parts.push(`
|
|
117374
|
+
Result:
|
|
117375
|
+
${job.result.content}`);
|
|
117376
|
+
}
|
|
117377
|
+
if (job.error) {
|
|
117378
|
+
parts.push(`
|
|
117379
|
+
Error (${job.error.code}): ${job.error.message}`);
|
|
117380
|
+
}
|
|
117381
|
+
return parts.join(`
|
|
117382
|
+
`);
|
|
117383
|
+
};
|
|
117384
|
+
}
|
|
117385
|
+
var jobResultTool = {
|
|
117386
|
+
name: "job_result",
|
|
117387
|
+
description: "Get the result of a background job. Optionally wait up to 30 seconds for the job to complete if still running.",
|
|
117388
|
+
parameters: {
|
|
117389
|
+
type: "object",
|
|
117390
|
+
properties: {
|
|
117391
|
+
job_id: {
|
|
117392
|
+
type: "string",
|
|
117393
|
+
description: "The ID of the job to get results from"
|
|
117394
|
+
},
|
|
117395
|
+
wait: {
|
|
117396
|
+
type: "boolean",
|
|
117397
|
+
description: "Whether to wait up to 30 seconds for the job to complete (default: false)",
|
|
117398
|
+
default: false
|
|
117399
|
+
}
|
|
117400
|
+
},
|
|
117401
|
+
required: ["job_id"]
|
|
117402
|
+
}
|
|
117403
|
+
};
|
|
117404
|
+
function createJobResultExecutor(getJobManager) {
|
|
117405
|
+
return async (input) => {
|
|
117406
|
+
const manager = getJobManager();
|
|
117407
|
+
if (!manager) {
|
|
117408
|
+
return "Jobs system is not enabled";
|
|
117409
|
+
}
|
|
117410
|
+
const jobId = input.job_id;
|
|
117411
|
+
if (!jobId) {
|
|
117412
|
+
return "Error: job_id is required";
|
|
117413
|
+
}
|
|
117414
|
+
const wait = input.wait === true;
|
|
117415
|
+
const waitMs = wait ? 30000 : 0;
|
|
117416
|
+
const job = await manager.getJobResult(jobId, waitMs);
|
|
117417
|
+
if (!job) {
|
|
117418
|
+
return `Job not found: ${jobId}`;
|
|
117419
|
+
}
|
|
117420
|
+
if (job.status === "pending" || job.status === "running") {
|
|
117421
|
+
return `Job is still ${job.status}. Use job_status to monitor or job_result with wait=true to wait for completion.`;
|
|
117422
|
+
}
|
|
117423
|
+
if (job.status === "completed" && job.result) {
|
|
117424
|
+
return job.result.content;
|
|
117425
|
+
}
|
|
117426
|
+
if (job.error) {
|
|
117427
|
+
return `Job ${job.status}: ${job.error.message}`;
|
|
117428
|
+
}
|
|
117429
|
+
return `Job ${job.status}`;
|
|
117430
|
+
};
|
|
117431
|
+
}
|
|
117432
|
+
var jobCancelTool = {
|
|
117433
|
+
name: "job_cancel",
|
|
117434
|
+
description: "Cancel a running or pending background job.",
|
|
117435
|
+
parameters: {
|
|
117436
|
+
type: "object",
|
|
117437
|
+
properties: {
|
|
117438
|
+
job_id: {
|
|
117439
|
+
type: "string",
|
|
117440
|
+
description: "The ID of the job to cancel"
|
|
117441
|
+
}
|
|
117442
|
+
},
|
|
117443
|
+
required: ["job_id"]
|
|
117444
|
+
}
|
|
117445
|
+
};
|
|
117446
|
+
function createJobCancelExecutor(getJobManager) {
|
|
117447
|
+
return async (input) => {
|
|
117448
|
+
const manager = getJobManager();
|
|
117449
|
+
if (!manager) {
|
|
117450
|
+
return "Jobs system is not enabled";
|
|
117451
|
+
}
|
|
117452
|
+
const jobId = input.job_id;
|
|
117453
|
+
if (!jobId) {
|
|
117454
|
+
return "Error: job_id is required";
|
|
117455
|
+
}
|
|
117456
|
+
const cancelled = await manager.cancelJob(jobId);
|
|
117457
|
+
if (cancelled) {
|
|
117458
|
+
return `Job ${jobId} has been cancelled`;
|
|
117459
|
+
}
|
|
117460
|
+
const job = await readJob(jobId);
|
|
117461
|
+
if (!job) {
|
|
117462
|
+
return `Job not found: ${jobId}`;
|
|
117463
|
+
}
|
|
117464
|
+
return `Cannot cancel job ${jobId}: status is ${job.status}`;
|
|
117465
|
+
};
|
|
117466
|
+
}
|
|
117467
|
+
var jobListTool = {
|
|
117468
|
+
name: "job_list",
|
|
117469
|
+
description: "List all background jobs for the current session.",
|
|
117470
|
+
parameters: {
|
|
117471
|
+
type: "object",
|
|
117472
|
+
properties: {
|
|
117473
|
+
status: {
|
|
117474
|
+
type: "string",
|
|
117475
|
+
description: "Filter by status (pending, running, completed, failed, timeout, cancelled)",
|
|
117476
|
+
enum: ["pending", "running", "completed", "failed", "timeout", "cancelled"]
|
|
117477
|
+
}
|
|
117478
|
+
}
|
|
117479
|
+
}
|
|
117480
|
+
};
|
|
117481
|
+
function createJobListExecutor(getJobManager) {
|
|
117482
|
+
return async (input) => {
|
|
117483
|
+
const manager = getJobManager();
|
|
117484
|
+
if (!manager) {
|
|
117485
|
+
return "Jobs system is not enabled";
|
|
117486
|
+
}
|
|
117487
|
+
let jobs = await manager.listSessionJobs();
|
|
117488
|
+
const statusFilter = input.status;
|
|
117489
|
+
if (statusFilter) {
|
|
117490
|
+
jobs = jobs.filter((j) => j.status === statusFilter);
|
|
117491
|
+
}
|
|
117492
|
+
if (jobs.length === 0) {
|
|
117493
|
+
return statusFilter ? `No jobs with status '${statusFilter}'` : "No jobs found";
|
|
117494
|
+
}
|
|
117495
|
+
jobs.sort((a, b) => b.createdAt - a.createdAt);
|
|
117496
|
+
const lines = [`Found ${jobs.length} job(s):
|
|
117497
|
+
`];
|
|
117498
|
+
for (const job of jobs) {
|
|
117499
|
+
const age = formatAge(Date.now() - job.createdAt);
|
|
117500
|
+
let line = `[${job.status.toUpperCase()}] ${job.id} - ${job.connectorName} ${job.command} (${age} ago)`;
|
|
117501
|
+
if (job.status === "running" && job.startedAt) {
|
|
117502
|
+
const elapsed = ((Date.now() - job.startedAt) / 1000).toFixed(1);
|
|
117503
|
+
line += ` - running for ${elapsed}s`;
|
|
117504
|
+
}
|
|
117505
|
+
if (job.error) {
|
|
117506
|
+
line += ` - ${job.error.message.slice(0, 50)}`;
|
|
117507
|
+
}
|
|
117508
|
+
lines.push(line);
|
|
117509
|
+
}
|
|
117510
|
+
return lines.join(`
|
|
117511
|
+
`);
|
|
117512
|
+
};
|
|
117513
|
+
}
|
|
117514
|
+
function formatAge(ms) {
|
|
117515
|
+
const seconds = Math.floor(ms / 1000);
|
|
117516
|
+
if (seconds < 60)
|
|
117517
|
+
return `${seconds}s`;
|
|
117518
|
+
const minutes = Math.floor(seconds / 60);
|
|
117519
|
+
if (minutes < 60)
|
|
117520
|
+
return `${minutes}m`;
|
|
117521
|
+
const hours = Math.floor(minutes / 60);
|
|
117522
|
+
if (hours < 24)
|
|
117523
|
+
return `${hours}h`;
|
|
117524
|
+
const days = Math.floor(hours / 24);
|
|
117525
|
+
return `${days}d`;
|
|
117526
|
+
}
|
|
116571
117527
|
// packages/core/src/commands/builtin.ts
|
|
116572
117528
|
var VERSION = process.env.ASSISTANTS_VERSION || process.env.npm_package_version || "unknown";
|
|
116573
117529
|
function resolveAuthTimeout(resolve5) {
|
|
@@ -116648,6 +117604,7 @@ class BuiltinCommands {
|
|
|
116648
117604
|
loader.register(this.initCommand());
|
|
116649
117605
|
loader.register(this.costCommand());
|
|
116650
117606
|
loader.register(this.modelCommand());
|
|
117607
|
+
loader.register(this.skillCommand());
|
|
116651
117608
|
loader.register(this.skillsCommand(loader));
|
|
116652
117609
|
loader.register(this.memoryCommand());
|
|
116653
117610
|
loader.register(this.feedbackCommand());
|
|
@@ -116661,6 +117618,7 @@ class BuiltinCommands {
|
|
|
116661
117618
|
loader.register(this.verificationCommand());
|
|
116662
117619
|
loader.register(this.inboxCommand());
|
|
116663
117620
|
loader.register(this.walletCommand());
|
|
117621
|
+
loader.register(this.jobsCommand());
|
|
116664
117622
|
loader.register(this.exitCommand());
|
|
116665
117623
|
}
|
|
116666
117624
|
voiceCommand() {
|
|
@@ -117828,6 +118786,194 @@ Rate limit: ${status.readsUsed}/${status.maxReads} reads this hour
|
|
|
117828
118786
|
}
|
|
117829
118787
|
};
|
|
117830
118788
|
}
|
|
118789
|
+
jobsCommand() {
|
|
118790
|
+
return {
|
|
118791
|
+
name: "jobs",
|
|
118792
|
+
description: "List and manage background jobs",
|
|
118793
|
+
builtin: true,
|
|
118794
|
+
selfHandled: true,
|
|
118795
|
+
content: "",
|
|
118796
|
+
handler: async (args, context) => {
|
|
118797
|
+
const parts = args.trim().split(/\s+/);
|
|
118798
|
+
const subcommand = parts[0]?.toLowerCase() || "list";
|
|
118799
|
+
const arg = parts[1] || "";
|
|
118800
|
+
switch (subcommand) {
|
|
118801
|
+
case "list":
|
|
118802
|
+
case "": {
|
|
118803
|
+
const jobs = await listJobsForSession(context.sessionId);
|
|
118804
|
+
if (jobs.length === 0) {
|
|
118805
|
+
context.emit("text", `No jobs found for this session.
|
|
118806
|
+
`);
|
|
118807
|
+
context.emit("done");
|
|
118808
|
+
return { handled: true };
|
|
118809
|
+
}
|
|
118810
|
+
jobs.sort((a, b) => b.createdAt - a.createdAt);
|
|
118811
|
+
let output = `
|
|
118812
|
+
| Status | ID | Connector | Command | Age |
|
|
118813
|
+
`;
|
|
118814
|
+
output += `|--------|----|-----------|---------|----- |
|
|
118815
|
+
`;
|
|
118816
|
+
for (const job of jobs) {
|
|
118817
|
+
const age = this.formatAge(Date.now() - job.createdAt);
|
|
118818
|
+
const shortId = job.id.slice(0, 8);
|
|
118819
|
+
const command = job.command.slice(0, 30);
|
|
118820
|
+
output += `| ${job.status.toUpperCase()} | ${shortId} | ${job.connectorName} | ${command} | ${age} |
|
|
118821
|
+
`;
|
|
118822
|
+
}
|
|
118823
|
+
context.emit("text", output);
|
|
118824
|
+
context.emit("done");
|
|
118825
|
+
return { handled: true };
|
|
118826
|
+
}
|
|
118827
|
+
case "all": {
|
|
118828
|
+
const jobs = await listJobs();
|
|
118829
|
+
if (jobs.length === 0) {
|
|
118830
|
+
context.emit("text", `No jobs found.
|
|
118831
|
+
`);
|
|
118832
|
+
context.emit("done");
|
|
118833
|
+
return { handled: true };
|
|
118834
|
+
}
|
|
118835
|
+
jobs.sort((a, b) => b.createdAt - a.createdAt);
|
|
118836
|
+
let output = `
|
|
118837
|
+
| Status | ID | Session | Connector | Command | Age |
|
|
118838
|
+
`;
|
|
118839
|
+
output += `|--------|----|---------|-----------|---------|-----|
|
|
118840
|
+
`;
|
|
118841
|
+
for (const job of jobs) {
|
|
118842
|
+
const age = this.formatAge(Date.now() - job.createdAt);
|
|
118843
|
+
const shortId = job.id.slice(0, 8);
|
|
118844
|
+
const shortSession = job.sessionId.slice(0, 8);
|
|
118845
|
+
const command = job.command.slice(0, 20);
|
|
118846
|
+
output += `| ${job.status.toUpperCase()} | ${shortId} | ${shortSession} | ${job.connectorName} | ${command} | ${age} |
|
|
118847
|
+
`;
|
|
118848
|
+
}
|
|
118849
|
+
context.emit("text", output);
|
|
118850
|
+
context.emit("done");
|
|
118851
|
+
return { handled: true };
|
|
118852
|
+
}
|
|
118853
|
+
case "cancel": {
|
|
118854
|
+
if (!arg) {
|
|
118855
|
+
context.emit("text", `Usage: /jobs cancel <job_id>
|
|
118856
|
+
`);
|
|
118857
|
+
context.emit("done");
|
|
118858
|
+
return { handled: true };
|
|
118859
|
+
}
|
|
118860
|
+
const jobs = await listJobs();
|
|
118861
|
+
const matches = jobs.filter((j) => j.id.startsWith(arg) || j.id === arg);
|
|
118862
|
+
if (matches.length === 0) {
|
|
118863
|
+
context.emit("text", `Job not found: ${arg}
|
|
118864
|
+
`);
|
|
118865
|
+
context.emit("done");
|
|
118866
|
+
return { handled: true };
|
|
118867
|
+
}
|
|
118868
|
+
if (matches.length > 1) {
|
|
118869
|
+
context.emit("text", `Ambiguous job ID. Matches: ${matches.map((j) => j.id).join(", ")}
|
|
118870
|
+
`);
|
|
118871
|
+
context.emit("done");
|
|
118872
|
+
return { handled: true };
|
|
118873
|
+
}
|
|
118874
|
+
const job = matches[0];
|
|
118875
|
+
if (!["pending", "running"].includes(job.status)) {
|
|
118876
|
+
context.emit("text", `Cannot cancel job ${job.id}: status is ${job.status}
|
|
118877
|
+
`);
|
|
118878
|
+
context.emit("done");
|
|
118879
|
+
return { handled: true };
|
|
118880
|
+
}
|
|
118881
|
+
context.emit("text", `Job ${job.id} marked for cancellation. Use job_cancel tool for full cancellation.
|
|
118882
|
+
`);
|
|
118883
|
+
context.emit("done");
|
|
118884
|
+
return { handled: true };
|
|
118885
|
+
}
|
|
118886
|
+
case "clear": {
|
|
118887
|
+
const cleaned = await cleanupSessionJobs(context.sessionId);
|
|
118888
|
+
context.emit("text", `Cleared ${cleaned} completed job(s).
|
|
118889
|
+
`);
|
|
118890
|
+
context.emit("done");
|
|
118891
|
+
return { handled: true };
|
|
118892
|
+
}
|
|
118893
|
+
case "help": {
|
|
118894
|
+
const help = `
|
|
118895
|
+
/jobs List jobs for current session
|
|
118896
|
+
/jobs list List jobs for current session
|
|
118897
|
+
/jobs all List all jobs across sessions
|
|
118898
|
+
/jobs <id> Show details of a specific job
|
|
118899
|
+
/jobs cancel <id> Cancel a running job
|
|
118900
|
+
/jobs clear Clear completed jobs for this session
|
|
118901
|
+
/jobs help Show this help
|
|
118902
|
+
`;
|
|
118903
|
+
context.emit("text", help);
|
|
118904
|
+
context.emit("done");
|
|
118905
|
+
return { handled: true };
|
|
118906
|
+
}
|
|
118907
|
+
default: {
|
|
118908
|
+
const jobs = await listJobs();
|
|
118909
|
+
const matches = jobs.filter((j) => j.id.startsWith(subcommand) || j.id === subcommand);
|
|
118910
|
+
if (matches.length === 0) {
|
|
118911
|
+
context.emit("text", `Job not found: ${subcommand}
|
|
118912
|
+
Use /jobs help for usage.
|
|
118913
|
+
`);
|
|
118914
|
+
context.emit("done");
|
|
118915
|
+
return { handled: true };
|
|
118916
|
+
}
|
|
118917
|
+
if (matches.length > 1) {
|
|
118918
|
+
context.emit("text", `Ambiguous job ID. Matches: ${matches.map((j) => j.id).join(", ")}
|
|
118919
|
+
`);
|
|
118920
|
+
context.emit("done");
|
|
118921
|
+
return { handled: true };
|
|
118922
|
+
}
|
|
118923
|
+
const job = matches[0];
|
|
118924
|
+
let output = `
|
|
118925
|
+
Job ID: ${job.id}
|
|
118926
|
+
Status: ${job.status}
|
|
118927
|
+
Connector: ${job.connectorName}
|
|
118928
|
+
Command: ${job.command}
|
|
118929
|
+
Session: ${job.sessionId}
|
|
118930
|
+
Created: ${new Date(job.createdAt).toISOString()}
|
|
118931
|
+
`;
|
|
118932
|
+
if (job.startedAt) {
|
|
118933
|
+
output += `Started: ${new Date(job.startedAt).toISOString()}
|
|
118934
|
+
`;
|
|
118935
|
+
}
|
|
118936
|
+
if (job.completedAt) {
|
|
118937
|
+
output += `Completed: ${new Date(job.completedAt).toISOString()}
|
|
118938
|
+
`;
|
|
118939
|
+
const duration = job.completedAt - (job.startedAt || job.createdAt);
|
|
118940
|
+
output += `Duration: ${(duration / 1000).toFixed(1)}s
|
|
118941
|
+
`;
|
|
118942
|
+
}
|
|
118943
|
+
output += `Timeout: ${job.timeoutMs / 1000}s
|
|
118944
|
+
`;
|
|
118945
|
+
if (job.result) {
|
|
118946
|
+
output += `
|
|
118947
|
+
Result:
|
|
118948
|
+
${job.result.content}
|
|
118949
|
+
`;
|
|
118950
|
+
}
|
|
118951
|
+
if (job.error) {
|
|
118952
|
+
output += `
|
|
118953
|
+
Error (${job.error.code}): ${job.error.message}
|
|
118954
|
+
`;
|
|
118955
|
+
}
|
|
118956
|
+
context.emit("text", output);
|
|
118957
|
+
context.emit("done");
|
|
118958
|
+
return { handled: true };
|
|
118959
|
+
}
|
|
118960
|
+
}
|
|
118961
|
+
}
|
|
118962
|
+
};
|
|
118963
|
+
}
|
|
118964
|
+
formatAge(ms) {
|
|
118965
|
+
const seconds = Math.floor(ms / 1000);
|
|
118966
|
+
if (seconds < 60)
|
|
118967
|
+
return `${seconds}s`;
|
|
118968
|
+
const minutes = Math.floor(seconds / 60);
|
|
118969
|
+
if (minutes < 60)
|
|
118970
|
+
return `${minutes}m`;
|
|
118971
|
+
const hours = Math.floor(minutes / 60);
|
|
118972
|
+
if (hours < 24)
|
|
118973
|
+
return `${hours}h`;
|
|
118974
|
+
const days = Math.floor(hours / 24);
|
|
118975
|
+
return `${days}d`;
|
|
118976
|
+
}
|
|
117831
118977
|
exitCommand() {
|
|
117832
118978
|
return {
|
|
117833
118979
|
name: "exit",
|
|
@@ -118660,6 +119806,198 @@ Energy restored.
|
|
|
118660
119806
|
}
|
|
118661
119807
|
};
|
|
118662
119808
|
}
|
|
119809
|
+
skillCommand() {
|
|
119810
|
+
return {
|
|
119811
|
+
name: "skill",
|
|
119812
|
+
description: "Create or manage skills",
|
|
119813
|
+
builtin: true,
|
|
119814
|
+
selfHandled: true,
|
|
119815
|
+
content: "",
|
|
119816
|
+
handler: async (args, context) => {
|
|
119817
|
+
const tokens = splitArgs(args || "");
|
|
119818
|
+
const subcommand = tokens.shift()?.toLowerCase();
|
|
119819
|
+
const emitHelp = () => {
|
|
119820
|
+
let message = `
|
|
119821
|
+
**/skill commands**
|
|
119822
|
+
|
|
119823
|
+
`;
|
|
119824
|
+
message += `/skill create <name> [--project|--global] [options]
|
|
119825
|
+
`;
|
|
119826
|
+
message += `
|
|
119827
|
+
Options:
|
|
119828
|
+
`;
|
|
119829
|
+
message += ` --project Create in project (.assistants/skills)
|
|
119830
|
+
`;
|
|
119831
|
+
message += ` --global Create globally (~/.assistants/shared/skills)
|
|
119832
|
+
`;
|
|
119833
|
+
message += ` --desc "..." Description
|
|
119834
|
+
`;
|
|
119835
|
+
message += ` --tools a,b,c Allowed tools list
|
|
119836
|
+
`;
|
|
119837
|
+
message += ` --hint "..." Argument hint
|
|
119838
|
+
`;
|
|
119839
|
+
message += ` --content "..." Skill body content
|
|
119840
|
+
`;
|
|
119841
|
+
message += ` --interactive Ask follow-up questions
|
|
119842
|
+
`;
|
|
119843
|
+
message += ` --force Overwrite existing skill
|
|
119844
|
+
`;
|
|
119845
|
+
message += ` --yes Accept default (project) scope
|
|
119846
|
+
`;
|
|
119847
|
+
message += `
|
|
119848
|
+
Notes:
|
|
119849
|
+
`;
|
|
119850
|
+
message += ` - Skill directories must start with "skill-"
|
|
119851
|
+
`;
|
|
119852
|
+
message += ` - Skill names should not include the word "skill"
|
|
119853
|
+
`;
|
|
119854
|
+
context.emit("text", message);
|
|
119855
|
+
context.emit("done");
|
|
119856
|
+
};
|
|
119857
|
+
if (!subcommand || subcommand === "help") {
|
|
119858
|
+
emitHelp();
|
|
119859
|
+
return { handled: true };
|
|
119860
|
+
}
|
|
119861
|
+
if (subcommand !== "create") {
|
|
119862
|
+
context.emit("text", `Unknown /skill command: ${subcommand}
|
|
119863
|
+
`);
|
|
119864
|
+
context.emit("text", `Use /skill help for available commands.
|
|
119865
|
+
`);
|
|
119866
|
+
context.emit("done");
|
|
119867
|
+
return { handled: true };
|
|
119868
|
+
}
|
|
119869
|
+
let name;
|
|
119870
|
+
let scope;
|
|
119871
|
+
let description;
|
|
119872
|
+
let argumentHint;
|
|
119873
|
+
let content;
|
|
119874
|
+
let overwrite = false;
|
|
119875
|
+
let yes = false;
|
|
119876
|
+
let interactive = false;
|
|
119877
|
+
let allowedTools;
|
|
119878
|
+
for (let i = 0;i < tokens.length; i += 1) {
|
|
119879
|
+
const token = tokens[i];
|
|
119880
|
+
if (!token)
|
|
119881
|
+
continue;
|
|
119882
|
+
if (token.startsWith("--")) {
|
|
119883
|
+
switch (token) {
|
|
119884
|
+
case "--project":
|
|
119885
|
+
scope = "project";
|
|
119886
|
+
break;
|
|
119887
|
+
case "--global":
|
|
119888
|
+
scope = "global";
|
|
119889
|
+
break;
|
|
119890
|
+
case "--desc":
|
|
119891
|
+
case "--description":
|
|
119892
|
+
description = tokens[i + 1];
|
|
119893
|
+
i += 1;
|
|
119894
|
+
break;
|
|
119895
|
+
case "--tools": {
|
|
119896
|
+
const list = tokens[i + 1] || "";
|
|
119897
|
+
allowedTools = list.split(",").map((tool) => tool.trim()).filter(Boolean);
|
|
119898
|
+
i += 1;
|
|
119899
|
+
break;
|
|
119900
|
+
}
|
|
119901
|
+
case "--hint":
|
|
119902
|
+
argumentHint = tokens[i + 1];
|
|
119903
|
+
i += 1;
|
|
119904
|
+
break;
|
|
119905
|
+
case "--content":
|
|
119906
|
+
content = tokens[i + 1];
|
|
119907
|
+
i += 1;
|
|
119908
|
+
break;
|
|
119909
|
+
case "--interactive":
|
|
119910
|
+
case "--ask":
|
|
119911
|
+
case "--interview":
|
|
119912
|
+
interactive = true;
|
|
119913
|
+
break;
|
|
119914
|
+
case "--force":
|
|
119915
|
+
case "--overwrite":
|
|
119916
|
+
overwrite = true;
|
|
119917
|
+
break;
|
|
119918
|
+
case "--yes":
|
|
119919
|
+
yes = true;
|
|
119920
|
+
break;
|
|
119921
|
+
default:
|
|
119922
|
+
break;
|
|
119923
|
+
}
|
|
119924
|
+
} else if (!name) {
|
|
119925
|
+
name = token;
|
|
119926
|
+
}
|
|
119927
|
+
}
|
|
119928
|
+
if (!name) {
|
|
119929
|
+
context.emit("text", `Usage: /skill create <name> [--project|--global]
|
|
119930
|
+
`);
|
|
119931
|
+
context.emit("done");
|
|
119932
|
+
return { handled: true };
|
|
119933
|
+
}
|
|
119934
|
+
if (interactive || !scope && !yes) {
|
|
119935
|
+
const known = [];
|
|
119936
|
+
if (scope)
|
|
119937
|
+
known.push(`scope: ${scope}`);
|
|
119938
|
+
if (description)
|
|
119939
|
+
known.push(`description: ${description}`);
|
|
119940
|
+
if (content)
|
|
119941
|
+
known.push(`content: provided`);
|
|
119942
|
+
if (allowedTools && allowedTools.length > 0)
|
|
119943
|
+
known.push(`allowed_tools: ${allowedTools.join(", ")}`);
|
|
119944
|
+
if (argumentHint)
|
|
119945
|
+
known.push(`argument_hint: ${argumentHint}`);
|
|
119946
|
+
const missing = [];
|
|
119947
|
+
if (!scope)
|
|
119948
|
+
missing.push("scope (project/global, default project)");
|
|
119949
|
+
if (!description)
|
|
119950
|
+
missing.push("description");
|
|
119951
|
+
if (!content)
|
|
119952
|
+
missing.push("content (multi-line allowed)");
|
|
119953
|
+
if (!allowedTools || allowedTools.length === 0)
|
|
119954
|
+
missing.push("allowed tools (optional)");
|
|
119955
|
+
if (!argumentHint)
|
|
119956
|
+
missing.push("argument hint (optional)");
|
|
119957
|
+
const knownBlock = known.length > 0 ? `Known values:\\n- ${known.join("\\n- ")}\\n\\n` : "";
|
|
119958
|
+
const missingBlock = missing.length > 0 ? `Ask for:\\n- ${missing.join("\\n- ")}\\n\\n` : "";
|
|
119959
|
+
context.emit("done");
|
|
119960
|
+
return {
|
|
119961
|
+
handled: false,
|
|
119962
|
+
prompt: `We are creating a new skill named "${name}".\\n\\n${knownBlock}${missingBlock}Use the ask_user tool to interview the user and collect missing fields. Then call skill_create with name, scope, and any provided fields. If the user leaves optional fields blank, omit them. If scope is not specified, default to project.`
|
|
119963
|
+
};
|
|
119964
|
+
}
|
|
119965
|
+
const finalScope = scope ?? "project";
|
|
119966
|
+
try {
|
|
119967
|
+
const result = await createSkill({
|
|
119968
|
+
name,
|
|
119969
|
+
scope: finalScope,
|
|
119970
|
+
description,
|
|
119971
|
+
allowedTools,
|
|
119972
|
+
argumentHint,
|
|
119973
|
+
content,
|
|
119974
|
+
cwd: context.cwd,
|
|
119975
|
+
overwrite
|
|
119976
|
+
});
|
|
119977
|
+
await context.refreshSkills?.();
|
|
119978
|
+
let message = `
|
|
119979
|
+
Created skill "${result.name}" (${result.scope}).
|
|
119980
|
+
`;
|
|
119981
|
+
message += `Location: ${result.filePath}
|
|
119982
|
+
`;
|
|
119983
|
+
message += `Invoke with: $${result.name} [args] or /${result.name} [args]
|
|
119984
|
+
`;
|
|
119985
|
+
if (!scope) {
|
|
119986
|
+
message += `Defaulted to project scope. Use --global for a global skill.
|
|
119987
|
+
`;
|
|
119988
|
+
}
|
|
119989
|
+
context.emit("text", message);
|
|
119990
|
+
context.emit("done");
|
|
119991
|
+
return { handled: true };
|
|
119992
|
+
} catch (error) {
|
|
119993
|
+
context.emit("text", `Failed to create skill: ${error instanceof Error ? error.message : String(error)}
|
|
119994
|
+
`);
|
|
119995
|
+
context.emit("done");
|
|
119996
|
+
return { handled: true };
|
|
119997
|
+
}
|
|
119998
|
+
}
|
|
119999
|
+
};
|
|
120000
|
+
}
|
|
118663
120001
|
skillsCommand(loader) {
|
|
118664
120002
|
return {
|
|
118665
120003
|
name: "skills",
|
|
@@ -118674,6 +120012,9 @@ Energy restored.
|
|
|
118674
120012
|
`;
|
|
118675
120013
|
message += `Skills are invoked with $skill-name [arguments] or /skill-name [arguments]
|
|
118676
120014
|
|
|
120015
|
+
`;
|
|
120016
|
+
message += `Create a skill with /skill create <name>
|
|
120017
|
+
|
|
118677
120018
|
`;
|
|
118678
120019
|
if (context.skills.length === 0) {
|
|
118679
120020
|
message += `No skills loaded.
|
|
@@ -118803,8 +120144,8 @@ ${context.skills.length} skill(s) available.
|
|
|
118803
120144
|
`;
|
|
118804
120145
|
message += `| --- | --- | --- |
|
|
118805
120146
|
`;
|
|
118806
|
-
for (const
|
|
118807
|
-
message += `| ${
|
|
120147
|
+
for (const stat2 of errorStats.slice(0, 5)) {
|
|
120148
|
+
message += `| ${stat2.code} | ${stat2.count} | ${stat2.lastOccurrence} |
|
|
118808
120149
|
`;
|
|
118809
120150
|
}
|
|
118810
120151
|
}
|
|
@@ -118838,9 +120179,9 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
118838
120179
|
content: "",
|
|
118839
120180
|
handler: async (args, context) => {
|
|
118840
120181
|
const configPaths = [
|
|
118841
|
-
|
|
118842
|
-
|
|
118843
|
-
|
|
120182
|
+
join15(context.cwd, ".assistants", "config.json"),
|
|
120183
|
+
join15(context.cwd, ".assistants", "config.local.json"),
|
|
120184
|
+
join15(getConfigDir(), "config.json")
|
|
118844
120185
|
];
|
|
118845
120186
|
let message = `
|
|
118846
120187
|
**Configuration**
|
|
@@ -118858,9 +120199,9 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
118858
120199
|
message += `
|
|
118859
120200
|
**Commands Directories:**
|
|
118860
120201
|
`;
|
|
118861
|
-
message += ` - Project: ${
|
|
120202
|
+
message += ` - Project: ${join15(context.cwd, ".assistants", "commands")}
|
|
118862
120203
|
`;
|
|
118863
|
-
message += ` - Global: ${
|
|
120204
|
+
message += ` - Global: ${join15(homeDir, ".assistants", "commands")}
|
|
118864
120205
|
`;
|
|
118865
120206
|
context.emit("text", message);
|
|
118866
120207
|
context.emit("done");
|
|
@@ -118876,7 +120217,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
118876
120217
|
selfHandled: true,
|
|
118877
120218
|
content: "",
|
|
118878
120219
|
handler: async (args, context) => {
|
|
118879
|
-
const commandsDir =
|
|
120220
|
+
const commandsDir = join15(context.cwd, ".assistants", "commands");
|
|
118880
120221
|
mkdirSync4(commandsDir, { recursive: true });
|
|
118881
120222
|
const exampleCommand = `---
|
|
118882
120223
|
name: reflect
|
|
@@ -118892,7 +120233,7 @@ Please summarize the last interaction and suggest 2-3 next steps.
|
|
|
118892
120233
|
- Focus on clarity
|
|
118893
120234
|
- Ask a follow-up question if needed
|
|
118894
120235
|
`;
|
|
118895
|
-
const examplePath =
|
|
120236
|
+
const examplePath = join15(commandsDir, "reflect.md");
|
|
118896
120237
|
if (!existsSync8(examplePath)) {
|
|
118897
120238
|
writeFileSync5(examplePath, exampleCommand);
|
|
118898
120239
|
}
|
|
@@ -119660,7 +121001,7 @@ async function createLLMClient(config) {
|
|
|
119660
121001
|
// packages/core/src/heartbeat/manager.ts
|
|
119661
121002
|
import { dirname as dirname6 } from "path";
|
|
119662
121003
|
import { mkdirSync as mkdirSync5 } from "fs";
|
|
119663
|
-
import { readFile as
|
|
121004
|
+
import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
119664
121005
|
|
|
119665
121006
|
class HeartbeatManager {
|
|
119666
121007
|
config;
|
|
@@ -119739,12 +121080,12 @@ class HeartbeatManager {
|
|
|
119739
121080
|
}
|
|
119740
121081
|
async persist(heartbeat) {
|
|
119741
121082
|
try {
|
|
119742
|
-
await
|
|
121083
|
+
await writeFile5(this.config.persistPath, JSON.stringify(heartbeat, null, 2));
|
|
119743
121084
|
} catch {}
|
|
119744
121085
|
}
|
|
119745
121086
|
static async checkStale(path2, thresholdMs) {
|
|
119746
121087
|
try {
|
|
119747
|
-
const content = await
|
|
121088
|
+
const content = await readFile5(path2, "utf-8");
|
|
119748
121089
|
const heartbeat = JSON.parse(content);
|
|
119749
121090
|
const age = Date.now() - new Date(heartbeat.timestamp).getTime();
|
|
119750
121091
|
return { isStale: age > thresholdMs, lastHeartbeat: heartbeat };
|
|
@@ -119756,7 +121097,7 @@ class HeartbeatManager {
|
|
|
119756
121097
|
// packages/core/src/heartbeat/persistence.ts
|
|
119757
121098
|
import { dirname as dirname7 } from "path";
|
|
119758
121099
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
119759
|
-
import { readFile as
|
|
121100
|
+
import { readFile as readFile6, writeFile as writeFile6, unlink as unlink4 } from "fs/promises";
|
|
119760
121101
|
|
|
119761
121102
|
class StatePersistence {
|
|
119762
121103
|
path;
|
|
@@ -119766,12 +121107,12 @@ class StatePersistence {
|
|
|
119766
121107
|
}
|
|
119767
121108
|
async save(state) {
|
|
119768
121109
|
try {
|
|
119769
|
-
await
|
|
121110
|
+
await writeFile6(this.path, JSON.stringify(state, null, 2));
|
|
119770
121111
|
} catch {}
|
|
119771
121112
|
}
|
|
119772
121113
|
async load() {
|
|
119773
121114
|
try {
|
|
119774
|
-
const content = await
|
|
121115
|
+
const content = await readFile6(this.path, "utf-8");
|
|
119775
121116
|
return JSON.parse(content);
|
|
119776
121117
|
} catch {
|
|
119777
121118
|
return null;
|
|
@@ -119779,7 +121120,7 @@ class StatePersistence {
|
|
|
119779
121120
|
}
|
|
119780
121121
|
async clear() {
|
|
119781
121122
|
try {
|
|
119782
|
-
await
|
|
121123
|
+
await unlink4(this.path);
|
|
119783
121124
|
} catch {}
|
|
119784
121125
|
}
|
|
119785
121126
|
}
|
|
@@ -119983,7 +121324,7 @@ class EnergyManager {
|
|
|
119983
121324
|
// packages/core/src/energy/storage.ts
|
|
119984
121325
|
import { dirname as dirname8 } from "path";
|
|
119985
121326
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
119986
|
-
import { readFile as
|
|
121327
|
+
import { readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
|
|
119987
121328
|
|
|
119988
121329
|
class EnergyStorage {
|
|
119989
121330
|
path;
|
|
@@ -119993,12 +121334,12 @@ class EnergyStorage {
|
|
|
119993
121334
|
}
|
|
119994
121335
|
async save(state) {
|
|
119995
121336
|
try {
|
|
119996
|
-
await
|
|
121337
|
+
await writeFile7(this.path, JSON.stringify(state, null, 2));
|
|
119997
121338
|
} catch {}
|
|
119998
121339
|
}
|
|
119999
121340
|
async load() {
|
|
120000
121341
|
try {
|
|
120001
|
-
const content = await
|
|
121342
|
+
const content = await readFile7(this.path, "utf-8");
|
|
120002
121343
|
return JSON.parse(content);
|
|
120003
121344
|
} catch {
|
|
120004
121345
|
return null;
|
|
@@ -120058,12 +121399,12 @@ function validateToolCalls(toolCalls, tools) {
|
|
|
120058
121399
|
// packages/core/src/voice/utils.ts
|
|
120059
121400
|
import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
|
|
120060
121401
|
import { homedir as homedir12 } from "os";
|
|
120061
|
-
import { join as
|
|
121402
|
+
import { join as join17 } from "path";
|
|
120062
121403
|
import { spawnSync } from "child_process";
|
|
120063
121404
|
function loadApiKeyFromSecrets2(key) {
|
|
120064
121405
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
120065
121406
|
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir12();
|
|
120066
|
-
const secretsPath =
|
|
121407
|
+
const secretsPath = join17(homeDir, ".secrets");
|
|
120067
121408
|
if (!existsSync10(secretsPath))
|
|
120068
121409
|
return;
|
|
120069
121410
|
try {
|
|
@@ -120137,7 +121478,7 @@ class SystemSTT {
|
|
|
120137
121478
|
// packages/core/src/voice/tts.ts
|
|
120138
121479
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
120139
121480
|
import { tmpdir as tmpdir2 } from "os";
|
|
120140
|
-
import { join as
|
|
121481
|
+
import { join as join18 } from "path";
|
|
120141
121482
|
import { readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
120142
121483
|
class ElevenLabsTTS {
|
|
120143
121484
|
apiKey;
|
|
@@ -120241,7 +121582,7 @@ class SystemTTS {
|
|
|
120241
121582
|
if (!say) {
|
|
120242
121583
|
throw new Error('System TTS not available: missing "say" command.');
|
|
120243
121584
|
}
|
|
120244
|
-
const output =
|
|
121585
|
+
const output = join18(tmpdir2(), `assistants-tts-${Date.now()}.aiff`);
|
|
120245
121586
|
const args = [];
|
|
120246
121587
|
if (this.voiceId) {
|
|
120247
121588
|
args.push("-v", this.voiceId);
|
|
@@ -120263,7 +121604,7 @@ class SystemTTS {
|
|
|
120263
121604
|
}
|
|
120264
121605
|
const espeak = findExecutable("espeak") || findExecutable("espeak-ng");
|
|
120265
121606
|
if (espeak) {
|
|
120266
|
-
const output =
|
|
121607
|
+
const output = join18(tmpdir2(), `assistants-tts-${Date.now()}.wav`);
|
|
120267
121608
|
const args = ["-w", output];
|
|
120268
121609
|
if (this.voiceId) {
|
|
120269
121610
|
args.push("-v", this.voiceId);
|
|
@@ -120290,14 +121631,14 @@ class SystemTTS {
|
|
|
120290
121631
|
// packages/core/src/voice/player.ts
|
|
120291
121632
|
import { spawn } from "child_process";
|
|
120292
121633
|
import { tmpdir as tmpdir3 } from "os";
|
|
120293
|
-
import { join as
|
|
120294
|
-
import { unlink as
|
|
121634
|
+
import { join as join19 } from "path";
|
|
121635
|
+
import { unlink as unlink5, writeFileSync as writeFileSync6 } from "fs";
|
|
120295
121636
|
class AudioPlayer {
|
|
120296
121637
|
currentProcess = null;
|
|
120297
121638
|
playing = false;
|
|
120298
121639
|
async play(audio, options = {}) {
|
|
120299
121640
|
const format = options.format ?? "mp3";
|
|
120300
|
-
const tempFile =
|
|
121641
|
+
const tempFile = join19(tmpdir3(), `assistants-audio-${Date.now()}.${format}`);
|
|
120301
121642
|
writeFileSync6(tempFile, Buffer.from(audio));
|
|
120302
121643
|
const player = this.resolvePlayer(format);
|
|
120303
121644
|
if (!player) {
|
|
@@ -120309,13 +121650,13 @@ class AudioPlayer {
|
|
|
120309
121650
|
this.currentProcess.on("close", () => {
|
|
120310
121651
|
this.playing = false;
|
|
120311
121652
|
this.currentProcess = null;
|
|
120312
|
-
|
|
121653
|
+
unlink5(tempFile, () => {});
|
|
120313
121654
|
resolve5();
|
|
120314
121655
|
});
|
|
120315
121656
|
this.currentProcess.on("error", (error2) => {
|
|
120316
121657
|
this.playing = false;
|
|
120317
121658
|
this.currentProcess = null;
|
|
120318
|
-
|
|
121659
|
+
unlink5(tempFile, () => {});
|
|
120319
121660
|
reject(error2);
|
|
120320
121661
|
});
|
|
120321
121662
|
});
|
|
@@ -120365,8 +121706,8 @@ class AudioPlayer {
|
|
|
120365
121706
|
// packages/core/src/voice/recorder.ts
|
|
120366
121707
|
import { spawn as spawn2 } from "child_process";
|
|
120367
121708
|
import { tmpdir as tmpdir4 } from "os";
|
|
120368
|
-
import { join as
|
|
120369
|
-
import { readFileSync as readFileSync7, unlink as
|
|
121709
|
+
import { join as join20 } from "path";
|
|
121710
|
+
import { readFileSync as readFileSync7, unlink as unlink6 } from "fs";
|
|
120370
121711
|
class AudioRecorder {
|
|
120371
121712
|
currentProcess = null;
|
|
120372
121713
|
async record(options = {}) {
|
|
@@ -120376,7 +121717,7 @@ class AudioRecorder {
|
|
|
120376
121717
|
const duration = options.durationSeconds ?? 5;
|
|
120377
121718
|
const sampleRate = options.sampleRate ?? 16000;
|
|
120378
121719
|
const channels = options.channels ?? 1;
|
|
120379
|
-
const output =
|
|
121720
|
+
const output = join20(tmpdir4(), `assistants-record-${Date.now()}.wav`);
|
|
120380
121721
|
const recorder = this.resolveRecorder(sampleRate, channels, duration, output);
|
|
120381
121722
|
if (!recorder) {
|
|
120382
121723
|
throw new Error("No supported audio recorder found. Install sox or ffmpeg.");
|
|
@@ -120397,7 +121738,7 @@ class AudioRecorder {
|
|
|
120397
121738
|
});
|
|
120398
121739
|
});
|
|
120399
121740
|
const data = readFileSync7(output);
|
|
120400
|
-
|
|
121741
|
+
unlink6(output, () => {});
|
|
120401
121742
|
return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
120402
121743
|
}
|
|
120403
121744
|
stop() {
|
|
@@ -120569,14 +121910,14 @@ class VoiceManager {
|
|
|
120569
121910
|
// packages/core/src/identity/assistant-manager.ts
|
|
120570
121911
|
init_src();
|
|
120571
121912
|
import { existsSync as existsSync12 } from "fs";
|
|
120572
|
-
import { mkdir as
|
|
120573
|
-
import { join as
|
|
121913
|
+
import { mkdir as mkdir7, readFile as readFile9, writeFile as writeFile9, rm as rm2 } from "fs/promises";
|
|
121914
|
+
import { join as join22 } from "path";
|
|
120574
121915
|
|
|
120575
121916
|
// packages/core/src/identity/identity-manager.ts
|
|
120576
121917
|
init_src();
|
|
120577
121918
|
import { existsSync as existsSync11 } from "fs";
|
|
120578
|
-
import { mkdir as
|
|
120579
|
-
import { join as
|
|
121919
|
+
import { mkdir as mkdir6, readFile as readFile8, writeFile as writeFile8, rm } from "fs/promises";
|
|
121920
|
+
import { join as join21 } from "path";
|
|
120580
121921
|
var DEFAULT_PROFILE = {
|
|
120581
121922
|
displayName: "Assistant",
|
|
120582
121923
|
timezone: "UTC",
|
|
@@ -120606,22 +121947,22 @@ class IdentityManager {
|
|
|
120606
121947
|
this.basePath = basePath;
|
|
120607
121948
|
}
|
|
120608
121949
|
get identitiesRoot() {
|
|
120609
|
-
return
|
|
121950
|
+
return join21(this.basePath, "assistants", this.assistantId, "identities");
|
|
120610
121951
|
}
|
|
120611
121952
|
get indexPath() {
|
|
120612
|
-
return
|
|
121953
|
+
return join21(this.identitiesRoot, "index.json");
|
|
120613
121954
|
}
|
|
120614
121955
|
get activePath() {
|
|
120615
|
-
return
|
|
121956
|
+
return join21(this.identitiesRoot, "active.json");
|
|
120616
121957
|
}
|
|
120617
121958
|
identityPath(id) {
|
|
120618
|
-
return
|
|
121959
|
+
return join21(this.identitiesRoot, `${id}.json`);
|
|
120619
121960
|
}
|
|
120620
121961
|
assistantConfigPath() {
|
|
120621
|
-
return
|
|
121962
|
+
return join21(this.basePath, "assistants", this.assistantId, "config.json");
|
|
120622
121963
|
}
|
|
120623
121964
|
async initialize() {
|
|
120624
|
-
await
|
|
121965
|
+
await mkdir6(this.identitiesRoot, { recursive: true });
|
|
120625
121966
|
const index = await this.readIndex();
|
|
120626
121967
|
for (const id of index.identities) {
|
|
120627
121968
|
const identity = await this.readIdentity(id);
|
|
@@ -120728,7 +122069,7 @@ class IdentityManager {
|
|
|
120728
122069
|
return { identities: [] };
|
|
120729
122070
|
}
|
|
120730
122071
|
try {
|
|
120731
|
-
const raw = await
|
|
122072
|
+
const raw = await readFile8(this.indexPath, "utf-8");
|
|
120732
122073
|
const data = JSON.parse(raw);
|
|
120733
122074
|
return { identities: Array.isArray(data.identities) ? data.identities : [] };
|
|
120734
122075
|
} catch {
|
|
@@ -120740,33 +122081,33 @@ class IdentityManager {
|
|
|
120740
122081
|
if (!index.identities.includes(id)) {
|
|
120741
122082
|
index.identities.push(id);
|
|
120742
122083
|
}
|
|
120743
|
-
await
|
|
122084
|
+
await writeFile8(this.indexPath, JSON.stringify(index, null, 2));
|
|
120744
122085
|
}
|
|
120745
122086
|
async removeFromIndex(id) {
|
|
120746
122087
|
const index = await this.readIndex();
|
|
120747
122088
|
index.identities = index.identities.filter((identityId) => identityId !== id);
|
|
120748
|
-
await
|
|
122089
|
+
await writeFile8(this.indexPath, JSON.stringify(index, null, 2));
|
|
120749
122090
|
}
|
|
120750
122091
|
async readIdentity(id) {
|
|
120751
122092
|
const path2 = this.identityPath(id);
|
|
120752
122093
|
if (!existsSync11(path2))
|
|
120753
122094
|
return null;
|
|
120754
122095
|
try {
|
|
120755
|
-
const raw = await
|
|
122096
|
+
const raw = await readFile8(path2, "utf-8");
|
|
120756
122097
|
return JSON.parse(raw);
|
|
120757
122098
|
} catch {
|
|
120758
122099
|
return null;
|
|
120759
122100
|
}
|
|
120760
122101
|
}
|
|
120761
122102
|
async persistIdentity(identity) {
|
|
120762
|
-
await
|
|
120763
|
-
await
|
|
122103
|
+
await mkdir6(this.identitiesRoot, { recursive: true });
|
|
122104
|
+
await writeFile8(this.identityPath(identity.id), JSON.stringify(identity, null, 2));
|
|
120764
122105
|
}
|
|
120765
122106
|
async readActive() {
|
|
120766
122107
|
if (!existsSync11(this.activePath))
|
|
120767
122108
|
return null;
|
|
120768
122109
|
try {
|
|
120769
|
-
const raw = await
|
|
122110
|
+
const raw = await readFile8(this.activePath, "utf-8");
|
|
120770
122111
|
const data = JSON.parse(raw);
|
|
120771
122112
|
return data.id || null;
|
|
120772
122113
|
} catch {
|
|
@@ -120775,13 +122116,13 @@ class IdentityManager {
|
|
|
120775
122116
|
}
|
|
120776
122117
|
async setActive(id) {
|
|
120777
122118
|
this.activeId = id;
|
|
120778
|
-
await
|
|
122119
|
+
await writeFile8(this.activePath, JSON.stringify({ id }, null, 2));
|
|
120779
122120
|
}
|
|
120780
122121
|
async loadAssistant() {
|
|
120781
122122
|
if (!existsSync11(this.assistantConfigPath()))
|
|
120782
122123
|
return null;
|
|
120783
122124
|
try {
|
|
120784
|
-
const raw = await
|
|
122125
|
+
const raw = await readFile8(this.assistantConfigPath(), "utf-8");
|
|
120785
122126
|
return JSON.parse(raw);
|
|
120786
122127
|
} catch {
|
|
120787
122128
|
return null;
|
|
@@ -120802,19 +122143,19 @@ class AssistantManager {
|
|
|
120802
122143
|
this.basePath = basePath;
|
|
120803
122144
|
}
|
|
120804
122145
|
get assistantsRoot() {
|
|
120805
|
-
return
|
|
122146
|
+
return join22(this.basePath, "assistants");
|
|
120806
122147
|
}
|
|
120807
122148
|
get indexPath() {
|
|
120808
|
-
return
|
|
122149
|
+
return join22(this.assistantsRoot, "index.json");
|
|
120809
122150
|
}
|
|
120810
122151
|
get activePath() {
|
|
120811
|
-
return
|
|
122152
|
+
return join22(this.basePath, "active.json");
|
|
120812
122153
|
}
|
|
120813
122154
|
assistantConfigPath(id) {
|
|
120814
|
-
return
|
|
122155
|
+
return join22(this.assistantsRoot, id, "config.json");
|
|
120815
122156
|
}
|
|
120816
122157
|
async initialize() {
|
|
120817
|
-
await
|
|
122158
|
+
await mkdir7(this.assistantsRoot, { recursive: true });
|
|
120818
122159
|
const index = await this.readIndex();
|
|
120819
122160
|
for (const id of index.assistants) {
|
|
120820
122161
|
const assistant = await this.readAssistant(id);
|
|
@@ -120865,7 +122206,7 @@ class AssistantManager {
|
|
|
120865
122206
|
if (!this.assistants.has(id)) {
|
|
120866
122207
|
throw new Error(`Assistant ${id} not found`);
|
|
120867
122208
|
}
|
|
120868
|
-
await rm2(
|
|
122209
|
+
await rm2(join22(this.assistantsRoot, id), { recursive: true, force: true });
|
|
120869
122210
|
this.assistants.delete(id);
|
|
120870
122211
|
await this.removeFromIndex(id);
|
|
120871
122212
|
if (this.activeId === id) {
|
|
@@ -120900,7 +122241,7 @@ class AssistantManager {
|
|
|
120900
122241
|
return { assistants: [] };
|
|
120901
122242
|
}
|
|
120902
122243
|
try {
|
|
120903
|
-
const raw = await
|
|
122244
|
+
const raw = await readFile9(this.indexPath, "utf-8");
|
|
120904
122245
|
const data = JSON.parse(raw);
|
|
120905
122246
|
return { assistants: Array.isArray(data.assistants) ? data.assistants : [] };
|
|
120906
122247
|
} catch {
|
|
@@ -120912,34 +122253,34 @@ class AssistantManager {
|
|
|
120912
122253
|
if (!index.assistants.includes(id)) {
|
|
120913
122254
|
index.assistants.push(id);
|
|
120914
122255
|
}
|
|
120915
|
-
await
|
|
122256
|
+
await writeFile9(this.indexPath, JSON.stringify(index, null, 2));
|
|
120916
122257
|
}
|
|
120917
122258
|
async removeFromIndex(id) {
|
|
120918
122259
|
const index = await this.readIndex();
|
|
120919
122260
|
index.assistants = index.assistants.filter((assistantId) => assistantId !== id);
|
|
120920
|
-
await
|
|
122261
|
+
await writeFile9(this.indexPath, JSON.stringify(index, null, 2));
|
|
120921
122262
|
}
|
|
120922
122263
|
async readAssistant(id) {
|
|
120923
122264
|
const configPath = this.assistantConfigPath(id);
|
|
120924
122265
|
if (!existsSync12(configPath))
|
|
120925
122266
|
return null;
|
|
120926
122267
|
try {
|
|
120927
|
-
const raw = await
|
|
122268
|
+
const raw = await readFile9(configPath, "utf-8");
|
|
120928
122269
|
return JSON.parse(raw);
|
|
120929
122270
|
} catch {
|
|
120930
122271
|
return null;
|
|
120931
122272
|
}
|
|
120932
122273
|
}
|
|
120933
122274
|
async persistAssistant(assistant) {
|
|
120934
|
-
const dir =
|
|
120935
|
-
await
|
|
120936
|
-
await
|
|
122275
|
+
const dir = join22(this.assistantsRoot, assistant.id);
|
|
122276
|
+
await mkdir7(dir, { recursive: true });
|
|
122277
|
+
await writeFile9(this.assistantConfigPath(assistant.id), JSON.stringify(assistant, null, 2));
|
|
120937
122278
|
}
|
|
120938
122279
|
async readActive() {
|
|
120939
122280
|
if (!existsSync12(this.activePath))
|
|
120940
122281
|
return null;
|
|
120941
122282
|
try {
|
|
120942
|
-
const raw = await
|
|
122283
|
+
const raw = await readFile9(this.activePath, "utf-8");
|
|
120943
122284
|
const data = JSON.parse(raw);
|
|
120944
122285
|
return data.id || null;
|
|
120945
122286
|
} catch {
|
|
@@ -120948,11 +122289,11 @@ class AssistantManager {
|
|
|
120948
122289
|
}
|
|
120949
122290
|
async setActive(id) {
|
|
120950
122291
|
this.activeId = id;
|
|
120951
|
-
await
|
|
122292
|
+
await writeFile9(this.activePath, JSON.stringify({ id }, null, 2));
|
|
120952
122293
|
}
|
|
120953
122294
|
}
|
|
120954
122295
|
// packages/core/src/inbox/inbox-manager.ts
|
|
120955
|
-
import { join as
|
|
122296
|
+
import { join as join25 } from "path";
|
|
120956
122297
|
|
|
120957
122298
|
// node_modules/.pnpm/@aws-sdk+middleware-expect-continue@3.972.3/node_modules/@aws-sdk/middleware-expect-continue/dist-es/index.js
|
|
120958
122299
|
var import_protocol_http = __toESM(require_dist_cjs2(), 1);
|
|
@@ -129810,8 +131151,8 @@ class S3InboxClient {
|
|
|
129810
131151
|
}
|
|
129811
131152
|
|
|
129812
131153
|
// packages/core/src/inbox/storage/local-cache.ts
|
|
129813
|
-
import { join as
|
|
129814
|
-
import { mkdir as
|
|
131154
|
+
import { join as join24 } from "path";
|
|
131155
|
+
import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile11, rm as rm3, readdir as readdir4, stat as stat2 } from "fs/promises";
|
|
129815
131156
|
|
|
129816
131157
|
class LocalInboxCache {
|
|
129817
131158
|
agentId;
|
|
@@ -129821,18 +131162,18 @@ class LocalInboxCache {
|
|
|
129821
131162
|
constructor(options) {
|
|
129822
131163
|
this.agentId = options.agentId;
|
|
129823
131164
|
this.basePath = options.basePath;
|
|
129824
|
-
this.cacheDir =
|
|
131165
|
+
this.cacheDir = join24(this.basePath, this.agentId);
|
|
129825
131166
|
}
|
|
129826
131167
|
async ensureDirectories() {
|
|
129827
|
-
await
|
|
129828
|
-
await
|
|
131168
|
+
await mkdir8(join24(this.cacheDir, "emails"), { recursive: true });
|
|
131169
|
+
await mkdir8(join24(this.cacheDir, "attachments"), { recursive: true });
|
|
129829
131170
|
}
|
|
129830
131171
|
async loadIndex() {
|
|
129831
131172
|
if (this.index)
|
|
129832
131173
|
return this.index;
|
|
129833
131174
|
try {
|
|
129834
|
-
const indexPath =
|
|
129835
|
-
const content = await
|
|
131175
|
+
const indexPath = join24(this.cacheDir, "index.json");
|
|
131176
|
+
const content = await readFile11(indexPath, "utf-8");
|
|
129836
131177
|
this.index = JSON.parse(content);
|
|
129837
131178
|
return this.index;
|
|
129838
131179
|
} catch {
|
|
@@ -129844,13 +131185,13 @@ class LocalInboxCache {
|
|
|
129844
131185
|
if (!this.index)
|
|
129845
131186
|
return;
|
|
129846
131187
|
await this.ensureDirectories();
|
|
129847
|
-
const indexPath =
|
|
129848
|
-
await
|
|
131188
|
+
const indexPath = join24(this.cacheDir, "index.json");
|
|
131189
|
+
await writeFile11(indexPath, JSON.stringify(this.index, null, 2));
|
|
129849
131190
|
}
|
|
129850
131191
|
async saveEmail(email) {
|
|
129851
131192
|
await this.ensureDirectories();
|
|
129852
|
-
const emailPath =
|
|
129853
|
-
await
|
|
131193
|
+
const emailPath = join24(this.cacheDir, "emails", `${email.id}.json`);
|
|
131194
|
+
await writeFile11(emailPath, JSON.stringify(email, null, 2));
|
|
129854
131195
|
const index = await this.loadIndex();
|
|
129855
131196
|
const existingIdx = index.emails.findIndex((e3) => e3.id === email.id);
|
|
129856
131197
|
const entry = {
|
|
@@ -129873,8 +131214,8 @@ class LocalInboxCache {
|
|
|
129873
131214
|
}
|
|
129874
131215
|
async loadEmail(id) {
|
|
129875
131216
|
try {
|
|
129876
|
-
const emailPath =
|
|
129877
|
-
const content = await
|
|
131217
|
+
const emailPath = join24(this.cacheDir, "emails", `${id}.json`);
|
|
131218
|
+
const content = await readFile11(emailPath, "utf-8");
|
|
129878
131219
|
return JSON.parse(content);
|
|
129879
131220
|
} catch {
|
|
129880
131221
|
return null;
|
|
@@ -129925,16 +131266,16 @@ class LocalInboxCache {
|
|
|
129925
131266
|
return new Set(index.emails.map((e3) => e3.id));
|
|
129926
131267
|
}
|
|
129927
131268
|
async saveAttachment(emailId, filename, content) {
|
|
129928
|
-
const attachmentDir =
|
|
129929
|
-
await
|
|
129930
|
-
const attachmentPath =
|
|
129931
|
-
await
|
|
131269
|
+
const attachmentDir = join24(this.cacheDir, "attachments", emailId);
|
|
131270
|
+
await mkdir8(attachmentDir, { recursive: true });
|
|
131271
|
+
const attachmentPath = join24(attachmentDir, filename);
|
|
131272
|
+
await writeFile11(attachmentPath, content);
|
|
129932
131273
|
return attachmentPath;
|
|
129933
131274
|
}
|
|
129934
131275
|
async getAttachmentPath(emailId, filename) {
|
|
129935
131276
|
try {
|
|
129936
|
-
const attachmentPath =
|
|
129937
|
-
await
|
|
131277
|
+
const attachmentPath = join24(this.cacheDir, "attachments", emailId, filename);
|
|
131278
|
+
await stat2(attachmentPath);
|
|
129938
131279
|
return attachmentPath;
|
|
129939
131280
|
} catch {
|
|
129940
131281
|
return null;
|
|
@@ -129962,10 +131303,10 @@ class LocalInboxCache {
|
|
|
129962
131303
|
for (const id of removed) {
|
|
129963
131304
|
index.emails = index.emails.filter((e3) => e3.id !== id);
|
|
129964
131305
|
try {
|
|
129965
|
-
await rm3(
|
|
131306
|
+
await rm3(join24(this.cacheDir, "emails", `${id}.json`));
|
|
129966
131307
|
} catch {}
|
|
129967
131308
|
try {
|
|
129968
|
-
await rm3(
|
|
131309
|
+
await rm3(join24(this.cacheDir, "attachments", id), { recursive: true });
|
|
129969
131310
|
} catch {}
|
|
129970
131311
|
}
|
|
129971
131312
|
if (removed.length > 0) {
|
|
@@ -129976,20 +131317,20 @@ class LocalInboxCache {
|
|
|
129976
131317
|
async getCacheSize() {
|
|
129977
131318
|
let totalSize = 0;
|
|
129978
131319
|
try {
|
|
129979
|
-
const emailsDir =
|
|
129980
|
-
const files = await
|
|
131320
|
+
const emailsDir = join24(this.cacheDir, "emails");
|
|
131321
|
+
const files = await readdir4(emailsDir);
|
|
129981
131322
|
for (const file of files) {
|
|
129982
|
-
const fileStat = await
|
|
131323
|
+
const fileStat = await stat2(join24(emailsDir, file));
|
|
129983
131324
|
totalSize += fileStat.size;
|
|
129984
131325
|
}
|
|
129985
131326
|
} catch {}
|
|
129986
131327
|
try {
|
|
129987
|
-
const attachmentsDir =
|
|
129988
|
-
const dirs = await
|
|
131328
|
+
const attachmentsDir = join24(this.cacheDir, "attachments");
|
|
131329
|
+
const dirs = await readdir4(attachmentsDir);
|
|
129989
131330
|
for (const dir of dirs) {
|
|
129990
|
-
const files = await
|
|
131331
|
+
const files = await readdir4(join24(attachmentsDir, dir));
|
|
129991
131332
|
for (const file of files) {
|
|
129992
|
-
const fileStat = await
|
|
131333
|
+
const fileStat = await stat2(join24(attachmentsDir, dir, file));
|
|
129993
131334
|
totalSize += fileStat.size;
|
|
129994
131335
|
}
|
|
129995
131336
|
}
|
|
@@ -132576,7 +133917,7 @@ class InboxManager {
|
|
|
132576
133917
|
}
|
|
132577
133918
|
}
|
|
132578
133919
|
function createInboxManager(agentId, agentName, config, configDir) {
|
|
132579
|
-
const basePath =
|
|
133920
|
+
const basePath = join25(configDir, "inbox");
|
|
132580
133921
|
return new InboxManager({
|
|
132581
133922
|
agentId,
|
|
132582
133923
|
agentName,
|
|
@@ -134741,10 +136082,12 @@ class AgentLoop {
|
|
|
134741
136082
|
identityManager = null;
|
|
134742
136083
|
inboxManager = null;
|
|
134743
136084
|
walletManager = null;
|
|
136085
|
+
jobManager = null;
|
|
134744
136086
|
identityContext = null;
|
|
134745
136087
|
projectContext = null;
|
|
134746
136088
|
activeProjectId = null;
|
|
134747
136089
|
assistantId = null;
|
|
136090
|
+
askUserHandler = null;
|
|
134748
136091
|
onChunk;
|
|
134749
136092
|
onToolStart;
|
|
134750
136093
|
onToolEnd;
|
|
@@ -134823,6 +136166,9 @@ class AgentLoop {
|
|
|
134823
136166
|
FilesystemTools.registerAll(this.toolRegistry, this.sessionId);
|
|
134824
136167
|
WebTools.registerAll(this.toolRegistry);
|
|
134825
136168
|
ImageTools.registerAll(this.toolRegistry);
|
|
136169
|
+
this.toolRegistry.register(SkillTool.tool, SkillTool.executor);
|
|
136170
|
+
const askUserTool = createAskUserTool(() => this.askUserHandler);
|
|
136171
|
+
this.toolRegistry.register(askUserTool.tool, askUserTool.executor);
|
|
134826
136172
|
this.toolRegistry.register(FeedbackTool.tool, FeedbackTool.executor);
|
|
134827
136173
|
this.toolRegistry.register(SchedulerTool.tool, SchedulerTool.executor);
|
|
134828
136174
|
if (this.config?.inbox?.enabled) {
|
|
@@ -134838,6 +136184,22 @@ class AgentLoop {
|
|
|
134838
136184
|
this.walletManager = createWalletManager(agentId, this.config.wallet);
|
|
134839
136185
|
registerWalletTools(this.toolRegistry, () => this.walletManager);
|
|
134840
136186
|
}
|
|
136187
|
+
if (this.config?.jobs?.enabled !== false) {
|
|
136188
|
+
this.jobManager = new JobManager(this.config?.jobs || {}, this.sessionId);
|
|
136189
|
+
this.jobManager.onJobComplete((event) => {
|
|
136190
|
+
const statusEmoji = event.status === "completed" ? "\u2713" : event.status === "failed" ? "\u2717" : "\u26A0";
|
|
136191
|
+
const message = `
|
|
136192
|
+
[Job ${event.status}] ${event.connector} (${event.jobId}): ${event.summary}
|
|
136193
|
+
`;
|
|
136194
|
+
this.emit({ type: "text", content: message });
|
|
136195
|
+
});
|
|
136196
|
+
const jobTools = createJobTools(() => this.jobManager);
|
|
136197
|
+
for (const { tool, executor } of jobTools) {
|
|
136198
|
+
this.toolRegistry.register(tool, executor);
|
|
136199
|
+
}
|
|
136200
|
+
this.connectorBridge.setJobManagerGetter(() => this.jobManager);
|
|
136201
|
+
this.jobManager.cleanup().catch(() => {});
|
|
136202
|
+
}
|
|
134841
136203
|
this.connectorBridge.registerAll(this.toolRegistry);
|
|
134842
136204
|
this.builtinCommands.registerAll(this.commandLoader);
|
|
134843
136205
|
this.hookLoader.load(hooksConfig);
|
|
@@ -135311,6 +136673,9 @@ class AgentLoop {
|
|
|
135311
136673
|
this.identityContext = await this.identityManager.buildSystemPromptContext();
|
|
135312
136674
|
}
|
|
135313
136675
|
},
|
|
136676
|
+
refreshSkills: async () => {
|
|
136677
|
+
await this.skillLoader.loadAll(this.cwd);
|
|
136678
|
+
},
|
|
135314
136679
|
switchAssistant: async (assistantId) => {
|
|
135315
136680
|
await this.switchAssistant(assistantId);
|
|
135316
136681
|
},
|
|
@@ -135530,6 +136895,9 @@ ${content.trim()}`);
|
|
|
135530
136895
|
}
|
|
135531
136896
|
this.contextManager?.refreshState(this.context.getMessages());
|
|
135532
136897
|
}
|
|
136898
|
+
setAskUserHandler(handler) {
|
|
136899
|
+
this.askUserHandler = handler;
|
|
136900
|
+
}
|
|
135533
136901
|
clearConversation() {
|
|
135534
136902
|
this.resetContext();
|
|
135535
136903
|
}
|
|
@@ -135541,7 +136909,7 @@ ${content.trim()}`);
|
|
|
135541
136909
|
const heartbeatConfig = this.buildHeartbeatConfig(this.config);
|
|
135542
136910
|
if (!heartbeatConfig)
|
|
135543
136911
|
return;
|
|
135544
|
-
const statePath =
|
|
136912
|
+
const statePath = join26(getConfigDir(), "state", `${this.sessionId}.json`);
|
|
135545
136913
|
this.heartbeatManager = new HeartbeatManager(heartbeatConfig);
|
|
135546
136914
|
this.heartbeatPersistence = new StatePersistence(statePath);
|
|
135547
136915
|
this.heartbeatRecovery = new RecoveryManager(this.heartbeatPersistence, heartbeatConfig.persistPath, heartbeatConfig.staleThresholdMs, {
|
|
@@ -135590,7 +136958,7 @@ ${content.trim()}`);
|
|
|
135590
136958
|
async startEnergySystem() {
|
|
135591
136959
|
if (!this.config || this.config.energy?.enabled === false)
|
|
135592
136960
|
return;
|
|
135593
|
-
const statePath =
|
|
136961
|
+
const statePath = join26(getConfigDir(), "energy", "state.json");
|
|
135594
136962
|
this.energyManager = new EnergyManager(this.config.energy, new EnergyStorage(statePath));
|
|
135595
136963
|
await this.energyManager.initialize();
|
|
135596
136964
|
this.refreshEnergyEffects();
|
|
@@ -135841,7 +137209,7 @@ ${this.identityContext}`);
|
|
|
135841
137209
|
return null;
|
|
135842
137210
|
const intervalMs = Math.max(1000, config.heartbeat?.intervalMs ?? 15000);
|
|
135843
137211
|
const staleThresholdMs = Math.max(intervalMs * 2, config.heartbeat?.staleThresholdMs ?? 120000);
|
|
135844
|
-
const persistPath = config.heartbeat?.persistPath ??
|
|
137212
|
+
const persistPath = config.heartbeat?.persistPath ?? join26(getConfigDir(), "heartbeats", `${this.sessionId}.json`);
|
|
135845
137213
|
return {
|
|
135846
137214
|
intervalMs,
|
|
135847
137215
|
staleThresholdMs,
|
|
@@ -135909,12 +137277,19 @@ ${this.identityContext}`);
|
|
|
135909
137277
|
const allowed = this.getEffectiveAllowedTools();
|
|
135910
137278
|
if (!allowed)
|
|
135911
137279
|
return tools;
|
|
135912
|
-
return tools.filter((tool) =>
|
|
137280
|
+
return tools.filter((tool) => {
|
|
137281
|
+
const name2 = tool.name.toLowerCase();
|
|
137282
|
+
if (name2 === "ask_user")
|
|
137283
|
+
return true;
|
|
137284
|
+
return allowed.has(name2);
|
|
137285
|
+
});
|
|
135913
137286
|
}
|
|
135914
137287
|
isToolAllowed(name2) {
|
|
135915
137288
|
const allowed = this.getEffectiveAllowedTools();
|
|
135916
137289
|
if (!allowed)
|
|
135917
137290
|
return true;
|
|
137291
|
+
if (name2.toLowerCase() === "ask_user")
|
|
137292
|
+
return true;
|
|
135918
137293
|
return allowed.has(name2.toLowerCase());
|
|
135919
137294
|
}
|
|
135920
137295
|
}
|
|
@@ -135938,17 +137313,17 @@ init_src();
|
|
|
135938
137313
|
|
|
135939
137314
|
// packages/core/src/logger.ts
|
|
135940
137315
|
import { existsSync as existsSync13, mkdirSync as mkdirSync8, appendFileSync, readdirSync as readdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
135941
|
-
import { join as
|
|
137316
|
+
import { join as join27 } from "path";
|
|
135942
137317
|
class Logger {
|
|
135943
137318
|
logDir;
|
|
135944
137319
|
logFile;
|
|
135945
137320
|
sessionId;
|
|
135946
137321
|
constructor(sessionId, basePath) {
|
|
135947
137322
|
this.sessionId = sessionId;
|
|
135948
|
-
this.logDir =
|
|
137323
|
+
this.logDir = join27(basePath || getConfigDir(), "logs");
|
|
135949
137324
|
this.ensureDir(this.logDir);
|
|
135950
137325
|
const date = new Date().toISOString().split("T")[0];
|
|
135951
|
-
this.logFile =
|
|
137326
|
+
this.logFile = join27(this.logDir, `${date}.log`);
|
|
135952
137327
|
}
|
|
135953
137328
|
ensureDir(dir) {
|
|
135954
137329
|
if (!existsSync13(dir)) {
|
|
@@ -135992,9 +137367,9 @@ class SessionStorage {
|
|
|
135992
137367
|
constructor(sessionId, basePath, assistantId) {
|
|
135993
137368
|
this.sessionId = sessionId;
|
|
135994
137369
|
const root = basePath || getConfigDir();
|
|
135995
|
-
this.sessionsDir = assistantId ?
|
|
137370
|
+
this.sessionsDir = assistantId ? join27(root, "assistants", assistantId, "sessions") : join27(root, "sessions");
|
|
135996
137371
|
this.ensureDir(this.sessionsDir);
|
|
135997
|
-
this.sessionFile =
|
|
137372
|
+
this.sessionFile = join27(this.sessionsDir, `${sessionId}.json`);
|
|
135998
137373
|
}
|
|
135999
137374
|
ensureDir(dir) {
|
|
136000
137375
|
if (!existsSync13(dir)) {
|
|
@@ -136020,7 +137395,7 @@ class SessionStorage {
|
|
|
136020
137395
|
}
|
|
136021
137396
|
static getActiveAssistantId() {
|
|
136022
137397
|
try {
|
|
136023
|
-
const activePath =
|
|
137398
|
+
const activePath = join27(getConfigDir(), "active.json");
|
|
136024
137399
|
if (!existsSync13(activePath))
|
|
136025
137400
|
return null;
|
|
136026
137401
|
const raw = readFileSync9(activePath, "utf-8");
|
|
@@ -136034,12 +137409,12 @@ class SessionStorage {
|
|
|
136034
137409
|
const root = getConfigDir();
|
|
136035
137410
|
const resolvedId = assistantId ?? SessionStorage.getActiveAssistantId();
|
|
136036
137411
|
if (resolvedId) {
|
|
136037
|
-
const assistantDir =
|
|
137412
|
+
const assistantDir = join27(root, "assistants", resolvedId, "sessions");
|
|
136038
137413
|
if (existsSync13(assistantDir)) {
|
|
136039
137414
|
return assistantDir;
|
|
136040
137415
|
}
|
|
136041
137416
|
}
|
|
136042
|
-
return
|
|
137417
|
+
return join27(root, "sessions");
|
|
136043
137418
|
}
|
|
136044
137419
|
static listSessions(assistantId) {
|
|
136045
137420
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
@@ -136051,8 +137426,8 @@ class SessionStorage {
|
|
|
136051
137426
|
if (!file.endsWith(".json"))
|
|
136052
137427
|
continue;
|
|
136053
137428
|
try {
|
|
136054
|
-
const filePath =
|
|
136055
|
-
const
|
|
137429
|
+
const filePath = join27(sessionsDir, file);
|
|
137430
|
+
const stat3 = Bun.file(filePath);
|
|
136056
137431
|
const content = JSON.parse(readFileSync9(filePath, "utf-8"));
|
|
136057
137432
|
sessions.push({
|
|
136058
137433
|
id: file.replace(".json", ""),
|
|
@@ -136071,7 +137446,7 @@ class SessionStorage {
|
|
|
136071
137446
|
}
|
|
136072
137447
|
static loadSession(sessionId, assistantId) {
|
|
136073
137448
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
136074
|
-
const sessionFile =
|
|
137449
|
+
const sessionFile = join27(sessionsDir, `${sessionId}.json`);
|
|
136075
137450
|
try {
|
|
136076
137451
|
if (!existsSync13(sessionFile))
|
|
136077
137452
|
return null;
|
|
@@ -136085,15 +137460,15 @@ function initAssistantsDir() {
|
|
|
136085
137460
|
const baseDir = getConfigDir();
|
|
136086
137461
|
const dirs = [
|
|
136087
137462
|
baseDir,
|
|
136088
|
-
|
|
136089
|
-
|
|
136090
|
-
|
|
136091
|
-
|
|
136092
|
-
|
|
136093
|
-
|
|
136094
|
-
|
|
136095
|
-
|
|
136096
|
-
|
|
137463
|
+
join27(baseDir, "logs"),
|
|
137464
|
+
join27(baseDir, "assistants"),
|
|
137465
|
+
join27(baseDir, "shared", "skills"),
|
|
137466
|
+
join27(baseDir, "commands"),
|
|
137467
|
+
join27(baseDir, "temp"),
|
|
137468
|
+
join27(baseDir, "heartbeats"),
|
|
137469
|
+
join27(baseDir, "state"),
|
|
137470
|
+
join27(baseDir, "energy"),
|
|
137471
|
+
join27(baseDir, "migration")
|
|
136097
137472
|
];
|
|
136098
137473
|
for (const dir of dirs) {
|
|
136099
137474
|
if (!existsSync13(dir)) {
|
|
@@ -136255,6 +137630,11 @@ class EmbeddedClient {
|
|
|
136255
137630
|
onError(callback) {
|
|
136256
137631
|
this.errorCallbacks.push(callback);
|
|
136257
137632
|
}
|
|
137633
|
+
setAskUserHandler(handler) {
|
|
137634
|
+
if (typeof this.agent.setAskUserHandler === "function") {
|
|
137635
|
+
this.agent.setAskUserHandler(handler);
|
|
137636
|
+
}
|
|
137637
|
+
}
|
|
136258
137638
|
async getTools() {
|
|
136259
137639
|
if (!this.initialized) {
|
|
136260
137640
|
await this.initialize();
|
|
@@ -136610,6 +137990,7 @@ var COMMANDS = [
|
|
|
136610
137990
|
{ name: "/cost", description: "show estimated API cost" },
|
|
136611
137991
|
{ name: "/model", description: "show model information" },
|
|
136612
137992
|
{ name: "/skills", description: "list available skills" },
|
|
137993
|
+
{ name: "/skill", description: "create or manage skills" },
|
|
136613
137994
|
{ name: "/config", description: "show configuration" },
|
|
136614
137995
|
{ name: "/projects", description: "manage projects in this folder" },
|
|
136615
137996
|
{ name: "/plans", description: "manage project plans" },
|
|
@@ -136626,7 +138007,15 @@ var COMMANDS = [
|
|
|
136626
138007
|
{ name: "/resume", description: "resume a scheduled command" },
|
|
136627
138008
|
{ name: "/exit", description: "exit assistants" }
|
|
136628
138009
|
];
|
|
136629
|
-
function Input({
|
|
138010
|
+
function Input({
|
|
138011
|
+
onSubmit,
|
|
138012
|
+
isProcessing,
|
|
138013
|
+
queueLength = 0,
|
|
138014
|
+
commands: commands3,
|
|
138015
|
+
skills = [],
|
|
138016
|
+
isAskingUser = false,
|
|
138017
|
+
askPlaceholder
|
|
138018
|
+
}) {
|
|
136630
138019
|
const [value, setValue] = import_react30.useState("");
|
|
136631
138020
|
const [selectedIndex, setSelectedIndex] = import_react30.useState(0);
|
|
136632
138021
|
const allCommands = import_react30.useMemo(() => {
|
|
@@ -136641,6 +138030,8 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands: commands3, s
|
|
|
136641
138030
|
return merged.sort((a5, b7) => a5.name.localeCompare(b7.name));
|
|
136642
138031
|
}, [commands3]);
|
|
136643
138032
|
const autocompleteMode = import_react30.useMemo(() => {
|
|
138033
|
+
if (isAskingUser)
|
|
138034
|
+
return null;
|
|
136644
138035
|
if (value.startsWith("$") && !value.includes(" ")) {
|
|
136645
138036
|
return "skill";
|
|
136646
138037
|
}
|
|
@@ -136670,6 +138061,9 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands: commands3, s
|
|
|
136670
138061
|
setSelectedIndex((prev) => Math.min(prev, autocompleteItems.length - 1));
|
|
136671
138062
|
}, [autocompleteItems.length]);
|
|
136672
138063
|
use_input_default((input, key) => {
|
|
138064
|
+
if (isAskingUser) {
|
|
138065
|
+
return;
|
|
138066
|
+
}
|
|
136673
138067
|
if (key.tab) {
|
|
136674
138068
|
if (autocompleteItems.length > 0) {
|
|
136675
138069
|
const selected = autocompleteItems[selectedIndex] || autocompleteItems[0];
|
|
@@ -136735,7 +138129,9 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands: commands3, s
|
|
|
136735
138129
|
setSelectedIndex(0);
|
|
136736
138130
|
};
|
|
136737
138131
|
let placeholder = "Type a message...";
|
|
136738
|
-
if (
|
|
138132
|
+
if (isAskingUser) {
|
|
138133
|
+
placeholder = askPlaceholder || "Answer the question...";
|
|
138134
|
+
} else if (isProcessing) {
|
|
136739
138135
|
placeholder = queueLength > 0 ? "Type to queue (Tab) or interrupt (Shift+Enter)..." : "Type to interrupt (Shift+Enter)...";
|
|
136740
138136
|
}
|
|
136741
138137
|
const truncateDescription = (desc, maxLen = 60) => {
|
|
@@ -136807,7 +138203,7 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands: commands3, s
|
|
|
136807
138203
|
children: "-".repeat(terminalWidth)
|
|
136808
138204
|
}, undefined, false, undefined, this)
|
|
136809
138205
|
}, undefined, false, undefined, this),
|
|
136810
|
-
isProcessing && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
138206
|
+
isProcessing && !isAskingUser && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
136811
138207
|
marginLeft: 2,
|
|
136812
138208
|
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
136813
138209
|
dimColor: true,
|
|
@@ -138322,6 +139718,8 @@ function getToolDisplayName(toolCall) {
|
|
|
138322
139718
|
return "schedule";
|
|
138323
139719
|
case "submit_feedback":
|
|
138324
139720
|
return "feedback";
|
|
139721
|
+
case "ask_user":
|
|
139722
|
+
return "ask";
|
|
138325
139723
|
case "notion":
|
|
138326
139724
|
case "gmail":
|
|
138327
139725
|
case "googledrive":
|
|
@@ -138356,6 +139754,12 @@ function formatToolCall(toolCall) {
|
|
|
138356
139754
|
return formatScheduleCall(input);
|
|
138357
139755
|
case "submit_feedback":
|
|
138358
139756
|
return formatFeedbackCall(input);
|
|
139757
|
+
case "ask_user": {
|
|
139758
|
+
const title = String(input.title || "");
|
|
139759
|
+
const question = Array.isArray(input.questions) && input.questions[0]?.question ? String(input.questions[0].question) : "";
|
|
139760
|
+
const label = title || question || "asking user";
|
|
139761
|
+
return `Asking: ${truncate(label, 60)}`;
|
|
139762
|
+
}
|
|
138359
139763
|
case "notion":
|
|
138360
139764
|
return `Notion: ${truncate(String(input.command || input.action || ""), 60)}`;
|
|
138361
139765
|
case "gmail":
|
|
@@ -139085,8 +140489,87 @@ function QueueIndicator({
|
|
|
139085
140489
|
}, undefined, true, undefined, this);
|
|
139086
140490
|
}
|
|
139087
140491
|
|
|
139088
|
-
// packages/terminal/src/components/
|
|
140492
|
+
// packages/terminal/src/components/AskUserPanel.tsx
|
|
139089
140493
|
var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
|
|
140494
|
+
function AskUserPanel({
|
|
140495
|
+
sessionId,
|
|
140496
|
+
request: request2,
|
|
140497
|
+
question,
|
|
140498
|
+
index,
|
|
140499
|
+
total
|
|
140500
|
+
}) {
|
|
140501
|
+
return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140502
|
+
flexDirection: "column",
|
|
140503
|
+
borderStyle: "round",
|
|
140504
|
+
borderColor: "cyan",
|
|
140505
|
+
paddingX: 1,
|
|
140506
|
+
marginY: 1,
|
|
140507
|
+
children: [
|
|
140508
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140509
|
+
justifyContent: "space-between",
|
|
140510
|
+
children: [
|
|
140511
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140512
|
+
color: "cyan",
|
|
140513
|
+
bold: true,
|
|
140514
|
+
children: request2.title || "Question"
|
|
140515
|
+
}, undefined, false, undefined, this),
|
|
140516
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140517
|
+
dimColor: true,
|
|
140518
|
+
children: [
|
|
140519
|
+
index + 1,
|
|
140520
|
+
"/",
|
|
140521
|
+
total
|
|
140522
|
+
]
|
|
140523
|
+
}, undefined, true, undefined, this)
|
|
140524
|
+
]
|
|
140525
|
+
}, undefined, true, undefined, this),
|
|
140526
|
+
request2.description && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140527
|
+
marginTop: 1,
|
|
140528
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140529
|
+
dimColor: true,
|
|
140530
|
+
children: request2.description
|
|
140531
|
+
}, undefined, false, undefined, this)
|
|
140532
|
+
}, undefined, false, undefined, this),
|
|
140533
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140534
|
+
marginTop: 1,
|
|
140535
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140536
|
+
children: question.question
|
|
140537
|
+
}, undefined, false, undefined, this)
|
|
140538
|
+
}, undefined, false, undefined, this),
|
|
140539
|
+
question.options && question.options.length > 0 && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140540
|
+
flexDirection: "column",
|
|
140541
|
+
marginTop: 1,
|
|
140542
|
+
children: question.options.map((opt, idx) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140543
|
+
dimColor: true,
|
|
140544
|
+
children: [
|
|
140545
|
+
"\u2022 ",
|
|
140546
|
+
opt
|
|
140547
|
+
]
|
|
140548
|
+
}, `${opt}-${idx}`, true, undefined, this))
|
|
140549
|
+
}, undefined, false, undefined, this),
|
|
140550
|
+
question.multiline && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140551
|
+
marginTop: 1,
|
|
140552
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140553
|
+
dimColor: true,
|
|
140554
|
+
children: "Multi-line answer allowed. Paste text and press Enter."
|
|
140555
|
+
}, undefined, false, undefined, this)
|
|
140556
|
+
}, undefined, false, undefined, this),
|
|
140557
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
140558
|
+
marginTop: 1,
|
|
140559
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
140560
|
+
dimColor: true,
|
|
140561
|
+
children: [
|
|
140562
|
+
"Session: ",
|
|
140563
|
+
sessionId
|
|
140564
|
+
]
|
|
140565
|
+
}, undefined, true, undefined, this)
|
|
140566
|
+
}, undefined, false, undefined, this)
|
|
140567
|
+
]
|
|
140568
|
+
}, undefined, true, undefined, this);
|
|
140569
|
+
}
|
|
140570
|
+
|
|
140571
|
+
// packages/terminal/src/components/App.tsx
|
|
140572
|
+
var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
|
|
139090
140573
|
var SHOW_ERROR_CODES = process.env.ASSISTANTS_DEBUG === "1";
|
|
139091
140574
|
function formatElapsedDuration(ms2) {
|
|
139092
140575
|
const totalSeconds = Math.max(0, Math.floor(ms2 / 1000));
|
|
@@ -139122,6 +140605,7 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139122
140605
|
const [voiceState, setVoiceState] = import_react36.useState();
|
|
139123
140606
|
const [identityInfo, setIdentityInfo] = import_react36.useState();
|
|
139124
140607
|
const [verboseTools, setVerboseTools] = import_react36.useState(false);
|
|
140608
|
+
const [askUserState, setAskUserState] = import_react36.useState(null);
|
|
139125
140609
|
const [processingStartTime, setProcessingStartTime] = import_react36.useState();
|
|
139126
140610
|
const [currentTurnTokens, setCurrentTurnTokens] = import_react36.useState(0);
|
|
139127
140611
|
const [scrollOffset, setScrollOffset] = import_react36.useState(0);
|
|
@@ -139137,12 +140621,60 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139137
140621
|
const isProcessingRef = import_react36.useRef(isProcessing);
|
|
139138
140622
|
const processingStartTimeRef = import_react36.useRef(processingStartTime);
|
|
139139
140623
|
const pendingSendsRef = import_react36.useRef([]);
|
|
140624
|
+
const askUserStateRef = import_react36.useRef(null);
|
|
139140
140625
|
const updateScrollMetrics = import_react36.useCallback((offset) => {
|
|
139141
140626
|
const currentOffset = typeof offset === "number" ? offset : scrollRef.current?.getScrollOffset() ?? 0;
|
|
139142
140627
|
const bottomOffset = scrollRef.current?.getBottomOffset() ?? 0;
|
|
139143
140628
|
setScrollOffset(currentOffset);
|
|
139144
140629
|
setAutoScroll(currentOffset >= Math.max(0, bottomOffset - 1));
|
|
139145
140630
|
}, []);
|
|
140631
|
+
const beginAskUser = import_react36.useCallback((sessionId, request2) => {
|
|
140632
|
+
return new Promise((resolve5, reject) => {
|
|
140633
|
+
if (askUserStateRef.current) {
|
|
140634
|
+
reject(new Error("Another interview is already in progress."));
|
|
140635
|
+
return;
|
|
140636
|
+
}
|
|
140637
|
+
const state = {
|
|
140638
|
+
sessionId,
|
|
140639
|
+
request: request2,
|
|
140640
|
+
index: 0,
|
|
140641
|
+
answers: {},
|
|
140642
|
+
resolve: resolve5,
|
|
140643
|
+
reject
|
|
140644
|
+
};
|
|
140645
|
+
askUserStateRef.current = state;
|
|
140646
|
+
setAskUserState(state);
|
|
140647
|
+
});
|
|
140648
|
+
}, []);
|
|
140649
|
+
const cancelAskUser = import_react36.useCallback((reason) => {
|
|
140650
|
+
const current = askUserStateRef.current;
|
|
140651
|
+
if (!current)
|
|
140652
|
+
return;
|
|
140653
|
+
askUserStateRef.current = null;
|
|
140654
|
+
setAskUserState(null);
|
|
140655
|
+
current.reject(new Error(reason));
|
|
140656
|
+
}, []);
|
|
140657
|
+
const submitAskAnswer = import_react36.useCallback((answer) => {
|
|
140658
|
+
setAskUserState((prev) => {
|
|
140659
|
+
if (!prev)
|
|
140660
|
+
return prev;
|
|
140661
|
+
const question = prev.request.questions[prev.index];
|
|
140662
|
+
const answers = { ...prev.answers, [question.id]: answer };
|
|
140663
|
+
const nextIndex = prev.index + 1;
|
|
140664
|
+
if (nextIndex >= prev.request.questions.length) {
|
|
140665
|
+
askUserStateRef.current = null;
|
|
140666
|
+
prev.resolve({ answers });
|
|
140667
|
+
return null;
|
|
140668
|
+
}
|
|
140669
|
+
const nextState = {
|
|
140670
|
+
...prev,
|
|
140671
|
+
index: nextIndex,
|
|
140672
|
+
answers
|
|
140673
|
+
};
|
|
140674
|
+
askUserStateRef.current = nextState;
|
|
140675
|
+
return nextState;
|
|
140676
|
+
});
|
|
140677
|
+
}, []);
|
|
139146
140678
|
import_react36.useEffect(() => {
|
|
139147
140679
|
if (!stdout)
|
|
139148
140680
|
return;
|
|
@@ -139463,6 +140995,7 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139463
140995
|
});
|
|
139464
140996
|
const session = await registry.createSession(cwd2);
|
|
139465
140997
|
setActiveSessionId(session.id);
|
|
140998
|
+
session.client.setAskUserHandler((request2) => beginAskUser(session.id, request2));
|
|
139466
140999
|
await loadSessionMetadata(session);
|
|
139467
141000
|
setEnergyState(session.client.getEnergyState() ?? undefined);
|
|
139468
141001
|
setVoiceState(session.client.getVoiceState() ?? undefined);
|
|
@@ -139477,7 +141010,7 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139477
141010
|
return () => {
|
|
139478
141011
|
registry.closeAll();
|
|
139479
141012
|
};
|
|
139480
|
-
}, [cwd2, registry, handleChunk, finalizeResponse, resetTurnState, loadSessionMetadata]);
|
|
141013
|
+
}, [cwd2, registry, handleChunk, finalizeResponse, resetTurnState, loadSessionMetadata, beginAskUser]);
|
|
139481
141014
|
const processQueue = import_react36.useCallback(async () => {
|
|
139482
141015
|
const activeSession2 = registryRef.current.getActiveSession();
|
|
139483
141016
|
if (!activeSession2 || !activeSessionId)
|
|
@@ -139536,6 +141069,8 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139536
141069
|
const backgroundProcessingCount = registry.getBackgroundProcessingSessions().length;
|
|
139537
141070
|
const MAX_QUEUED_PREVIEW = 3;
|
|
139538
141071
|
const inlineCount = activeInline.length;
|
|
141072
|
+
const activeAskQuestion = askUserState?.request.questions[askUserState.index];
|
|
141073
|
+
const askPlaceholder = activeAskQuestion?.placeholder || activeAskQuestion?.question || "Answer the question...";
|
|
139539
141074
|
const showWelcome = messages.length === 0 && !isProcessing;
|
|
139540
141075
|
const renderWidth = columns ? Math.max(1, columns - 2) : undefined;
|
|
139541
141076
|
const wrapChars = renderWidth ?? MESSAGE_WRAP_CHARS;
|
|
@@ -139588,6 +141123,7 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139588
141123
|
try {
|
|
139589
141124
|
saveCurrentSessionState();
|
|
139590
141125
|
const newSession = await registry.createSession(cwd2);
|
|
141126
|
+
newSession.client.setAskUserHandler((request2) => beginAskUser(newSession.id, request2));
|
|
139591
141127
|
await registry.switchSession(newSession.id);
|
|
139592
141128
|
setActiveSessionId(newSession.id);
|
|
139593
141129
|
loadSessionState(newSession.id);
|
|
@@ -139600,7 +141136,7 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139600
141136
|
} catch (err) {
|
|
139601
141137
|
setError(err instanceof Error ? err.message : "Failed to create session");
|
|
139602
141138
|
}
|
|
139603
|
-
}, [cwd2, registry, saveCurrentSessionState, loadSessionState]);
|
|
141139
|
+
}, [cwd2, registry, saveCurrentSessionState, loadSessionState, beginAskUser]);
|
|
139604
141140
|
const getScrollStep = import_react36.useCallback(() => {
|
|
139605
141141
|
const viewport = scrollRef.current?.getViewportHeight();
|
|
139606
141142
|
const fallback = Math.max(3, rows - 6);
|
|
@@ -139615,6 +141151,9 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139615
141151
|
return;
|
|
139616
141152
|
}
|
|
139617
141153
|
if (key.ctrl && input === "c") {
|
|
141154
|
+
if (askUserStateRef.current) {
|
|
141155
|
+
cancelAskUser("Cancelled by user");
|
|
141156
|
+
}
|
|
139618
141157
|
if (isProcessing && activeSession) {
|
|
139619
141158
|
activeSession.client.stop();
|
|
139620
141159
|
const finalized = finalizeResponse("stopped");
|
|
@@ -139635,6 +141174,9 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139635
141174
|
return;
|
|
139636
141175
|
}
|
|
139637
141176
|
if (key.escape) {
|
|
141177
|
+
if (askUserStateRef.current) {
|
|
141178
|
+
cancelAskUser("Cancelled by user");
|
|
141179
|
+
}
|
|
139638
141180
|
if (isProcessing && activeSession) {
|
|
139639
141181
|
activeSession.client.stop();
|
|
139640
141182
|
const finalized = finalizeResponse("stopped");
|
|
@@ -139672,6 +141214,10 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139672
141214
|
setAutoScroll(true);
|
|
139673
141215
|
}, [activeSessionId]);
|
|
139674
141216
|
const handleSubmit = import_react36.useCallback(async (input, mode = "normal") => {
|
|
141217
|
+
if (askUserStateRef.current) {
|
|
141218
|
+
submitAskAnswer(input.trim());
|
|
141219
|
+
return;
|
|
141220
|
+
}
|
|
139675
141221
|
if (!activeSession || !input.trim())
|
|
139676
141222
|
return;
|
|
139677
141223
|
const trimmedInput = input.trim();
|
|
@@ -139793,24 +141339,25 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139793
141339
|
handleSessionSwitch,
|
|
139794
141340
|
finalizeResponse,
|
|
139795
141341
|
resetTurnState,
|
|
139796
|
-
activeSessionId
|
|
141342
|
+
activeSessionId,
|
|
141343
|
+
submitAskAnswer
|
|
139797
141344
|
]);
|
|
139798
141345
|
if (isInitializing) {
|
|
139799
|
-
return /* @__PURE__ */
|
|
141346
|
+
return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
139800
141347
|
flexDirection: "column",
|
|
139801
141348
|
padding: 1,
|
|
139802
141349
|
height: rows,
|
|
139803
|
-
children: /* @__PURE__ */
|
|
141350
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Spinner2, {
|
|
139804
141351
|
label: "Initializing..."
|
|
139805
141352
|
}, undefined, false, undefined, this)
|
|
139806
141353
|
}, undefined, false, undefined, this);
|
|
139807
141354
|
}
|
|
139808
141355
|
if (showSessionSelector) {
|
|
139809
|
-
return /* @__PURE__ */
|
|
141356
|
+
return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
139810
141357
|
flexDirection: "column",
|
|
139811
141358
|
padding: 1,
|
|
139812
141359
|
height: rows,
|
|
139813
|
-
children: /* @__PURE__ */
|
|
141360
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SessionSelector, {
|
|
139814
141361
|
sessions,
|
|
139815
141362
|
activeSessionId,
|
|
139816
141363
|
onSelect: handleSessionSwitch,
|
|
@@ -139824,19 +141371,19 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139824
141371
|
return { toolCall: e6.toolCall, result };
|
|
139825
141372
|
});
|
|
139826
141373
|
const isThinking = isProcessing && !currentResponse && !currentToolCall && toolCallEntries.length === 0;
|
|
139827
|
-
return /* @__PURE__ */
|
|
141374
|
+
return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
139828
141375
|
flexDirection: "column",
|
|
139829
141376
|
padding: 1,
|
|
139830
141377
|
height: rows,
|
|
139831
141378
|
children: [
|
|
139832
|
-
showWelcome && /* @__PURE__ */
|
|
141379
|
+
showWelcome && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(WelcomeBanner, {
|
|
139833
141380
|
version: version2 ?? "unknown",
|
|
139834
141381
|
model: activeSession?.client.getModel() ?? "unknown",
|
|
139835
141382
|
directory: activeSession?.cwd || cwd2
|
|
139836
141383
|
}, undefined, false, undefined, this),
|
|
139837
|
-
backgroundProcessingCount > 0 && /* @__PURE__ */
|
|
141384
|
+
backgroundProcessingCount > 0 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
139838
141385
|
marginBottom: 1,
|
|
139839
|
-
children: /* @__PURE__ */
|
|
141386
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
139840
141387
|
color: "yellow",
|
|
139841
141388
|
children: [
|
|
139842
141389
|
backgroundProcessingCount,
|
|
@@ -139846,8 +141393,8 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139846
141393
|
]
|
|
139847
141394
|
}, undefined, true, undefined, this)
|
|
139848
141395
|
}, undefined, false, undefined, this),
|
|
139849
|
-
scrollOffset > 0 && /* @__PURE__ */
|
|
139850
|
-
children: /* @__PURE__ */
|
|
141396
|
+
scrollOffset > 0 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
141397
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
139851
141398
|
dimColor: true,
|
|
139852
141399
|
children: [
|
|
139853
141400
|
"\u2191 ",
|
|
@@ -139856,16 +141403,16 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139856
141403
|
]
|
|
139857
141404
|
}, undefined, true, undefined, this)
|
|
139858
141405
|
}, undefined, false, undefined, this),
|
|
139859
|
-
/* @__PURE__ */
|
|
141406
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
139860
141407
|
flexGrow: 1,
|
|
139861
141408
|
flexShrink: 1,
|
|
139862
141409
|
minHeight: 1,
|
|
139863
|
-
children: /* @__PURE__ */
|
|
141410
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ScrollView, {
|
|
139864
141411
|
ref: scrollRef,
|
|
139865
141412
|
onScroll: (offset) => updateScrollMetrics(offset),
|
|
139866
141413
|
onContentHeightChange: () => updateScrollMetrics(),
|
|
139867
141414
|
onViewportSizeChange: () => updateScrollMetrics(),
|
|
139868
|
-
children: /* @__PURE__ */
|
|
141415
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Messages3, {
|
|
139869
141416
|
messages: displayMessages,
|
|
139870
141417
|
currentResponse: undefined,
|
|
139871
141418
|
streamingMessages,
|
|
@@ -139877,28 +141424,37 @@ function App2({ cwd: cwd2, version: version2 }) {
|
|
|
139877
141424
|
}, activeSessionId || "default", false, undefined, this)
|
|
139878
141425
|
}, undefined, false, undefined, this)
|
|
139879
141426
|
}, undefined, false, undefined, this),
|
|
139880
|
-
/* @__PURE__ */
|
|
141427
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(QueueIndicator, {
|
|
139881
141428
|
messages: [...activeInline, ...activeQueue],
|
|
139882
141429
|
maxPreview: MAX_QUEUED_PREVIEW
|
|
139883
141430
|
}, undefined, false, undefined, this),
|
|
139884
|
-
|
|
141431
|
+
askUserState && activeAskQuestion && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(AskUserPanel, {
|
|
141432
|
+
sessionId: askUserState.sessionId,
|
|
141433
|
+
request: askUserState.request,
|
|
141434
|
+
question: activeAskQuestion,
|
|
141435
|
+
index: askUserState.index,
|
|
141436
|
+
total: askUserState.request.questions.length
|
|
141437
|
+
}, undefined, false, undefined, this),
|
|
141438
|
+
error2 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ErrorBanner, {
|
|
139885
141439
|
error: error2,
|
|
139886
141440
|
showErrorCodes: SHOW_ERROR_CODES
|
|
139887
141441
|
}, undefined, false, undefined, this),
|
|
139888
|
-
/* @__PURE__ */
|
|
141442
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ProcessingIndicator, {
|
|
139889
141443
|
isProcessing,
|
|
139890
141444
|
startTime: processingStartTime,
|
|
139891
141445
|
tokenCount: currentTurnTokens,
|
|
139892
141446
|
isThinking
|
|
139893
141447
|
}, undefined, false, undefined, this),
|
|
139894
|
-
/* @__PURE__ */
|
|
141448
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Input, {
|
|
139895
141449
|
onSubmit: handleSubmit,
|
|
139896
141450
|
isProcessing,
|
|
139897
141451
|
queueLength: activeQueue.length + inlineCount,
|
|
139898
141452
|
commands: commands3,
|
|
139899
|
-
skills
|
|
141453
|
+
skills,
|
|
141454
|
+
isAskingUser: Boolean(activeAskQuestion),
|
|
141455
|
+
askPlaceholder
|
|
139900
141456
|
}, undefined, false, undefined, this),
|
|
139901
|
-
/* @__PURE__ */
|
|
141457
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Status, {
|
|
139902
141458
|
isProcessing,
|
|
139903
141459
|
cwd: activeSession?.cwd || cwd2,
|
|
139904
141460
|
queueLength: activeQueue.length + inlineCount,
|
|
@@ -140091,7 +141647,7 @@ function formatStreamEvent(chunk) {
|
|
|
140091
141647
|
}
|
|
140092
141648
|
|
|
140093
141649
|
// packages/terminal/src/index.tsx
|
|
140094
|
-
var
|
|
141650
|
+
var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
|
|
140095
141651
|
var VERSION3 = "0.6.37";
|
|
140096
141652
|
process.env.ASSISTANTS_VERSION ??= VERSION3;
|
|
140097
141653
|
function parseArgs(argv) {
|
|
@@ -140239,7 +141795,7 @@ if (options.print !== null) {
|
|
|
140239
141795
|
process.exit(1);
|
|
140240
141796
|
});
|
|
140241
141797
|
} else {
|
|
140242
|
-
const { waitUntilExit } = render_default(/* @__PURE__ */
|
|
141798
|
+
const { waitUntilExit } = render_default(/* @__PURE__ */ jsx_dev_runtime13.jsxDEV(App2, {
|
|
140243
141799
|
cwd: options.cwd,
|
|
140244
141800
|
version: VERSION3
|
|
140245
141801
|
}, undefined, false, undefined, this));
|
|
@@ -140248,4 +141804,4 @@ if (options.print !== null) {
|
|
|
140248
141804
|
});
|
|
140249
141805
|
}
|
|
140250
141806
|
|
|
140251
|
-
//# debugId=
|
|
141807
|
+
//# debugId=26B340BF6D9D424564756E2164756E21
|