@hasna/assistants 0.6.32 → 0.6.35
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 +623 -222
- package/dist/index.js.map +27 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17712,14 +17712,13 @@ function sleep(ms) {
|
|
|
17712
17712
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17713
17713
|
}
|
|
17714
17714
|
function parseFrontmatter(content) {
|
|
17715
|
-
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
17715
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
17716
17716
|
if (!match) {
|
|
17717
17717
|
return { frontmatter: {}, content };
|
|
17718
17718
|
}
|
|
17719
17719
|
const [, yamlContent, markdownContent] = match;
|
|
17720
17720
|
const frontmatter = {};
|
|
17721
|
-
const lines = yamlContent.split(
|
|
17722
|
-
`);
|
|
17721
|
+
const lines = yamlContent.split(/\r?\n/);
|
|
17723
17722
|
for (const line of lines) {
|
|
17724
17723
|
const colonIndex = line.indexOf(":");
|
|
17725
17724
|
if (colonIndex === -1)
|
|
@@ -28327,14 +28326,14 @@ var exports_anthropic = {};
|
|
|
28327
28326
|
__export(exports_anthropic, {
|
|
28328
28327
|
AnthropicClient: () => AnthropicClient
|
|
28329
28328
|
});
|
|
28330
|
-
import { readFileSync as readFileSync4, existsSync as
|
|
28331
|
-
import { homedir as
|
|
28332
|
-
import { join as
|
|
28329
|
+
import { readFileSync as readFileSync4, existsSync as existsSync9 } from "fs";
|
|
28330
|
+
import { homedir as homedir11 } from "os";
|
|
28331
|
+
import { join as join14 } from "path";
|
|
28333
28332
|
function loadApiKeyFromSecrets() {
|
|
28334
28333
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
28335
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
28336
|
-
const secretsPath =
|
|
28337
|
-
if (
|
|
28334
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir11();
|
|
28335
|
+
const secretsPath = join14(homeDir, ".secrets");
|
|
28336
|
+
if (existsSync9(secretsPath)) {
|
|
28338
28337
|
try {
|
|
28339
28338
|
const content = readFileSync4(secretsPath, "utf-8");
|
|
28340
28339
|
const match = content.match(/export\s+ANTHROPIC_API_KEY\s*=\s*["']?([^"'\n]+)["']?/);
|
|
@@ -36578,7 +36577,7 @@ var import_react29 = __toESM(require_react(), 1);
|
|
|
36578
36577
|
|
|
36579
36578
|
// packages/core/src/agent/loop.ts
|
|
36580
36579
|
init_src();
|
|
36581
|
-
import { join as
|
|
36580
|
+
import { join as join21 } from "path";
|
|
36582
36581
|
|
|
36583
36582
|
// packages/core/src/agent/context.ts
|
|
36584
36583
|
init_src();
|
|
@@ -36650,6 +36649,9 @@ class AgentContext {
|
|
|
36650
36649
|
try {
|
|
36651
36650
|
const parsed = JSON.parse(content);
|
|
36652
36651
|
if (parsed && parsed.__pdf_attachment__ === true) {
|
|
36652
|
+
if (!parsed.data || typeof parsed.data !== "string") {
|
|
36653
|
+
return null;
|
|
36654
|
+
}
|
|
36653
36655
|
return {
|
|
36654
36656
|
type: "pdf",
|
|
36655
36657
|
source: {
|
|
@@ -36701,8 +36703,11 @@ class AgentContext {
|
|
|
36701
36703
|
if (this.messages.length <= this.maxMessages) {
|
|
36702
36704
|
return;
|
|
36703
36705
|
}
|
|
36704
|
-
|
|
36706
|
+
let systemMessages = this.messages.filter((m) => m.role === "system");
|
|
36705
36707
|
const nonSystemMessages = this.messages.filter((m) => m.role !== "system");
|
|
36708
|
+
if (systemMessages.length > this.maxMessages) {
|
|
36709
|
+
systemMessages = systemMessages.slice(-this.maxMessages);
|
|
36710
|
+
}
|
|
36706
36711
|
const targetCount = Math.max(0, this.maxMessages - systemMessages.length);
|
|
36707
36712
|
let recentMessages = targetCount > 0 ? nonSystemMessages.slice(-targetCount) : [];
|
|
36708
36713
|
while (recentMessages.length > 0 && recentMessages[0].toolResults) {
|
|
@@ -36871,7 +36876,33 @@ class ContextManager {
|
|
|
36871
36876
|
summarizedCount: 0
|
|
36872
36877
|
};
|
|
36873
36878
|
}
|
|
36874
|
-
|
|
36879
|
+
let summary = "";
|
|
36880
|
+
try {
|
|
36881
|
+
summary = await this.summarizer.summarize(toSummarize);
|
|
36882
|
+
} catch {
|
|
36883
|
+
const tokens = this.tokenCounter.countMessages(messages);
|
|
36884
|
+
this.state.totalTokens = tokens;
|
|
36885
|
+
this.state.messageCount = messages.length;
|
|
36886
|
+
return {
|
|
36887
|
+
messages,
|
|
36888
|
+
summarized: false,
|
|
36889
|
+
tokensBefore: tokens,
|
|
36890
|
+
tokensAfter: tokens,
|
|
36891
|
+
summarizedCount: 0
|
|
36892
|
+
};
|
|
36893
|
+
}
|
|
36894
|
+
if (!summary.trim()) {
|
|
36895
|
+
const tokens = this.tokenCounter.countMessages(messages);
|
|
36896
|
+
this.state.totalTokens = tokens;
|
|
36897
|
+
this.state.messageCount = messages.length;
|
|
36898
|
+
return {
|
|
36899
|
+
messages,
|
|
36900
|
+
summarized: false,
|
|
36901
|
+
tokensBefore: tokens,
|
|
36902
|
+
tokensAfter: tokens,
|
|
36903
|
+
summarizedCount: 0
|
|
36904
|
+
};
|
|
36905
|
+
}
|
|
36875
36906
|
const summaryMessage = {
|
|
36876
36907
|
id: generateId(),
|
|
36877
36908
|
role: "system",
|
|
@@ -37715,7 +37746,7 @@ function isErrorResult(result) {
|
|
|
37715
37746
|
// packages/core/src/tools/connector.ts
|
|
37716
37747
|
init_errors();
|
|
37717
37748
|
import { homedir as homedir2 } from "os";
|
|
37718
|
-
import { join as join3, delimiter, dirname as dirname2 } from "path";
|
|
37749
|
+
import { join as join3, delimiter, dirname as dirname2, extname } from "path";
|
|
37719
37750
|
import { readdirSync, statSync, existsSync as existsSync2, mkdirSync, writeFileSync, readFileSync as readFileSync2 } from "fs";
|
|
37720
37751
|
function resolveTimeout(resolve) {
|
|
37721
37752
|
resolve({ exitCode: 1 });
|
|
@@ -37803,7 +37834,11 @@ class ConnectorBridge {
|
|
|
37803
37834
|
if (!stats.isFile()) {
|
|
37804
37835
|
continue;
|
|
37805
37836
|
}
|
|
37806
|
-
const
|
|
37837
|
+
const ext = extname(file);
|
|
37838
|
+
let name = file.replace("connect-", "");
|
|
37839
|
+
if (ext && [".exe", ".cmd", ".bat", ".ps1"].includes(ext.toLowerCase())) {
|
|
37840
|
+
name = name.slice(0, -ext.length);
|
|
37841
|
+
}
|
|
37807
37842
|
if (name && !name.includes(".") && name.length > 1) {
|
|
37808
37843
|
connectorNames.add(name);
|
|
37809
37844
|
}
|
|
@@ -37857,6 +37892,7 @@ class ConnectorBridge {
|
|
|
37857
37892
|
async discover(connectorNames) {
|
|
37858
37893
|
const names = connectorNames && connectorNames.length > 0 ? connectorNames : this.autoDiscoverConnectorNames();
|
|
37859
37894
|
if (names.length === 0) {
|
|
37895
|
+
this.connectors = new Map;
|
|
37860
37896
|
return [];
|
|
37861
37897
|
}
|
|
37862
37898
|
const uncached = [];
|
|
@@ -37900,16 +37936,17 @@ class ConnectorBridge {
|
|
|
37900
37936
|
};
|
|
37901
37937
|
}
|
|
37902
37938
|
async populateCache(name) {
|
|
37903
|
-
const cli =
|
|
37939
|
+
const cli = await this.resolveConnectorCli(name);
|
|
37904
37940
|
try {
|
|
37905
37941
|
let timeoutId = null;
|
|
37906
37942
|
const timeoutPromise = new Promise((resolve) => {
|
|
37907
37943
|
timeoutId = setTimeout(resolveTimeout, 500, resolve);
|
|
37908
37944
|
});
|
|
37909
|
-
|
|
37910
|
-
|
|
37911
|
-
|
|
37912
|
-
|
|
37945
|
+
if (!cli) {
|
|
37946
|
+
ConnectorBridge.cache.set(name, null);
|
|
37947
|
+
return;
|
|
37948
|
+
}
|
|
37949
|
+
const result = await Promise.race([Bun.$`which ${cli}`.quiet().nothrow(), timeoutPromise]);
|
|
37913
37950
|
if (timeoutId) {
|
|
37914
37951
|
clearTimeout(timeoutId);
|
|
37915
37952
|
}
|
|
@@ -37923,6 +37960,30 @@ class ConnectorBridge {
|
|
|
37923
37960
|
ConnectorBridge.cache.set(name, null);
|
|
37924
37961
|
}
|
|
37925
37962
|
}
|
|
37963
|
+
async resolveConnectorCli(name) {
|
|
37964
|
+
const base2 = `connect-${name}`;
|
|
37965
|
+
const candidates = [base2];
|
|
37966
|
+
const extCandidates = [".exe", ".cmd", ".bat", ".ps1"];
|
|
37967
|
+
for (const ext of extCandidates) {
|
|
37968
|
+
candidates.push(`${base2}${ext}`);
|
|
37969
|
+
}
|
|
37970
|
+
for (const candidate of candidates) {
|
|
37971
|
+
try {
|
|
37972
|
+
let timeoutId = null;
|
|
37973
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
37974
|
+
timeoutId = setTimeout(resolveTimeout, 500, resolve);
|
|
37975
|
+
});
|
|
37976
|
+
const result = await Promise.race([Bun.$`which ${candidate}`.quiet().nothrow(), timeoutPromise]);
|
|
37977
|
+
if (timeoutId) {
|
|
37978
|
+
clearTimeout(timeoutId);
|
|
37979
|
+
}
|
|
37980
|
+
if (result.exitCode === 0) {
|
|
37981
|
+
return candidate;
|
|
37982
|
+
}
|
|
37983
|
+
} catch {}
|
|
37984
|
+
}
|
|
37985
|
+
return null;
|
|
37986
|
+
}
|
|
37926
37987
|
async discoverConnector(name, cli) {
|
|
37927
37988
|
try {
|
|
37928
37989
|
const helpResult = await Bun.$`${cli} --help`.quiet();
|
|
@@ -38462,14 +38523,16 @@ ${stderr || stdout}`.trim(), {
|
|
|
38462
38523
|
|
|
38463
38524
|
// packages/core/src/tools/filesystem.ts
|
|
38464
38525
|
import { join as join4, resolve as resolve3, dirname as dirname3, sep } from "path";
|
|
38526
|
+
import { homedir as homedir5 } from "os";
|
|
38465
38527
|
init_errors();
|
|
38466
38528
|
var {Glob } = globalThis.Bun;
|
|
38467
38529
|
|
|
38468
38530
|
// packages/core/src/validation/paths.ts
|
|
38469
|
-
import { resolve, normalize } from "path";
|
|
38531
|
+
import { resolve, normalize, relative, isAbsolute } from "path";
|
|
38532
|
+
import { homedir as homedir3 } from "os";
|
|
38470
38533
|
import { lstat, realpath } from "fs/promises";
|
|
38471
38534
|
async function validatePath(inputPath, options = {}) {
|
|
38472
|
-
const normalized = normalize(inputPath);
|
|
38535
|
+
const normalized = normalize(expandHome(inputPath));
|
|
38473
38536
|
const resolved = resolve(normalized);
|
|
38474
38537
|
const allowedPaths = options.allowedPaths?.map((p) => resolve(p));
|
|
38475
38538
|
const blockedPaths = options.blockedPaths?.map((p) => resolve(p));
|
|
@@ -38490,7 +38553,7 @@ async function validatePath(inputPath, options = {}) {
|
|
|
38490
38553
|
}
|
|
38491
38554
|
} catch {}
|
|
38492
38555
|
}
|
|
38493
|
-
if (blockedPaths && blockedPaths.some((blocked) => resolved
|
|
38556
|
+
if (blockedPaths && blockedPaths.some((blocked) => isWithinPath(resolved, blocked))) {
|
|
38494
38557
|
return { valid: false, resolved, error: "Path is in blocked list" };
|
|
38495
38558
|
}
|
|
38496
38559
|
if (!isWithinAllowed(resolved, allowedPaths)) {
|
|
@@ -38498,15 +38561,35 @@ async function validatePath(inputPath, options = {}) {
|
|
|
38498
38561
|
}
|
|
38499
38562
|
return { valid: true, resolved };
|
|
38500
38563
|
}
|
|
38564
|
+
function expandHome(value) {
|
|
38565
|
+
if (value === "~")
|
|
38566
|
+
return homedir3();
|
|
38567
|
+
if (value.startsWith("~/")) {
|
|
38568
|
+
return resolve(homedir3(), value.slice(2));
|
|
38569
|
+
}
|
|
38570
|
+
return value;
|
|
38571
|
+
}
|
|
38501
38572
|
function isWithinAllowed(path, allowed) {
|
|
38502
38573
|
if (!allowed || allowed.length === 0)
|
|
38503
38574
|
return true;
|
|
38504
38575
|
return allowed.some((allowedPath) => path === allowedPath || path.startsWith(`${allowedPath}/`));
|
|
38505
38576
|
}
|
|
38577
|
+
function isWithinPath(target, base2) {
|
|
38578
|
+
if (target === base2)
|
|
38579
|
+
return true;
|
|
38580
|
+
const rel = relative(base2, target);
|
|
38581
|
+
if (!rel || rel === "")
|
|
38582
|
+
return true;
|
|
38583
|
+
if (rel.startsWith(".."))
|
|
38584
|
+
return false;
|
|
38585
|
+
if (isAbsolute(rel))
|
|
38586
|
+
return false;
|
|
38587
|
+
return true;
|
|
38588
|
+
}
|
|
38506
38589
|
|
|
38507
38590
|
// packages/core/src/security/path-validator.ts
|
|
38508
|
-
import { homedir as
|
|
38509
|
-
import { resolve as resolve2 } from "path";
|
|
38591
|
+
import { homedir as homedir4 } from "os";
|
|
38592
|
+
import { resolve as resolve2, relative as relative2, isAbsolute as isAbsolute2 } from "path";
|
|
38510
38593
|
import { lstat as lstat2, realpath as realpath2 } from "fs/promises";
|
|
38511
38594
|
var PROTECTED_PATHS = [
|
|
38512
38595
|
"/etc/passwd",
|
|
@@ -38518,17 +38601,16 @@ var PROTECTED_PATHS = [
|
|
|
38518
38601
|
"~/.kube/config"
|
|
38519
38602
|
];
|
|
38520
38603
|
async function isPathSafe(targetPath, operation, options = {}) {
|
|
38521
|
-
const
|
|
38522
|
-
const
|
|
38604
|
+
const expandedTarget = expandHome2(targetPath);
|
|
38605
|
+
const resolved = resolve2(expandedTarget);
|
|
38606
|
+
const home = homedir4();
|
|
38523
38607
|
for (const protectedPath of PROTECTED_PATHS) {
|
|
38524
38608
|
const expanded = protectedPath.replace("~", home);
|
|
38525
|
-
if (resolved
|
|
38526
|
-
|
|
38527
|
-
|
|
38528
|
-
|
|
38529
|
-
|
|
38530
|
-
};
|
|
38531
|
-
}
|
|
38609
|
+
if (isWithinPath2(resolved, expanded)) {
|
|
38610
|
+
return {
|
|
38611
|
+
safe: false,
|
|
38612
|
+
reason: `Cannot ${operation} protected path: ${protectedPath}`
|
|
38613
|
+
};
|
|
38532
38614
|
}
|
|
38533
38615
|
}
|
|
38534
38616
|
try {
|
|
@@ -38546,6 +38628,24 @@ async function isPathSafe(targetPath, operation, options = {}) {
|
|
|
38546
38628
|
} catch {}
|
|
38547
38629
|
return { safe: true };
|
|
38548
38630
|
}
|
|
38631
|
+
function expandHome2(value) {
|
|
38632
|
+
if (value === "~")
|
|
38633
|
+
return homedir4();
|
|
38634
|
+
if (value.startsWith("~/")) {
|
|
38635
|
+
return resolve2(homedir4(), value.slice(2));
|
|
38636
|
+
}
|
|
38637
|
+
return value;
|
|
38638
|
+
}
|
|
38639
|
+
function isWithinPath2(target, base2) {
|
|
38640
|
+
const rel = relative2(base2, target);
|
|
38641
|
+
if (rel === "")
|
|
38642
|
+
return true;
|
|
38643
|
+
if (rel.startsWith(".."))
|
|
38644
|
+
return false;
|
|
38645
|
+
if (isAbsolute2(rel))
|
|
38646
|
+
return false;
|
|
38647
|
+
return true;
|
|
38648
|
+
}
|
|
38549
38649
|
|
|
38550
38650
|
// packages/core/src/tools/filesystem.ts
|
|
38551
38651
|
var currentSessionId = "default";
|
|
@@ -38562,6 +38662,17 @@ function isInScriptsFolder(path, cwd2, sessionId) {
|
|
|
38562
38662
|
}
|
|
38563
38663
|
|
|
38564
38664
|
class FilesystemTools {
|
|
38665
|
+
static resolveInputPath(baseCwd, inputPath) {
|
|
38666
|
+
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
38667
|
+
const home = envHome && envHome.trim().length > 0 ? envHome : homedir5();
|
|
38668
|
+
if (inputPath === "~") {
|
|
38669
|
+
return home;
|
|
38670
|
+
}
|
|
38671
|
+
if (inputPath.startsWith("~/")) {
|
|
38672
|
+
return resolve3(home, inputPath.slice(2));
|
|
38673
|
+
}
|
|
38674
|
+
return resolve3(baseCwd, inputPath);
|
|
38675
|
+
}
|
|
38565
38676
|
static registerAll(registry, sessionId) {
|
|
38566
38677
|
if (sessionId) {
|
|
38567
38678
|
currentSessionId = sessionId;
|
|
@@ -38603,9 +38714,21 @@ class FilesystemTools {
|
|
|
38603
38714
|
};
|
|
38604
38715
|
static readExecutor = async (input) => {
|
|
38605
38716
|
const baseCwd = input.cwd || process.cwd();
|
|
38606
|
-
const
|
|
38717
|
+
const rawPath = String(input.path || "").trim();
|
|
38718
|
+
if (!rawPath) {
|
|
38719
|
+
throw new ToolExecutionError("File path is required", {
|
|
38720
|
+
toolName: "read",
|
|
38721
|
+
toolInput: input,
|
|
38722
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38723
|
+
recoverable: false,
|
|
38724
|
+
retryable: false,
|
|
38725
|
+
suggestion: "Provide a valid file path."
|
|
38726
|
+
});
|
|
38727
|
+
}
|
|
38728
|
+
const path = FilesystemTools.resolveInputPath(baseCwd, rawPath);
|
|
38607
38729
|
const offset = (input.offset || 1) - 1;
|
|
38608
|
-
const
|
|
38730
|
+
const limitRaw = input.limit;
|
|
38731
|
+
const limit = typeof limitRaw === "number" && limitRaw > 0 ? Math.floor(limitRaw) : undefined;
|
|
38609
38732
|
try {
|
|
38610
38733
|
const safety = await isPathSafe(path, "read", { cwd: baseCwd });
|
|
38611
38734
|
if (!safety.safe) {
|
|
@@ -38661,7 +38784,10 @@ class FilesystemTools {
|
|
|
38661
38784
|
});
|
|
38662
38785
|
}
|
|
38663
38786
|
const content = await file.text();
|
|
38664
|
-
const
|
|
38787
|
+
const normalized = content.replace(/\r\n/g, `
|
|
38788
|
+
`).replace(/\r/g, `
|
|
38789
|
+
`);
|
|
38790
|
+
const lines = normalized.split(`
|
|
38665
38791
|
`);
|
|
38666
38792
|
const startLine = Math.max(0, offset);
|
|
38667
38793
|
const endLine = limit ? startLine + limit : lines.length;
|
|
@@ -38711,6 +38837,16 @@ class FilesystemTools {
|
|
|
38711
38837
|
const filename = input.filename || input.path;
|
|
38712
38838
|
const content = input.content;
|
|
38713
38839
|
const baseCwd = input.cwd || process.cwd();
|
|
38840
|
+
if (typeof content !== "string") {
|
|
38841
|
+
throw new ToolExecutionError("Content must be a string", {
|
|
38842
|
+
toolName: "write",
|
|
38843
|
+
toolInput: input,
|
|
38844
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38845
|
+
recoverable: false,
|
|
38846
|
+
retryable: false,
|
|
38847
|
+
suggestion: "Provide string content to write."
|
|
38848
|
+
});
|
|
38849
|
+
}
|
|
38714
38850
|
const scriptsFolder = getScriptsFolder(baseCwd, input.sessionId);
|
|
38715
38851
|
if (!filename || !filename.trim()) {
|
|
38716
38852
|
throw new ToolExecutionError("Filename is required", {
|
|
@@ -38805,13 +38941,55 @@ class FilesystemTools {
|
|
|
38805
38941
|
}
|
|
38806
38942
|
};
|
|
38807
38943
|
static globExecutor = async (input) => {
|
|
38808
|
-
const pattern = input.pattern;
|
|
38944
|
+
const pattern = String(input.pattern || "").trim();
|
|
38809
38945
|
const baseCwd = input.cwd || process.cwd();
|
|
38810
|
-
const searchPath =
|
|
38946
|
+
const searchPath = FilesystemTools.resolveInputPath(baseCwd, input.path || ".");
|
|
38811
38947
|
try {
|
|
38948
|
+
if (!pattern) {
|
|
38949
|
+
throw new ToolExecutionError("Pattern is required", {
|
|
38950
|
+
toolName: "glob",
|
|
38951
|
+
toolInput: input,
|
|
38952
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38953
|
+
recoverable: false,
|
|
38954
|
+
retryable: false
|
|
38955
|
+
});
|
|
38956
|
+
}
|
|
38957
|
+
const safety = await isPathSafe(searchPath, "read", { cwd: baseCwd });
|
|
38958
|
+
if (!safety.safe) {
|
|
38959
|
+
getSecurityLogger().log({
|
|
38960
|
+
eventType: "path_violation",
|
|
38961
|
+
severity: "high",
|
|
38962
|
+
details: {
|
|
38963
|
+
tool: "glob",
|
|
38964
|
+
path: searchPath,
|
|
38965
|
+
reason: safety.reason || "Blocked path"
|
|
38966
|
+
},
|
|
38967
|
+
sessionId: input.sessionId || "unknown"
|
|
38968
|
+
});
|
|
38969
|
+
throw new ToolExecutionError(safety.reason || "Blocked path", {
|
|
38970
|
+
toolName: "glob",
|
|
38971
|
+
toolInput: input,
|
|
38972
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
38973
|
+
recoverable: false,
|
|
38974
|
+
retryable: false
|
|
38975
|
+
});
|
|
38976
|
+
}
|
|
38977
|
+
const validated = await validatePath(searchPath, {
|
|
38978
|
+
allowSymlinks: true,
|
|
38979
|
+
allowedPaths: [baseCwd, searchPath]
|
|
38980
|
+
});
|
|
38981
|
+
if (!validated.valid) {
|
|
38982
|
+
throw new ToolExecutionError(validated.error || "Invalid path", {
|
|
38983
|
+
toolName: "glob",
|
|
38984
|
+
toolInput: input,
|
|
38985
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38986
|
+
recoverable: false,
|
|
38987
|
+
retryable: false
|
|
38988
|
+
});
|
|
38989
|
+
}
|
|
38812
38990
|
const glob = new Glob(pattern);
|
|
38813
38991
|
const matches = [];
|
|
38814
|
-
for await (const file of glob.scan({ cwd:
|
|
38992
|
+
for await (const file of glob.scan({ cwd: validated.resolved })) {
|
|
38815
38993
|
matches.push(file);
|
|
38816
38994
|
if (matches.length >= 1000)
|
|
38817
38995
|
break;
|
|
@@ -38864,18 +39042,60 @@ class FilesystemTools {
|
|
|
38864
39042
|
}
|
|
38865
39043
|
};
|
|
38866
39044
|
static grepExecutor = async (input) => {
|
|
38867
|
-
const pattern = input.pattern;
|
|
39045
|
+
const pattern = String(input.pattern || "").trim();
|
|
38868
39046
|
const baseCwd = input.cwd || process.cwd();
|
|
38869
|
-
const searchPath =
|
|
39047
|
+
const searchPath = FilesystemTools.resolveInputPath(baseCwd, input.path || ".");
|
|
38870
39048
|
const globPattern = input.glob || "**/*";
|
|
38871
39049
|
const caseSensitive = input.caseSensitive || false;
|
|
38872
39050
|
try {
|
|
39051
|
+
if (!pattern) {
|
|
39052
|
+
throw new ToolExecutionError("Pattern is required", {
|
|
39053
|
+
toolName: "grep",
|
|
39054
|
+
toolInput: input,
|
|
39055
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
39056
|
+
recoverable: false,
|
|
39057
|
+
retryable: false
|
|
39058
|
+
});
|
|
39059
|
+
}
|
|
39060
|
+
const safety = await isPathSafe(searchPath, "read", { cwd: baseCwd });
|
|
39061
|
+
if (!safety.safe) {
|
|
39062
|
+
getSecurityLogger().log({
|
|
39063
|
+
eventType: "path_violation",
|
|
39064
|
+
severity: "high",
|
|
39065
|
+
details: {
|
|
39066
|
+
tool: "grep",
|
|
39067
|
+
path: searchPath,
|
|
39068
|
+
reason: safety.reason || "Blocked path"
|
|
39069
|
+
},
|
|
39070
|
+
sessionId: input.sessionId || "unknown"
|
|
39071
|
+
});
|
|
39072
|
+
throw new ToolExecutionError(safety.reason || "Blocked path", {
|
|
39073
|
+
toolName: "grep",
|
|
39074
|
+
toolInput: input,
|
|
39075
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
39076
|
+
recoverable: false,
|
|
39077
|
+
retryable: false
|
|
39078
|
+
});
|
|
39079
|
+
}
|
|
39080
|
+
const validated = await validatePath(searchPath, {
|
|
39081
|
+
allowSymlinks: true,
|
|
39082
|
+
allowedPaths: [baseCwd, searchPath]
|
|
39083
|
+
});
|
|
39084
|
+
if (!validated.valid) {
|
|
39085
|
+
throw new ToolExecutionError(validated.error || "Invalid path", {
|
|
39086
|
+
toolName: "grep",
|
|
39087
|
+
toolInput: input,
|
|
39088
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
39089
|
+
recoverable: false,
|
|
39090
|
+
retryable: false
|
|
39091
|
+
});
|
|
39092
|
+
}
|
|
38873
39093
|
const flags = caseSensitive ? "" : "i";
|
|
38874
39094
|
const regex2 = new RegExp(pattern, flags);
|
|
38875
39095
|
const results = [];
|
|
38876
39096
|
const glob = new Glob(globPattern);
|
|
38877
|
-
for await (const file of glob.scan({ cwd:
|
|
38878
|
-
const filePath = join4(
|
|
39097
|
+
for await (const file of glob.scan({ cwd: validated.resolved })) {
|
|
39098
|
+
const filePath = join4(validated.resolved, file);
|
|
38879
39099
|
try {
|
|
38880
39100
|
const content = await Bun.file(filePath).text();
|
|
38881
39101
|
const lines = content.split(`
|
|
@@ -38928,7 +39148,7 @@ class FilesystemTools {
|
|
|
38928
39148
|
};
|
|
38929
39149
|
static readPdfExecutor = async (input) => {
|
|
38930
39150
|
const baseCwd = input.cwd || process.cwd();
|
|
38931
|
-
const path =
|
|
39151
|
+
const path = FilesystemTools.resolveInputPath(baseCwd, String(input.path || ""));
|
|
38932
39152
|
try {
|
|
38933
39153
|
const safety = await isPathSafe(path, "read", { cwd: baseCwd });
|
|
38934
39154
|
if (!safety.safe) {
|
|
@@ -39847,13 +40067,19 @@ function getNextCronRun(expression, fromTime, timeZone) {
|
|
|
39847
40067
|
|
|
39848
40068
|
// packages/core/src/scheduler/store.ts
|
|
39849
40069
|
var DEFAULT_LOCK_TTL_MS = 10 * 60 * 1000;
|
|
40070
|
+
var SAFE_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
39850
40071
|
function schedulesDir(cwd2) {
|
|
39851
40072
|
return join6(getProjectConfigDir(cwd2), "schedules");
|
|
39852
40073
|
}
|
|
39853
40074
|
function locksDir(cwd2) {
|
|
39854
40075
|
return join6(schedulesDir(cwd2), "locks");
|
|
39855
40076
|
}
|
|
40077
|
+
function isSafeId(id) {
|
|
40078
|
+
return SAFE_ID_PATTERN.test(id);
|
|
40079
|
+
}
|
|
39856
40080
|
function schedulePath(cwd2, id) {
|
|
40081
|
+
if (!isSafeId(id))
|
|
40082
|
+
return null;
|
|
39857
40083
|
return join6(schedulesDir(cwd2), `${id}.json`);
|
|
39858
40084
|
}
|
|
39859
40085
|
function lockPath(cwd2, id) {
|
|
@@ -39886,11 +40112,17 @@ async function listSchedules(cwd2) {
|
|
|
39886
40112
|
async function saveSchedule(cwd2, schedule) {
|
|
39887
40113
|
await ensureDirs(cwd2);
|
|
39888
40114
|
const path = schedulePath(cwd2, schedule.id);
|
|
40115
|
+
if (!path) {
|
|
40116
|
+
throw new Error(`Invalid schedule id: ${schedule.id}`);
|
|
40117
|
+
}
|
|
39889
40118
|
await writeFile(path, JSON.stringify(schedule, null, 2), "utf-8");
|
|
39890
40119
|
}
|
|
39891
40120
|
async function deleteSchedule(cwd2, id) {
|
|
39892
40121
|
try {
|
|
39893
|
-
|
|
40122
|
+
const path = schedulePath(cwd2, id);
|
|
40123
|
+
if (!path)
|
|
40124
|
+
return false;
|
|
40125
|
+
await unlink(path);
|
|
39894
40126
|
return true;
|
|
39895
40127
|
} catch {
|
|
39896
40128
|
return false;
|
|
@@ -39902,7 +40134,10 @@ function computeNextRun(schedule, fromTime) {
|
|
|
39902
40134
|
if (schedule.schedule.kind === "once") {
|
|
39903
40135
|
if (!schedule.schedule.at)
|
|
39904
40136
|
return;
|
|
39905
|
-
|
|
40137
|
+
const next = parseScheduledTime(schedule.schedule.at, validTimezone);
|
|
40138
|
+
if (!next || next <= fromTime)
|
|
40139
|
+
return;
|
|
40140
|
+
return next;
|
|
39906
40141
|
}
|
|
39907
40142
|
if (schedule.schedule.kind === "cron") {
|
|
39908
40143
|
if (!schedule.schedule.cron)
|
|
@@ -39918,12 +40153,17 @@ async function getDueSchedules(cwd2, nowTime) {
|
|
|
39918
40153
|
return false;
|
|
39919
40154
|
if (!schedule.nextRunAt)
|
|
39920
40155
|
return false;
|
|
40156
|
+
if (!Number.isFinite(schedule.nextRunAt))
|
|
40157
|
+
return false;
|
|
39921
40158
|
return schedule.nextRunAt <= nowTime;
|
|
39922
40159
|
});
|
|
39923
40160
|
}
|
|
39924
40161
|
async function updateSchedule(cwd2, id, updater) {
|
|
39925
40162
|
try {
|
|
39926
|
-
const
|
|
40163
|
+
const path = schedulePath(cwd2, id);
|
|
40164
|
+
if (!path)
|
|
40165
|
+
return null;
|
|
40166
|
+
const raw = await readFile(path, "utf-8");
|
|
39927
40167
|
const schedule = JSON.parse(raw);
|
|
39928
40168
|
const updated = updater(schedule);
|
|
39929
40169
|
await saveSchedule(cwd2, updated);
|
|
@@ -39933,6 +40173,8 @@ async function updateSchedule(cwd2, id, updater) {
|
|
|
39933
40173
|
}
|
|
39934
40174
|
}
|
|
39935
40175
|
async function acquireScheduleLock(cwd2, id, ownerId, ttlMs = DEFAULT_LOCK_TTL_MS, allowRetry = true) {
|
|
40176
|
+
if (!isSafeId(id))
|
|
40177
|
+
return false;
|
|
39936
40178
|
await ensureDirs(cwd2);
|
|
39937
40179
|
const path = lockPath(cwd2, id);
|
|
39938
40180
|
const now2 = Date.now();
|
|
@@ -39965,6 +40207,8 @@ async function acquireScheduleLock(cwd2, id, ownerId, ttlMs = DEFAULT_LOCK_TTL_M
|
|
|
39965
40207
|
return false;
|
|
39966
40208
|
}
|
|
39967
40209
|
async function releaseScheduleLock(cwd2, id, ownerId) {
|
|
40210
|
+
if (!isSafeId(id))
|
|
40211
|
+
return;
|
|
39968
40212
|
const path = lockPath(cwd2, id);
|
|
39969
40213
|
try {
|
|
39970
40214
|
const raw = await readFile(path, "utf-8");
|
|
@@ -39975,6 +40219,8 @@ async function releaseScheduleLock(cwd2, id, ownerId) {
|
|
|
39975
40219
|
} catch {}
|
|
39976
40220
|
}
|
|
39977
40221
|
async function refreshScheduleLock(cwd2, id, ownerId) {
|
|
40222
|
+
if (!isSafeId(id))
|
|
40223
|
+
return;
|
|
39978
40224
|
const path = lockPath(cwd2, id);
|
|
39979
40225
|
try {
|
|
39980
40226
|
const raw = await readFile(path, "utf-8");
|
|
@@ -39987,7 +40233,10 @@ async function refreshScheduleLock(cwd2, id, ownerId) {
|
|
|
39987
40233
|
}
|
|
39988
40234
|
async function readSchedule(cwd2, id) {
|
|
39989
40235
|
try {
|
|
39990
|
-
const
|
|
40236
|
+
const path = schedulePath(cwd2, id);
|
|
40237
|
+
if (!path)
|
|
40238
|
+
return null;
|
|
40239
|
+
const raw = await readFile(path, "utf-8");
|
|
39991
40240
|
const schedule = JSON.parse(raw);
|
|
39992
40241
|
if (!schedule?.id)
|
|
39993
40242
|
return null;
|
|
@@ -40033,6 +40282,9 @@ function parseDateTime(value) {
|
|
|
40033
40282
|
if (!Number.isFinite(year) || !Number.isFinite(month) || !Number.isFinite(day) || !Number.isFinite(hour) || !Number.isFinite(minute) || !Number.isFinite(second)) {
|
|
40034
40283
|
return null;
|
|
40035
40284
|
}
|
|
40285
|
+
if (month < 1 || month > 12 || day < 1 || day > 31 || hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) {
|
|
40286
|
+
return null;
|
|
40287
|
+
}
|
|
40036
40288
|
return { year, month, day, hour, minute, second };
|
|
40037
40289
|
}
|
|
40038
40290
|
function hasTimeZoneOffset(value) {
|
|
@@ -40171,11 +40423,21 @@ class SchedulerTool {
|
|
|
40171
40423
|
const id = String(input.id || "").trim();
|
|
40172
40424
|
if (!id)
|
|
40173
40425
|
return "Error: id is required.";
|
|
40426
|
+
let nextRunAt;
|
|
40427
|
+
if (action === "resume") {
|
|
40428
|
+
const schedule = await readSchedule(cwd2, id);
|
|
40429
|
+
if (!schedule)
|
|
40430
|
+
return `Schedule ${id} not found.`;
|
|
40431
|
+
nextRunAt = computeNextRun(schedule, Date.now());
|
|
40432
|
+
if (!nextRunAt) {
|
|
40433
|
+
return `Error: unable to compute next run for schedule ${id}.`;
|
|
40434
|
+
}
|
|
40435
|
+
}
|
|
40174
40436
|
const updated = await updateSchedule(cwd2, id, (s) => ({
|
|
40175
40437
|
...s,
|
|
40176
40438
|
status: action === "pause" ? "paused" : "active",
|
|
40177
40439
|
updatedAt: Date.now(),
|
|
40178
|
-
nextRunAt: action === "resume" ?
|
|
40440
|
+
nextRunAt: action === "resume" ? nextRunAt : s.nextRunAt
|
|
40179
40441
|
}));
|
|
40180
40442
|
if (!updated)
|
|
40181
40443
|
return `Schedule ${id} not found.`;
|
|
@@ -40190,7 +40452,7 @@ init_src();
|
|
|
40190
40452
|
import { existsSync as existsSync4, writeFileSync as writeFileSync3, unlinkSync } from "fs";
|
|
40191
40453
|
import { tmpdir } from "os";
|
|
40192
40454
|
import { join as join7 } from "path";
|
|
40193
|
-
import { homedir as
|
|
40455
|
+
import { homedir as homedir6 } from "os";
|
|
40194
40456
|
async function getViuPath() {
|
|
40195
40457
|
const explicitPath = process.env.ASSISTANTS_VIU_PATH || process.env.VIU_PATH;
|
|
40196
40458
|
if (explicitPath) {
|
|
@@ -40202,7 +40464,7 @@ async function getViuPath() {
|
|
|
40202
40464
|
} catch {}
|
|
40203
40465
|
}
|
|
40204
40466
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
40205
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
40467
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir6();
|
|
40206
40468
|
const locations = [
|
|
40207
40469
|
"viu",
|
|
40208
40470
|
join7(homeDir, ".cargo", "bin", "viu"),
|
|
@@ -40351,14 +40613,14 @@ Respond with ALLOW or DENY on the first line, followed by a short reason.`,
|
|
|
40351
40613
|
// packages/core/src/skills/loader.ts
|
|
40352
40614
|
init_src();
|
|
40353
40615
|
import { join as join8, basename, dirname as dirname4 } from "path";
|
|
40354
|
-
import { homedir as
|
|
40616
|
+
import { homedir as homedir7 } from "os";
|
|
40355
40617
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
40356
40618
|
|
|
40357
40619
|
class SkillLoader {
|
|
40358
40620
|
skills = new Map;
|
|
40359
40621
|
async loadAll(projectDir = process.cwd()) {
|
|
40360
40622
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
40361
|
-
const userHome = envHome && envHome.trim().length > 0 ? envHome :
|
|
40623
|
+
const userHome = envHome && envHome.trim().length > 0 ? envHome : homedir7();
|
|
40362
40624
|
const userSkillsDir = join8(userHome, ".assistants", "shared", "skills");
|
|
40363
40625
|
await this.loadFromDirectory(userSkillsDir);
|
|
40364
40626
|
const projectSkillsDir = join8(projectDir, ".assistants", "skills");
|
|
@@ -40574,6 +40836,7 @@ class HookLoader {
|
|
|
40574
40836
|
}
|
|
40575
40837
|
// packages/core/src/hooks/executor.ts
|
|
40576
40838
|
init_src();
|
|
40839
|
+
import { existsSync as existsSync5 } from "fs";
|
|
40577
40840
|
function killSpawnedProcess(proc) {
|
|
40578
40841
|
proc.kill();
|
|
40579
40842
|
}
|
|
@@ -40659,7 +40922,9 @@ class HookExecutor {
|
|
|
40659
40922
|
if (!hook.command)
|
|
40660
40923
|
return null;
|
|
40661
40924
|
try {
|
|
40925
|
+
const cwd2 = input.cwd && existsSync5(input.cwd) ? input.cwd : process.cwd();
|
|
40662
40926
|
const proc = Bun.spawn(["bash", "-c", hook.command], {
|
|
40927
|
+
cwd: cwd2,
|
|
40663
40928
|
stdin: "pipe",
|
|
40664
40929
|
stdout: "pipe",
|
|
40665
40930
|
stderr: "pipe"
|
|
@@ -41036,7 +41301,7 @@ init_src();
|
|
|
41036
41301
|
// packages/core/src/sessions/verification.ts
|
|
41037
41302
|
init_src();
|
|
41038
41303
|
import { join as join9 } from "path";
|
|
41039
|
-
import { existsSync as
|
|
41304
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4, readdirSync as readdirSync2 } from "fs";
|
|
41040
41305
|
|
|
41041
41306
|
class VerificationSessionStore {
|
|
41042
41307
|
basePath;
|
|
@@ -41047,7 +41312,7 @@ class VerificationSessionStore {
|
|
|
41047
41312
|
this.ensureDirectory();
|
|
41048
41313
|
}
|
|
41049
41314
|
ensureDirectory() {
|
|
41050
|
-
if (!
|
|
41315
|
+
if (!existsSync6(this.basePath)) {
|
|
41051
41316
|
mkdirSync3(this.basePath, { recursive: true });
|
|
41052
41317
|
}
|
|
41053
41318
|
}
|
|
@@ -41073,7 +41338,7 @@ class VerificationSessionStore {
|
|
|
41073
41338
|
}
|
|
41074
41339
|
get(id) {
|
|
41075
41340
|
const filePath = join9(this.basePath, `${id}.json`);
|
|
41076
|
-
if (!
|
|
41341
|
+
if (!existsSync6(filePath)) {
|
|
41077
41342
|
return null;
|
|
41078
41343
|
}
|
|
41079
41344
|
try {
|
|
@@ -41121,7 +41386,7 @@ class VerificationSessionStore {
|
|
|
41121
41386
|
this.save(session);
|
|
41122
41387
|
}
|
|
41123
41388
|
listFiles() {
|
|
41124
|
-
if (!
|
|
41389
|
+
if (!existsSync6(this.basePath)) {
|
|
41125
41390
|
return [];
|
|
41126
41391
|
}
|
|
41127
41392
|
return readdirSync2(this.basePath).filter((f) => f.endsWith(".json"));
|
|
@@ -41312,9 +41577,9 @@ function createScopeVerificationHook() {
|
|
|
41312
41577
|
};
|
|
41313
41578
|
}
|
|
41314
41579
|
// packages/core/src/commands/loader.ts
|
|
41315
|
-
import { existsSync as
|
|
41316
|
-
import { join as join10, basename as basename2, extname } from "path";
|
|
41317
|
-
import { homedir as
|
|
41580
|
+
import { existsSync as existsSync7, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
|
|
41581
|
+
import { join as join10, basename as basename2, extname as extname2 } from "path";
|
|
41582
|
+
import { homedir as homedir8 } from "os";
|
|
41318
41583
|
|
|
41319
41584
|
class CommandLoader {
|
|
41320
41585
|
commands = new Map;
|
|
@@ -41325,14 +41590,14 @@ class CommandLoader {
|
|
|
41325
41590
|
async loadAll() {
|
|
41326
41591
|
this.commands.clear();
|
|
41327
41592
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
41328
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
41593
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir8();
|
|
41329
41594
|
const globalDir = join10(homeDir, ".assistants", "commands");
|
|
41330
41595
|
await this.loadFromDirectory(globalDir, "global");
|
|
41331
41596
|
const projectDir = join10(this.cwd, ".assistants", "commands");
|
|
41332
41597
|
await this.loadFromDirectory(projectDir, "project");
|
|
41333
41598
|
}
|
|
41334
41599
|
async loadFromDirectory(dir, source, prefix = "") {
|
|
41335
|
-
if (!
|
|
41600
|
+
if (!existsSync7(dir))
|
|
41336
41601
|
return;
|
|
41337
41602
|
const entries = readdirSync3(dir);
|
|
41338
41603
|
for (const entry of entries) {
|
|
@@ -41341,7 +41606,7 @@ class CommandLoader {
|
|
|
41341
41606
|
if (stat.isDirectory()) {
|
|
41342
41607
|
const newPrefix = prefix ? `${prefix}:${entry}` : entry;
|
|
41343
41608
|
await this.loadFromDirectory(fullPath, source, newPrefix);
|
|
41344
|
-
} else if (stat.isFile() &&
|
|
41609
|
+
} else if (stat.isFile() && extname2(entry) === ".md") {
|
|
41345
41610
|
const command = await this.loadCommandFile(fullPath, prefix);
|
|
41346
41611
|
if (command) {
|
|
41347
41612
|
this.commands.set(command.name, command);
|
|
@@ -41372,15 +41637,14 @@ class CommandLoader {
|
|
|
41372
41637
|
}
|
|
41373
41638
|
}
|
|
41374
41639
|
parseFrontmatter(content) {
|
|
41375
|
-
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
|
|
41640
|
+
const frontmatterRegex = /^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n?([\s\S]*)$/;
|
|
41376
41641
|
const match = content.match(frontmatterRegex);
|
|
41377
41642
|
if (!match) {
|
|
41378
41643
|
return { frontmatter: {}, body: content };
|
|
41379
41644
|
}
|
|
41380
41645
|
const [, yamlContent, body] = match;
|
|
41381
41646
|
const frontmatter = {};
|
|
41382
|
-
const lines = yamlContent.split(
|
|
41383
|
-
`);
|
|
41647
|
+
const lines = yamlContent.split(/\r?\n/);
|
|
41384
41648
|
let currentListKey = null;
|
|
41385
41649
|
for (const rawLine of lines) {
|
|
41386
41650
|
const line = rawLine.trimEnd();
|
|
@@ -41512,10 +41776,16 @@ Use /help to see available commands.
|
|
|
41512
41776
|
}
|
|
41513
41777
|
if (!inCodeBlock && trimmed.startsWith("!")) {
|
|
41514
41778
|
const command = trimmed.slice(1).trim();
|
|
41779
|
+
if (!command) {
|
|
41780
|
+
processedLines.push(line);
|
|
41781
|
+
continue;
|
|
41782
|
+
}
|
|
41515
41783
|
const output = await this.executeShell(command, cwd2);
|
|
41516
|
-
|
|
41517
|
-
|
|
41518
|
-
\`\`\``
|
|
41784
|
+
const indent = line.match(/^\s*/)?.[0] ?? "";
|
|
41785
|
+
const fenced = [`${indent}\`\`\``, ...output.split(`
|
|
41786
|
+
`).map((o) => `${indent}${o}`), `${indent}\`\`\``];
|
|
41787
|
+
processedLines.push(fenced.join(`
|
|
41788
|
+
`));
|
|
41519
41789
|
} else {
|
|
41520
41790
|
processedLines.push(line);
|
|
41521
41791
|
}
|
|
@@ -41567,19 +41837,25 @@ ${stderr}`;
|
|
|
41567
41837
|
}
|
|
41568
41838
|
}
|
|
41569
41839
|
// packages/core/src/commands/builtin.ts
|
|
41570
|
-
import { join as
|
|
41571
|
-
import { homedir as
|
|
41572
|
-
import { existsSync as
|
|
41840
|
+
import { join as join13 } from "path";
|
|
41841
|
+
import { homedir as homedir10, platform as platform2, release, arch } from "os";
|
|
41842
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
41573
41843
|
init_src();
|
|
41574
41844
|
|
|
41575
41845
|
// packages/core/src/projects/store.ts
|
|
41576
41846
|
init_src();
|
|
41577
41847
|
import { join as join11 } from "path";
|
|
41578
41848
|
import { mkdir as mkdir3, readdir as readdir2, readFile as readFile2, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
|
|
41849
|
+
var SAFE_ID_PATTERN2 = /^[a-zA-Z0-9_-]+$/;
|
|
41579
41850
|
function projectsDir(cwd2) {
|
|
41580
41851
|
return join11(cwd2, ".assistants", "projects");
|
|
41581
41852
|
}
|
|
41853
|
+
function isSafeId2(id) {
|
|
41854
|
+
return SAFE_ID_PATTERN2.test(id);
|
|
41855
|
+
}
|
|
41582
41856
|
function projectPath(cwd2, id) {
|
|
41857
|
+
if (!isSafeId2(id))
|
|
41858
|
+
return null;
|
|
41583
41859
|
return join11(projectsDir(cwd2), `${id}.json`);
|
|
41584
41860
|
}
|
|
41585
41861
|
async function ensureProjectsDir(cwd2) {
|
|
@@ -41611,7 +41887,10 @@ async function listProjects(cwd2) {
|
|
|
41611
41887
|
}
|
|
41612
41888
|
async function readProject(cwd2, id) {
|
|
41613
41889
|
try {
|
|
41614
|
-
const
|
|
41890
|
+
const path = projectPath(cwd2, id);
|
|
41891
|
+
if (!path)
|
|
41892
|
+
return null;
|
|
41893
|
+
const raw = await readFile2(path, "utf-8");
|
|
41615
41894
|
const project = JSON.parse(raw);
|
|
41616
41895
|
if (!project?.id || !project?.name)
|
|
41617
41896
|
return null;
|
|
@@ -41627,11 +41906,18 @@ async function findProjectByName(cwd2, name) {
|
|
|
41627
41906
|
}
|
|
41628
41907
|
async function saveProject(cwd2, project) {
|
|
41629
41908
|
await ensureProjectsDir(cwd2);
|
|
41630
|
-
|
|
41909
|
+
const path = projectPath(cwd2, project.id);
|
|
41910
|
+
if (!path) {
|
|
41911
|
+
throw new Error(`Invalid project id: ${project.id}`);
|
|
41912
|
+
}
|
|
41913
|
+
await writeFile2(path, JSON.stringify(project, null, 2), "utf-8");
|
|
41631
41914
|
}
|
|
41632
41915
|
async function deleteProject(cwd2, id) {
|
|
41633
41916
|
try {
|
|
41634
|
-
|
|
41917
|
+
const path = projectPath(cwd2, id);
|
|
41918
|
+
if (!path)
|
|
41919
|
+
return false;
|
|
41920
|
+
await unlink2(path);
|
|
41635
41921
|
return true;
|
|
41636
41922
|
} catch {
|
|
41637
41923
|
return false;
|
|
@@ -41672,23 +41958,28 @@ function hasProjectNameConflict(projects, name) {
|
|
|
41672
41958
|
|
|
41673
41959
|
// packages/core/src/projects/context.ts
|
|
41674
41960
|
import { readFile as readFile3 } from "fs/promises";
|
|
41675
|
-
import {
|
|
41961
|
+
import { homedir as homedir9 } from "os";
|
|
41962
|
+
import { resolve as resolve4, join as join12 } from "path";
|
|
41676
41963
|
var DEFAULT_MAX_FILE_BYTES = 12000;
|
|
41964
|
+
function singleLine(value) {
|
|
41965
|
+
return value.replace(/[\r\n]+/g, " ").trim();
|
|
41966
|
+
}
|
|
41677
41967
|
function formatPlan(plan) {
|
|
41678
41968
|
const lines = [];
|
|
41679
|
-
lines.push(`- ${plan.title} (${plan.steps.length} steps)`);
|
|
41969
|
+
lines.push(`- ${singleLine(plan.title)} (${plan.steps.length} steps)`);
|
|
41680
41970
|
for (const step of plan.steps) {
|
|
41681
|
-
lines.push(` - [${step.status}] ${step.text}`);
|
|
41971
|
+
lines.push(` - [${step.status}] ${singleLine(step.text)}`);
|
|
41682
41972
|
}
|
|
41683
41973
|
return lines.join(`
|
|
41684
41974
|
`);
|
|
41685
41975
|
}
|
|
41686
41976
|
function normalizeEntryLabel(entry) {
|
|
41687
|
-
return entry.label ? entry.label
|
|
41977
|
+
return entry.label ? singleLine(entry.label) : singleLine(entry.value);
|
|
41688
41978
|
}
|
|
41689
41979
|
async function renderFileEntry(entry, options) {
|
|
41690
41980
|
const rawPath = entry.value.trim();
|
|
41691
|
-
const
|
|
41981
|
+
const expandedPath = rawPath === "~" ? homedir9() : rawPath.startsWith("~/") ? join12(homedir9(), rawPath.slice(2)) : rawPath;
|
|
41982
|
+
const resolved = resolve4(options.cwd, expandedPath);
|
|
41692
41983
|
const validation = await validatePath(resolved, { allowedPaths: [options.cwd] });
|
|
41693
41984
|
if (!validation.valid) {
|
|
41694
41985
|
return `- File: ${rawPath} (unavailable: ${validation.error || "invalid path"})`;
|
|
@@ -41820,7 +42111,7 @@ function splitArgs(input) {
|
|
|
41820
42111
|
args.push(current);
|
|
41821
42112
|
return args;
|
|
41822
42113
|
}
|
|
41823
|
-
function
|
|
42114
|
+
function singleLine2(value) {
|
|
41824
42115
|
return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
41825
42116
|
}
|
|
41826
42117
|
|
|
@@ -42659,12 +42950,12 @@ No context entries for project "${project.name}".
|
|
|
42659
42950
|
return { handled: true };
|
|
42660
42951
|
}
|
|
42661
42952
|
let output = `
|
|
42662
|
-
**Context Entries (${
|
|
42953
|
+
**Context Entries (${singleLine2(project.name)})**
|
|
42663
42954
|
|
|
42664
42955
|
`;
|
|
42665
42956
|
for (const entry of project.context) {
|
|
42666
|
-
const label = entry.label ? ` (${
|
|
42667
|
-
output += `- ${entry.id} [${entry.type}] ${
|
|
42957
|
+
const label = entry.label ? ` (${singleLine2(entry.label)})` : "";
|
|
42958
|
+
output += `- ${entry.id} [${entry.type}] ${singleLine2(entry.value)}${label}
|
|
42668
42959
|
`;
|
|
42669
42960
|
}
|
|
42670
42961
|
context.emit("text", output);
|
|
@@ -42811,7 +43102,7 @@ No projects found. Use /projects new <name>.
|
|
|
42811
43102
|
`;
|
|
42812
43103
|
for (const project of projects) {
|
|
42813
43104
|
const marker = project.id === activeId ? "*" : " ";
|
|
42814
|
-
output += `${marker} ${
|
|
43105
|
+
output += `${marker} ${singleLine2(project.name)} (${project.id})
|
|
42815
43106
|
`;
|
|
42816
43107
|
}
|
|
42817
43108
|
context.emit("text", output);
|
|
@@ -42873,13 +43164,13 @@ No projects found. Use /projects new <name>.
|
|
|
42873
43164
|
return { handled: true };
|
|
42874
43165
|
}
|
|
42875
43166
|
let output = `
|
|
42876
|
-
**Project: ${
|
|
43167
|
+
**Project: ${singleLine2(project.name)}**
|
|
42877
43168
|
|
|
42878
43169
|
`;
|
|
42879
43170
|
output += `ID: ${project.id}
|
|
42880
43171
|
`;
|
|
42881
43172
|
if (project.description) {
|
|
42882
|
-
output += `Description: ${
|
|
43173
|
+
output += `Description: ${singleLine2(project.description)}
|
|
42883
43174
|
`;
|
|
42884
43175
|
}
|
|
42885
43176
|
output += `Context entries: ${project.context.length}
|
|
@@ -43005,11 +43296,11 @@ No plans for project "${project.name}".
|
|
|
43005
43296
|
return { handled: true };
|
|
43006
43297
|
}
|
|
43007
43298
|
let output = `
|
|
43008
|
-
**Plans (${
|
|
43299
|
+
**Plans (${singleLine2(project.name)})**
|
|
43009
43300
|
|
|
43010
43301
|
`;
|
|
43011
43302
|
for (const plan of project.plans) {
|
|
43012
|
-
output += `- ${plan.id} ${
|
|
43303
|
+
output += `- ${plan.id} ${singleLine2(plan.title)} (${plan.steps.length} steps)
|
|
43013
43304
|
`;
|
|
43014
43305
|
}
|
|
43015
43306
|
context.emit("text", output);
|
|
@@ -43065,7 +43356,7 @@ No plans for project "${project.name}".
|
|
|
43065
43356
|
return { handled: true };
|
|
43066
43357
|
}
|
|
43067
43358
|
let output = `
|
|
43068
|
-
**Plan: ${
|
|
43359
|
+
**Plan: ${singleLine2(plan.title)}**
|
|
43069
43360
|
|
|
43070
43361
|
`;
|
|
43071
43362
|
output += `ID: ${plan.id}
|
|
@@ -43075,7 +43366,7 @@ No plans for project "${project.name}".
|
|
|
43075
43366
|
`;
|
|
43076
43367
|
} else {
|
|
43077
43368
|
for (const step of plan.steps) {
|
|
43078
|
-
output += `- ${step.id} [${step.status}] ${
|
|
43369
|
+
output += `- ${step.id} [${step.status}] ${singleLine2(step.text)}
|
|
43079
43370
|
`;
|
|
43080
43371
|
}
|
|
43081
43372
|
}
|
|
@@ -43508,9 +43799,9 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43508
43799
|
content: "",
|
|
43509
43800
|
handler: async (args, context) => {
|
|
43510
43801
|
const configPaths = [
|
|
43511
|
-
|
|
43512
|
-
|
|
43513
|
-
|
|
43802
|
+
join13(context.cwd, ".assistants", "config.json"),
|
|
43803
|
+
join13(context.cwd, ".assistants", "config.local.json"),
|
|
43804
|
+
join13(getConfigDir(), "config.json")
|
|
43514
43805
|
];
|
|
43515
43806
|
let message = `
|
|
43516
43807
|
**Configuration**
|
|
@@ -43519,18 +43810,18 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43519
43810
|
message += `**Config File Locations:**
|
|
43520
43811
|
`;
|
|
43521
43812
|
for (const path of configPaths) {
|
|
43522
|
-
const exists =
|
|
43813
|
+
const exists = existsSync8(path);
|
|
43523
43814
|
message += ` ${exists ? "\u2713" : "\u25CB"} ${path}
|
|
43524
43815
|
`;
|
|
43525
43816
|
}
|
|
43526
43817
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
43527
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
43818
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir10();
|
|
43528
43819
|
message += `
|
|
43529
43820
|
**Commands Directories:**
|
|
43530
43821
|
`;
|
|
43531
|
-
message += ` - Project: ${
|
|
43822
|
+
message += ` - Project: ${join13(context.cwd, ".assistants", "commands")}
|
|
43532
43823
|
`;
|
|
43533
|
-
message += ` - Global: ${
|
|
43824
|
+
message += ` - Global: ${join13(homeDir, ".assistants", "commands")}
|
|
43534
43825
|
`;
|
|
43535
43826
|
context.emit("text", message);
|
|
43536
43827
|
context.emit("done");
|
|
@@ -43546,7 +43837,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43546
43837
|
selfHandled: true,
|
|
43547
43838
|
content: "",
|
|
43548
43839
|
handler: async (args, context) => {
|
|
43549
|
-
const commandsDir =
|
|
43840
|
+
const commandsDir = join13(context.cwd, ".assistants", "commands");
|
|
43550
43841
|
mkdirSync4(commandsDir, { recursive: true });
|
|
43551
43842
|
const exampleCommand = `---
|
|
43552
43843
|
name: reflect
|
|
@@ -43562,8 +43853,8 @@ Please summarize the last interaction and suggest 2-3 next steps.
|
|
|
43562
43853
|
- Focus on clarity
|
|
43563
43854
|
- Ask a follow-up question if needed
|
|
43564
43855
|
`;
|
|
43565
|
-
const examplePath =
|
|
43566
|
-
if (!
|
|
43856
|
+
const examplePath = join13(commandsDir, "reflect.md");
|
|
43857
|
+
if (!existsSync8(examplePath)) {
|
|
43567
43858
|
writeFileSync5(examplePath, exampleCommand);
|
|
43568
43859
|
}
|
|
43569
43860
|
let message = `
|
|
@@ -44727,15 +45018,15 @@ function validateToolCalls(toolCalls, tools) {
|
|
|
44727
45018
|
}
|
|
44728
45019
|
|
|
44729
45020
|
// packages/core/src/voice/utils.ts
|
|
44730
|
-
import { existsSync as
|
|
44731
|
-
import { homedir as
|
|
44732
|
-
import { join as
|
|
45021
|
+
import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
|
|
45022
|
+
import { homedir as homedir12 } from "os";
|
|
45023
|
+
import { join as join15 } from "path";
|
|
44733
45024
|
import { spawnSync } from "child_process";
|
|
44734
45025
|
function loadApiKeyFromSecrets2(key) {
|
|
44735
45026
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
44736
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
44737
|
-
const secretsPath =
|
|
44738
|
-
if (!
|
|
45027
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir12();
|
|
45028
|
+
const secretsPath = join15(homeDir, ".secrets");
|
|
45029
|
+
if (!existsSync10(secretsPath))
|
|
44739
45030
|
return;
|
|
44740
45031
|
try {
|
|
44741
45032
|
const content = readFileSync5(secretsPath, "utf-8");
|
|
@@ -44808,7 +45099,7 @@ class SystemSTT {
|
|
|
44808
45099
|
// packages/core/src/voice/tts.ts
|
|
44809
45100
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
44810
45101
|
import { tmpdir as tmpdir2 } from "os";
|
|
44811
|
-
import { join as
|
|
45102
|
+
import { join as join16 } from "path";
|
|
44812
45103
|
import { readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
44813
45104
|
class ElevenLabsTTS {
|
|
44814
45105
|
apiKey;
|
|
@@ -44912,7 +45203,7 @@ class SystemTTS {
|
|
|
44912
45203
|
if (!say) {
|
|
44913
45204
|
throw new Error('System TTS not available: missing "say" command.');
|
|
44914
45205
|
}
|
|
44915
|
-
const output =
|
|
45206
|
+
const output = join16(tmpdir2(), `assistants-tts-${Date.now()}.aiff`);
|
|
44916
45207
|
const args = [];
|
|
44917
45208
|
if (this.voiceId) {
|
|
44918
45209
|
args.push("-v", this.voiceId);
|
|
@@ -44934,7 +45225,7 @@ class SystemTTS {
|
|
|
44934
45225
|
}
|
|
44935
45226
|
const espeak = findExecutable("espeak") || findExecutable("espeak-ng");
|
|
44936
45227
|
if (espeak) {
|
|
44937
|
-
const output =
|
|
45228
|
+
const output = join16(tmpdir2(), `assistants-tts-${Date.now()}.wav`);
|
|
44938
45229
|
const args = ["-w", output];
|
|
44939
45230
|
if (this.voiceId) {
|
|
44940
45231
|
args.push("-v", this.voiceId);
|
|
@@ -44961,14 +45252,14 @@ class SystemTTS {
|
|
|
44961
45252
|
// packages/core/src/voice/player.ts
|
|
44962
45253
|
import { spawn } from "child_process";
|
|
44963
45254
|
import { tmpdir as tmpdir3 } from "os";
|
|
44964
|
-
import { join as
|
|
45255
|
+
import { join as join17 } from "path";
|
|
44965
45256
|
import { unlink as unlink4, writeFileSync as writeFileSync6 } from "fs";
|
|
44966
45257
|
class AudioPlayer {
|
|
44967
45258
|
currentProcess = null;
|
|
44968
45259
|
playing = false;
|
|
44969
45260
|
async play(audio, options = {}) {
|
|
44970
45261
|
const format = options.format ?? "mp3";
|
|
44971
|
-
const tempFile =
|
|
45262
|
+
const tempFile = join17(tmpdir3(), `assistants-audio-${Date.now()}.${format}`);
|
|
44972
45263
|
writeFileSync6(tempFile, Buffer.from(audio));
|
|
44973
45264
|
const player = this.resolvePlayer(format);
|
|
44974
45265
|
if (!player) {
|
|
@@ -45036,7 +45327,7 @@ class AudioPlayer {
|
|
|
45036
45327
|
// packages/core/src/voice/recorder.ts
|
|
45037
45328
|
import { spawn as spawn2 } from "child_process";
|
|
45038
45329
|
import { tmpdir as tmpdir4 } from "os";
|
|
45039
|
-
import { join as
|
|
45330
|
+
import { join as join18 } from "path";
|
|
45040
45331
|
import { readFileSync as readFileSync7, unlink as unlink5 } from "fs";
|
|
45041
45332
|
class AudioRecorder {
|
|
45042
45333
|
currentProcess = null;
|
|
@@ -45047,7 +45338,7 @@ class AudioRecorder {
|
|
|
45047
45338
|
const duration = options.durationSeconds ?? 5;
|
|
45048
45339
|
const sampleRate = options.sampleRate ?? 16000;
|
|
45049
45340
|
const channels = options.channels ?? 1;
|
|
45050
|
-
const output =
|
|
45341
|
+
const output = join18(tmpdir4(), `assistants-record-${Date.now()}.wav`);
|
|
45051
45342
|
const recorder = this.resolveRecorder(sampleRate, channels, duration, output);
|
|
45052
45343
|
if (!recorder) {
|
|
45053
45344
|
throw new Error("No supported audio recorder found. Install sox or ffmpeg.");
|
|
@@ -45239,15 +45530,15 @@ class VoiceManager {
|
|
|
45239
45530
|
}
|
|
45240
45531
|
// packages/core/src/identity/assistant-manager.ts
|
|
45241
45532
|
init_src();
|
|
45242
|
-
import { existsSync as
|
|
45533
|
+
import { existsSync as existsSync12 } from "fs";
|
|
45243
45534
|
import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile7, rm as rm2 } from "fs/promises";
|
|
45244
|
-
import { join as
|
|
45535
|
+
import { join as join20 } from "path";
|
|
45245
45536
|
|
|
45246
45537
|
// packages/core/src/identity/identity-manager.ts
|
|
45247
45538
|
init_src();
|
|
45248
|
-
import { existsSync as
|
|
45539
|
+
import { existsSync as existsSync11 } from "fs";
|
|
45249
45540
|
import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile6, rm } from "fs/promises";
|
|
45250
|
-
import { join as
|
|
45541
|
+
import { join as join19 } from "path";
|
|
45251
45542
|
var DEFAULT_PROFILE = {
|
|
45252
45543
|
displayName: "Assistant",
|
|
45253
45544
|
timezone: "UTC",
|
|
@@ -45277,19 +45568,19 @@ class IdentityManager {
|
|
|
45277
45568
|
this.basePath = basePath;
|
|
45278
45569
|
}
|
|
45279
45570
|
get identitiesRoot() {
|
|
45280
|
-
return
|
|
45571
|
+
return join19(this.basePath, "assistants", this.assistantId, "identities");
|
|
45281
45572
|
}
|
|
45282
45573
|
get indexPath() {
|
|
45283
|
-
return
|
|
45574
|
+
return join19(this.identitiesRoot, "index.json");
|
|
45284
45575
|
}
|
|
45285
45576
|
get activePath() {
|
|
45286
|
-
return
|
|
45577
|
+
return join19(this.identitiesRoot, "active.json");
|
|
45287
45578
|
}
|
|
45288
45579
|
identityPath(id) {
|
|
45289
|
-
return
|
|
45580
|
+
return join19(this.identitiesRoot, `${id}.json`);
|
|
45290
45581
|
}
|
|
45291
45582
|
assistantConfigPath() {
|
|
45292
|
-
return
|
|
45583
|
+
return join19(this.basePath, "assistants", this.assistantId, "config.json");
|
|
45293
45584
|
}
|
|
45294
45585
|
async initialize() {
|
|
45295
45586
|
await mkdir4(this.identitiesRoot, { recursive: true });
|
|
@@ -45395,7 +45686,7 @@ class IdentityManager {
|
|
|
45395
45686
|
`);
|
|
45396
45687
|
}
|
|
45397
45688
|
async readIndex() {
|
|
45398
|
-
if (!
|
|
45689
|
+
if (!existsSync11(this.indexPath)) {
|
|
45399
45690
|
return { identities: [] };
|
|
45400
45691
|
}
|
|
45401
45692
|
try {
|
|
@@ -45420,7 +45711,7 @@ class IdentityManager {
|
|
|
45420
45711
|
}
|
|
45421
45712
|
async readIdentity(id) {
|
|
45422
45713
|
const path2 = this.identityPath(id);
|
|
45423
|
-
if (!
|
|
45714
|
+
if (!existsSync11(path2))
|
|
45424
45715
|
return null;
|
|
45425
45716
|
try {
|
|
45426
45717
|
const raw = await readFile7(path2, "utf-8");
|
|
@@ -45434,7 +45725,7 @@ class IdentityManager {
|
|
|
45434
45725
|
await writeFile6(this.identityPath(identity.id), JSON.stringify(identity, null, 2));
|
|
45435
45726
|
}
|
|
45436
45727
|
async readActive() {
|
|
45437
|
-
if (!
|
|
45728
|
+
if (!existsSync11(this.activePath))
|
|
45438
45729
|
return null;
|
|
45439
45730
|
try {
|
|
45440
45731
|
const raw = await readFile7(this.activePath, "utf-8");
|
|
@@ -45449,7 +45740,7 @@ class IdentityManager {
|
|
|
45449
45740
|
await writeFile6(this.activePath, JSON.stringify({ id }, null, 2));
|
|
45450
45741
|
}
|
|
45451
45742
|
async loadAssistant() {
|
|
45452
|
-
if (!
|
|
45743
|
+
if (!existsSync11(this.assistantConfigPath()))
|
|
45453
45744
|
return null;
|
|
45454
45745
|
try {
|
|
45455
45746
|
const raw = await readFile7(this.assistantConfigPath(), "utf-8");
|
|
@@ -45473,16 +45764,16 @@ class AssistantManager {
|
|
|
45473
45764
|
this.basePath = basePath;
|
|
45474
45765
|
}
|
|
45475
45766
|
get assistantsRoot() {
|
|
45476
|
-
return
|
|
45767
|
+
return join20(this.basePath, "assistants");
|
|
45477
45768
|
}
|
|
45478
45769
|
get indexPath() {
|
|
45479
|
-
return
|
|
45770
|
+
return join20(this.assistantsRoot, "index.json");
|
|
45480
45771
|
}
|
|
45481
45772
|
get activePath() {
|
|
45482
|
-
return
|
|
45773
|
+
return join20(this.basePath, "active.json");
|
|
45483
45774
|
}
|
|
45484
45775
|
assistantConfigPath(id) {
|
|
45485
|
-
return
|
|
45776
|
+
return join20(this.assistantsRoot, id, "config.json");
|
|
45486
45777
|
}
|
|
45487
45778
|
async initialize() {
|
|
45488
45779
|
await mkdir5(this.assistantsRoot, { recursive: true });
|
|
@@ -45536,7 +45827,7 @@ class AssistantManager {
|
|
|
45536
45827
|
if (!this.assistants.has(id)) {
|
|
45537
45828
|
throw new Error(`Assistant ${id} not found`);
|
|
45538
45829
|
}
|
|
45539
|
-
await rm2(
|
|
45830
|
+
await rm2(join20(this.assistantsRoot, id), { recursive: true, force: true });
|
|
45540
45831
|
this.assistants.delete(id);
|
|
45541
45832
|
await this.removeFromIndex(id);
|
|
45542
45833
|
if (this.activeId === id) {
|
|
@@ -45567,7 +45858,7 @@ class AssistantManager {
|
|
|
45567
45858
|
return new IdentityManager(assistantId, this.basePath);
|
|
45568
45859
|
}
|
|
45569
45860
|
async readIndex() {
|
|
45570
|
-
if (!
|
|
45861
|
+
if (!existsSync12(this.indexPath)) {
|
|
45571
45862
|
return { assistants: [] };
|
|
45572
45863
|
}
|
|
45573
45864
|
try {
|
|
@@ -45592,7 +45883,7 @@ class AssistantManager {
|
|
|
45592
45883
|
}
|
|
45593
45884
|
async readAssistant(id) {
|
|
45594
45885
|
const configPath = this.assistantConfigPath(id);
|
|
45595
|
-
if (!
|
|
45886
|
+
if (!existsSync12(configPath))
|
|
45596
45887
|
return null;
|
|
45597
45888
|
try {
|
|
45598
45889
|
const raw = await readFile8(configPath, "utf-8");
|
|
@@ -45602,12 +45893,12 @@ class AssistantManager {
|
|
|
45602
45893
|
}
|
|
45603
45894
|
}
|
|
45604
45895
|
async persistAssistant(assistant) {
|
|
45605
|
-
const dir =
|
|
45896
|
+
const dir = join20(this.assistantsRoot, assistant.id);
|
|
45606
45897
|
await mkdir5(dir, { recursive: true });
|
|
45607
45898
|
await writeFile7(this.assistantConfigPath(assistant.id), JSON.stringify(assistant, null, 2));
|
|
45608
45899
|
}
|
|
45609
45900
|
async readActive() {
|
|
45610
|
-
if (!
|
|
45901
|
+
if (!existsSync12(this.activePath))
|
|
45611
45902
|
return null;
|
|
45612
45903
|
try {
|
|
45613
45904
|
const raw = await readFile8(this.activePath, "utf-8");
|
|
@@ -46062,7 +46353,7 @@ class AgentLoop {
|
|
|
46062
46353
|
if (toolInput.cwd === undefined) {
|
|
46063
46354
|
toolInput.cwd = this.cwd;
|
|
46064
46355
|
}
|
|
46065
|
-
if (toolInput.sessionId ===
|
|
46356
|
+
if (typeof toolInput.sessionId !== "string" || toolInput.sessionId.length === 0) {
|
|
46066
46357
|
toolInput.sessionId = this.sessionId;
|
|
46067
46358
|
}
|
|
46068
46359
|
toolCall.input = toolInput;
|
|
@@ -46098,7 +46389,7 @@ class AgentLoop {
|
|
|
46098
46389
|
if (input.cwd === undefined) {
|
|
46099
46390
|
input.cwd = this.cwd;
|
|
46100
46391
|
}
|
|
46101
|
-
if (input.sessionId ===
|
|
46392
|
+
if (typeof input.sessionId !== "string" || input.sessionId.length === 0) {
|
|
46102
46393
|
input.sessionId = this.sessionId;
|
|
46103
46394
|
}
|
|
46104
46395
|
if (preHookResult?.continue === false || preHookResult?.permissionDecision === "deny") {
|
|
@@ -46444,7 +46735,7 @@ ${content.trim()}`);
|
|
|
46444
46735
|
const heartbeatConfig = this.buildHeartbeatConfig(this.config);
|
|
46445
46736
|
if (!heartbeatConfig)
|
|
46446
46737
|
return;
|
|
46447
|
-
const statePath =
|
|
46738
|
+
const statePath = join21(getConfigDir(), "state", `${this.sessionId}.json`);
|
|
46448
46739
|
this.heartbeatManager = new HeartbeatManager(heartbeatConfig);
|
|
46449
46740
|
this.heartbeatPersistence = new StatePersistence(statePath);
|
|
46450
46741
|
this.heartbeatRecovery = new RecoveryManager(this.heartbeatPersistence, heartbeatConfig.persistPath, heartbeatConfig.staleThresholdMs, {
|
|
@@ -46493,7 +46784,7 @@ ${content.trim()}`);
|
|
|
46493
46784
|
async startEnergySystem() {
|
|
46494
46785
|
if (!this.config || this.config.energy?.enabled === false)
|
|
46495
46786
|
return;
|
|
46496
|
-
const statePath =
|
|
46787
|
+
const statePath = join21(getConfigDir(), "energy", "state.json");
|
|
46497
46788
|
this.energyManager = new EnergyManager(this.config.energy, new EnergyStorage(statePath));
|
|
46498
46789
|
await this.energyManager.initialize();
|
|
46499
46790
|
this.refreshEnergyEffects();
|
|
@@ -46739,7 +47030,7 @@ ${this.identityContext}`);
|
|
|
46739
47030
|
return null;
|
|
46740
47031
|
const intervalMs = Math.max(1000, config.heartbeat?.intervalMs ?? 15000);
|
|
46741
47032
|
const staleThresholdMs = Math.max(intervalMs * 2, config.heartbeat?.staleThresholdMs ?? 120000);
|
|
46742
|
-
const persistPath = config.heartbeat?.persistPath ??
|
|
47033
|
+
const persistPath = config.heartbeat?.persistPath ?? join21(getConfigDir(), "heartbeats", `${this.sessionId}.json`);
|
|
46743
47034
|
return {
|
|
46744
47035
|
intervalMs,
|
|
46745
47036
|
staleThresholdMs,
|
|
@@ -46835,21 +47126,21 @@ init_anthropic();
|
|
|
46835
47126
|
init_src();
|
|
46836
47127
|
|
|
46837
47128
|
// packages/core/src/logger.ts
|
|
46838
|
-
import { existsSync as
|
|
46839
|
-
import { join as
|
|
47129
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, appendFileSync, readdirSync as readdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
47130
|
+
import { join as join22 } from "path";
|
|
46840
47131
|
class Logger {
|
|
46841
47132
|
logDir;
|
|
46842
47133
|
logFile;
|
|
46843
47134
|
sessionId;
|
|
46844
47135
|
constructor(sessionId, basePath) {
|
|
46845
47136
|
this.sessionId = sessionId;
|
|
46846
|
-
this.logDir =
|
|
47137
|
+
this.logDir = join22(basePath || getConfigDir(), "logs");
|
|
46847
47138
|
this.ensureDir(this.logDir);
|
|
46848
47139
|
const date = new Date().toISOString().split("T")[0];
|
|
46849
|
-
this.logFile =
|
|
47140
|
+
this.logFile = join22(this.logDir, `${date}.log`);
|
|
46850
47141
|
}
|
|
46851
47142
|
ensureDir(dir) {
|
|
46852
|
-
if (!
|
|
47143
|
+
if (!existsSync13(dir)) {
|
|
46853
47144
|
mkdirSync8(dir, { recursive: true });
|
|
46854
47145
|
}
|
|
46855
47146
|
}
|
|
@@ -46890,12 +47181,12 @@ class SessionStorage {
|
|
|
46890
47181
|
constructor(sessionId, basePath, assistantId) {
|
|
46891
47182
|
this.sessionId = sessionId;
|
|
46892
47183
|
const root = basePath || getConfigDir();
|
|
46893
|
-
this.sessionsDir = assistantId ?
|
|
47184
|
+
this.sessionsDir = assistantId ? join22(root, "assistants", assistantId, "sessions") : join22(root, "sessions");
|
|
46894
47185
|
this.ensureDir(this.sessionsDir);
|
|
46895
|
-
this.sessionFile =
|
|
47186
|
+
this.sessionFile = join22(this.sessionsDir, `${sessionId}.json`);
|
|
46896
47187
|
}
|
|
46897
47188
|
ensureDir(dir) {
|
|
46898
|
-
if (!
|
|
47189
|
+
if (!existsSync13(dir)) {
|
|
46899
47190
|
mkdirSync8(dir, { recursive: true });
|
|
46900
47191
|
}
|
|
46901
47192
|
}
|
|
@@ -46909,7 +47200,7 @@ class SessionStorage {
|
|
|
46909
47200
|
}
|
|
46910
47201
|
load() {
|
|
46911
47202
|
try {
|
|
46912
|
-
if (!
|
|
47203
|
+
if (!existsSync13(this.sessionFile))
|
|
46913
47204
|
return null;
|
|
46914
47205
|
return JSON.parse(readFileSync8(this.sessionFile, "utf-8"));
|
|
46915
47206
|
} catch {
|
|
@@ -46918,8 +47209,8 @@ class SessionStorage {
|
|
|
46918
47209
|
}
|
|
46919
47210
|
static getActiveAssistantId() {
|
|
46920
47211
|
try {
|
|
46921
|
-
const activePath =
|
|
46922
|
-
if (!
|
|
47212
|
+
const activePath = join22(getConfigDir(), "active.json");
|
|
47213
|
+
if (!existsSync13(activePath))
|
|
46923
47214
|
return null;
|
|
46924
47215
|
const raw = readFileSync8(activePath, "utf-8");
|
|
46925
47216
|
const data = JSON.parse(raw);
|
|
@@ -46932,16 +47223,16 @@ class SessionStorage {
|
|
|
46932
47223
|
const root = getConfigDir();
|
|
46933
47224
|
const resolvedId = assistantId ?? SessionStorage.getActiveAssistantId();
|
|
46934
47225
|
if (resolvedId) {
|
|
46935
|
-
const assistantDir =
|
|
46936
|
-
if (
|
|
47226
|
+
const assistantDir = join22(root, "assistants", resolvedId, "sessions");
|
|
47227
|
+
if (existsSync13(assistantDir)) {
|
|
46937
47228
|
return assistantDir;
|
|
46938
47229
|
}
|
|
46939
47230
|
}
|
|
46940
|
-
return
|
|
47231
|
+
return join22(root, "sessions");
|
|
46941
47232
|
}
|
|
46942
47233
|
static listSessions(assistantId) {
|
|
46943
47234
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
46944
|
-
if (!
|
|
47235
|
+
if (!existsSync13(sessionsDir))
|
|
46945
47236
|
return [];
|
|
46946
47237
|
const sessions = [];
|
|
46947
47238
|
const files = readdirSync4(sessionsDir);
|
|
@@ -46949,7 +47240,7 @@ class SessionStorage {
|
|
|
46949
47240
|
if (!file.endsWith(".json"))
|
|
46950
47241
|
continue;
|
|
46951
47242
|
try {
|
|
46952
|
-
const filePath =
|
|
47243
|
+
const filePath = join22(sessionsDir, file);
|
|
46953
47244
|
const stat = Bun.file(filePath);
|
|
46954
47245
|
const content = JSON.parse(readFileSync8(filePath, "utf-8"));
|
|
46955
47246
|
sessions.push({
|
|
@@ -46969,9 +47260,9 @@ class SessionStorage {
|
|
|
46969
47260
|
}
|
|
46970
47261
|
static loadSession(sessionId, assistantId) {
|
|
46971
47262
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
46972
|
-
const sessionFile =
|
|
47263
|
+
const sessionFile = join22(sessionsDir, `${sessionId}.json`);
|
|
46973
47264
|
try {
|
|
46974
|
-
if (!
|
|
47265
|
+
if (!existsSync13(sessionFile))
|
|
46975
47266
|
return null;
|
|
46976
47267
|
return JSON.parse(readFileSync8(sessionFile, "utf-8"));
|
|
46977
47268
|
} catch {
|
|
@@ -46983,18 +47274,18 @@ function initAssistantsDir() {
|
|
|
46983
47274
|
const baseDir = getConfigDir();
|
|
46984
47275
|
const dirs = [
|
|
46985
47276
|
baseDir,
|
|
46986
|
-
|
|
46987
|
-
|
|
46988
|
-
|
|
46989
|
-
|
|
46990
|
-
|
|
46991
|
-
|
|
46992
|
-
|
|
46993
|
-
|
|
46994
|
-
|
|
47277
|
+
join22(baseDir, "logs"),
|
|
47278
|
+
join22(baseDir, "assistants"),
|
|
47279
|
+
join22(baseDir, "shared", "skills"),
|
|
47280
|
+
join22(baseDir, "commands"),
|
|
47281
|
+
join22(baseDir, "temp"),
|
|
47282
|
+
join22(baseDir, "heartbeats"),
|
|
47283
|
+
join22(baseDir, "state"),
|
|
47284
|
+
join22(baseDir, "energy"),
|
|
47285
|
+
join22(baseDir, "migration")
|
|
46995
47286
|
];
|
|
46996
47287
|
for (const dir of dirs) {
|
|
46997
|
-
if (!
|
|
47288
|
+
if (!existsSync13(dir)) {
|
|
46998
47289
|
mkdirSync8(dir, { recursive: true });
|
|
46999
47290
|
}
|
|
47000
47291
|
}
|
|
@@ -47647,7 +47938,7 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47647
47938
|
const visibleSkills = getVisibleItems(filteredSkills);
|
|
47648
47939
|
const visibleCommands = getVisibleItems(filteredCommands);
|
|
47649
47940
|
const { stdout } = use_stdout_default();
|
|
47650
|
-
const terminalWidth = stdout?.columns ?? 80;
|
|
47941
|
+
const terminalWidth = Math.max(10, (stdout?.columns ?? 80) - 2);
|
|
47651
47942
|
const lines = value.split(`
|
|
47652
47943
|
`);
|
|
47653
47944
|
const lineCount = lines.length;
|
|
@@ -47657,8 +47948,8 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47657
47948
|
children: [
|
|
47658
47949
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
47659
47950
|
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
47660
|
-
color: "
|
|
47661
|
-
children: "
|
|
47951
|
+
color: "#666666",
|
|
47952
|
+
children: "-".repeat(terminalWidth)
|
|
47662
47953
|
}, undefined, false, undefined, this)
|
|
47663
47954
|
}, undefined, false, undefined, this),
|
|
47664
47955
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
@@ -47692,8 +47983,8 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47692
47983
|
}, undefined, false, undefined, this),
|
|
47693
47984
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
47694
47985
|
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
47695
|
-
color: "
|
|
47696
|
-
children: "
|
|
47986
|
+
color: "#666666",
|
|
47987
|
+
children: "-".repeat(terminalWidth)
|
|
47697
47988
|
}, undefined, false, undefined, this)
|
|
47698
47989
|
}, undefined, false, undefined, this),
|
|
47699
47990
|
isProcessing && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
@@ -47818,14 +48109,19 @@ function parseMarkdown(text, options) {
|
|
|
47818
48109
|
codeBlocks.push(match);
|
|
47819
48110
|
return `@@CODEBLOCK${codeBlocks.length - 1}@@`;
|
|
47820
48111
|
});
|
|
48112
|
+
const inlineCodeBlocks = [];
|
|
48113
|
+
result = result.replace(/`([^`\n]+)`/g, (_, code) => {
|
|
48114
|
+
inlineCodeBlocks.push(code);
|
|
48115
|
+
return `@@INLINECODE${inlineCodeBlocks.length - 1}@@`;
|
|
48116
|
+
});
|
|
47821
48117
|
const blockSections = [];
|
|
47822
48118
|
if (!options?.skipBlocks) {
|
|
47823
48119
|
result = extractBlockSections(result, blockSections);
|
|
47824
48120
|
}
|
|
47825
|
-
result = result.replace(
|
|
47826
|
-
result = result.replace(/__(
|
|
47827
|
-
result = result.replace(
|
|
47828
|
-
result = result.replace(/_(
|
|
48121
|
+
result = result.replace(/(^|[\s([{>])\*\*([^*]+?)\*\*(?=[\s)\]}<.,!?;:]|$)/gm, (_, lead, text2) => `${lead}${source_default.bold(text2)}`);
|
|
48122
|
+
result = result.replace(/(^|[\s([{>])__([^_]+?)__(?=[\s)\]}<.,!?;:]|$)/gm, (_, lead, text2) => `${lead}${source_default.bold(text2)}`);
|
|
48123
|
+
result = result.replace(/(^|[\s([{>])\*([^*\n]+?)\*(?=[\s)\]}<.,!?;:]|$)/gm, (_, lead, text2) => `${lead}${source_default.italic(text2)}`);
|
|
48124
|
+
result = result.replace(/(^|[\s([{>])_([^_\n]+?)_(?=[\s)\]}<.,!?;:]|$)/gm, (_, lead, text2) => `${lead}${source_default.italic(text2)}`);
|
|
47829
48125
|
result = result.replace(/`([^`]+)`/g, (_, code) => source_default.dim(code));
|
|
47830
48126
|
result = result.replace(/^### (.+)$/gm, (_, text2) => source_default.bold(text2));
|
|
47831
48127
|
result = result.replace(/^## (.+)$/gm, (_, text2) => source_default.bold(text2));
|
|
@@ -47848,6 +48144,10 @@ function parseMarkdown(text, options) {
|
|
|
47848
48144
|
const code = block.replace(/```\w*\n?/g, "").replace(/```$/g, "").trim();
|
|
47849
48145
|
return source_default.dim(code);
|
|
47850
48146
|
});
|
|
48147
|
+
result = result.replace(/@@INLINECODE(\d+)@@/g, (_, index) => {
|
|
48148
|
+
const code = inlineCodeBlocks[parseInt(index, 10)] ?? "";
|
|
48149
|
+
return source_default.dim(code);
|
|
48150
|
+
});
|
|
47851
48151
|
return result.trimEnd();
|
|
47852
48152
|
}
|
|
47853
48153
|
var ALLOWED_BLOCK_TYPES = new Set(["info", "success", "warning", "error", "note", "command"]);
|
|
@@ -48083,7 +48383,7 @@ function renderBlockSection(section, maxWidth) {
|
|
|
48083
48383
|
if (section.kind === "grid") {
|
|
48084
48384
|
const adjustedWidth2 = maxWidth ? Math.max(20, maxWidth - section.indent.length) : undefined;
|
|
48085
48385
|
if (section.cards.length === 0) {
|
|
48086
|
-
return renderCard({ type: "note", title: "Grid", body: section.body }, adjustedWidth2, section.indent).join(`
|
|
48386
|
+
return renderCard({ type: "note", title: "Grid", body: section.body }, adjustedWidth2, section.indent, Boolean(adjustedWidth2)).join(`
|
|
48087
48387
|
`);
|
|
48088
48388
|
}
|
|
48089
48389
|
return renderCardGrid(section.cards, section.columns, adjustedWidth2, section.indent);
|
|
@@ -48215,7 +48515,15 @@ function formatMarkdownTables(text, maxWidth) {
|
|
|
48215
48515
|
const lines = text.split(`
|
|
48216
48516
|
`);
|
|
48217
48517
|
const output = [];
|
|
48218
|
-
const isSeparator = (line) =>
|
|
48518
|
+
const isSeparator = (line) => {
|
|
48519
|
+
const trimmed = line.trim();
|
|
48520
|
+
if (!trimmed)
|
|
48521
|
+
return false;
|
|
48522
|
+
const withoutPipes = trimmed.replace(/\|/g, "");
|
|
48523
|
+
if (!withoutPipes)
|
|
48524
|
+
return false;
|
|
48525
|
+
return /^[\s:-]+$/.test(withoutPipes);
|
|
48526
|
+
};
|
|
48219
48527
|
const hasPipes = (line) => line.includes("|");
|
|
48220
48528
|
let i = 0;
|
|
48221
48529
|
while (i < lines.length) {
|
|
@@ -48242,7 +48550,31 @@ function formatMarkdownTables(text, maxWidth) {
|
|
|
48242
48550
|
function parseTableRow(line) {
|
|
48243
48551
|
const trimmed = line.trim();
|
|
48244
48552
|
const withoutEdges = trimmed.replace(/^\|/, "").replace(/\|$/, "");
|
|
48245
|
-
|
|
48553
|
+
const cells = [];
|
|
48554
|
+
let current = "";
|
|
48555
|
+
let escaping = false;
|
|
48556
|
+
for (let i = 0;i < withoutEdges.length; i += 1) {
|
|
48557
|
+
const ch = withoutEdges[i];
|
|
48558
|
+
if (escaping) {
|
|
48559
|
+
current += ch;
|
|
48560
|
+
escaping = false;
|
|
48561
|
+
continue;
|
|
48562
|
+
}
|
|
48563
|
+
if (ch === "\\") {
|
|
48564
|
+
escaping = true;
|
|
48565
|
+
continue;
|
|
48566
|
+
}
|
|
48567
|
+
if (ch === "|") {
|
|
48568
|
+
cells.push(current);
|
|
48569
|
+
current = "";
|
|
48570
|
+
continue;
|
|
48571
|
+
}
|
|
48572
|
+
current += ch;
|
|
48573
|
+
}
|
|
48574
|
+
if (escaping)
|
|
48575
|
+
current += "\\";
|
|
48576
|
+
cells.push(current);
|
|
48577
|
+
return cells.map((cell) => cell.replace(/[\r\n]+/g, " ").trim());
|
|
48246
48578
|
}
|
|
48247
48579
|
function renderTable(header, rows, maxWidth) {
|
|
48248
48580
|
const colCount = Math.max(header.length, ...rows.map((r) => r.length));
|
|
@@ -48456,11 +48788,17 @@ function wrapAnsiLine(line, width) {
|
|
|
48456
48788
|
const result = [];
|
|
48457
48789
|
let current = "";
|
|
48458
48790
|
let visible = 0;
|
|
48791
|
+
let activeAnsi = "";
|
|
48459
48792
|
let i = 0;
|
|
48460
48793
|
while (i < line.length) {
|
|
48461
48794
|
const match = line.slice(i).match(/^\x1b\[[0-9;]*m/);
|
|
48462
48795
|
if (match) {
|
|
48463
48796
|
current += match[0];
|
|
48797
|
+
if (match[0] === "\x1B[0m") {
|
|
48798
|
+
activeAnsi = "";
|
|
48799
|
+
} else {
|
|
48800
|
+
activeAnsi += match[0];
|
|
48801
|
+
}
|
|
48464
48802
|
i += match[0].length;
|
|
48465
48803
|
continue;
|
|
48466
48804
|
}
|
|
@@ -48469,7 +48807,7 @@ function wrapAnsiLine(line, width) {
|
|
|
48469
48807
|
i += 1;
|
|
48470
48808
|
if (visible >= width) {
|
|
48471
48809
|
result.push(current);
|
|
48472
|
-
current =
|
|
48810
|
+
current = activeAnsi;
|
|
48473
48811
|
visible = 0;
|
|
48474
48812
|
}
|
|
48475
48813
|
}
|
|
@@ -48480,6 +48818,7 @@ function wrapAnsiLine(line, width) {
|
|
|
48480
48818
|
function truncateAnsi(line, width) {
|
|
48481
48819
|
if (stripAnsi2(line).length <= width)
|
|
48482
48820
|
return line;
|
|
48821
|
+
const hasAnsi = /\x1b\[[0-9;]*m/.test(line);
|
|
48483
48822
|
if (width <= 3) {
|
|
48484
48823
|
let result = "";
|
|
48485
48824
|
let visible2 = 0;
|
|
@@ -48495,7 +48834,7 @@ function truncateAnsi(line, width) {
|
|
|
48495
48834
|
visible2 += 1;
|
|
48496
48835
|
i2 += 1;
|
|
48497
48836
|
}
|
|
48498
|
-
return result;
|
|
48837
|
+
return hasAnsi && !result.endsWith("\x1B[0m") ? result + "\x1B[0m" : result;
|
|
48499
48838
|
}
|
|
48500
48839
|
const suffix = "...";
|
|
48501
48840
|
const target = Math.max(0, width - suffix.length);
|
|
@@ -48513,7 +48852,8 @@ function truncateAnsi(line, width) {
|
|
|
48513
48852
|
visible += 1;
|
|
48514
48853
|
i += 1;
|
|
48515
48854
|
}
|
|
48516
|
-
|
|
48855
|
+
const truncated = current + suffix;
|
|
48856
|
+
return hasAnsi && !truncated.endsWith("\x1B[0m") ? truncated + "\x1B[0m" : truncated;
|
|
48517
48857
|
}
|
|
48518
48858
|
|
|
48519
48859
|
// packages/terminal/src/components/toolDisplay.ts
|
|
@@ -48537,7 +48877,7 @@ function truncateToolResult(toolResult, maxLines = 15, maxChars = 3000) {
|
|
|
48537
48877
|
if (content.length > maxChars) {
|
|
48538
48878
|
content = content.slice(0, maxChars) + "...";
|
|
48539
48879
|
}
|
|
48540
|
-
return prefix + content.
|
|
48880
|
+
return prefix + content.trimEnd();
|
|
48541
48881
|
}
|
|
48542
48882
|
function formatToolResultNicely(toolName, content, isError) {
|
|
48543
48883
|
if (isError) {
|
|
@@ -48706,7 +49046,7 @@ function estimateMessageLines(message, maxWidth) {
|
|
|
48706
49046
|
const hasContent = contentLines.length > 0;
|
|
48707
49047
|
const prefixWidth = message.role === "user" || message.role === "assistant" ? 2 : 0;
|
|
48708
49048
|
const effectiveWidth = maxWidth ? Math.max(1, maxWidth - prefixWidth) : maxWidth;
|
|
48709
|
-
const wrappedLines = contentLines.length > 0 ? countWrappedLines(contentLines, effectiveWidth) : 0;
|
|
49049
|
+
const wrappedLines = typeof message.__lineCount === "number" ? message.__lineCount : contentLines.length > 0 ? countWrappedLines(contentLines, effectiveWidth) : 0;
|
|
48710
49050
|
let lines = hasContent ? Math.max(1, wrappedLines) : 0;
|
|
48711
49051
|
if (message.role === "assistant" && message.toolCalls?.length) {
|
|
48712
49052
|
lines += estimateToolPanelLines(message.toolCalls, message.toolResults, hasContent);
|
|
@@ -48786,11 +49126,13 @@ function Messages3({
|
|
|
48786
49126
|
const columns = stdout?.columns ?? 80;
|
|
48787
49127
|
const messageWidth = Math.max(1, columns - 2);
|
|
48788
49128
|
const wrapWidth = messageWidth;
|
|
49129
|
+
const messageGroups = import_react24.useMemo(() => groupConsecutiveToolMessages(messages), [messages]);
|
|
49130
|
+
const messageItems = import_react24.useMemo(() => {
|
|
49131
|
+
return messageGroups.map((group) => group.type === "single" ? { kind: "message", message: group.message } : { kind: "grouped", messages: group.messages });
|
|
49132
|
+
}, [messageGroups]);
|
|
48789
49133
|
const items = import_react24.useMemo(() => {
|
|
48790
49134
|
const output = [];
|
|
48791
|
-
|
|
48792
|
-
output.push({ kind: "message", message });
|
|
48793
|
-
}
|
|
49135
|
+
output.push(...messageItems);
|
|
48794
49136
|
for (const entry of activityLog) {
|
|
48795
49137
|
output.push({ kind: "activity", entry });
|
|
48796
49138
|
}
|
|
@@ -48802,7 +49144,7 @@ function Messages3({
|
|
|
48802
49144
|
const lineSpans = import_react24.useMemo(() => {
|
|
48803
49145
|
let cursor = 0;
|
|
48804
49146
|
return items.map((item, index) => {
|
|
48805
|
-
const lines = item.kind === "activity" ? estimateActivityEntryLines(item.entry, wrapWidth, messageWidth) : estimateMessageLines(item.message, messageWidth);
|
|
49147
|
+
const lines = item.kind === "activity" ? estimateActivityEntryLines(item.entry, wrapWidth, messageWidth) : item.kind === "grouped" ? estimateGroupedToolLines(item.messages, messageWidth) : estimateMessageLines(item.message, messageWidth);
|
|
48806
49148
|
const start = cursor;
|
|
48807
49149
|
cursor += lines;
|
|
48808
49150
|
return { item, index, start, end: cursor, lines };
|
|
@@ -48812,16 +49154,15 @@ function Messages3({
|
|
|
48812
49154
|
const endLine = Math.max(0, totalLines - scrollOffsetLines);
|
|
48813
49155
|
const startLine = Math.max(0, endLine - maxVisibleLines);
|
|
48814
49156
|
const visibleSpans = lineSpans.filter((span) => span.end > startLine && span.start < endLine);
|
|
48815
|
-
const
|
|
49157
|
+
const visibleMessageItems = visibleSpans.filter((span) => span.item.kind === "message" || span.item.kind === "grouped").map((span) => span.item);
|
|
48816
49158
|
const visibleActivity = visibleSpans.filter((span) => span.item.kind === "activity").map((span) => span.item.entry);
|
|
48817
49159
|
const visibleStreaming = visibleSpans.filter((span) => span.item.kind === "streaming").map((span) => span.item.message);
|
|
48818
49160
|
const showCurrentResponse = Boolean(currentResponse) && streamingMessages.length === 0;
|
|
48819
|
-
const
|
|
48820
|
-
|
|
48821
|
-
|
|
48822
|
-
return { id: group.message.id, group };
|
|
49161
|
+
const historicalItems = visibleMessageItems.map((item) => {
|
|
49162
|
+
if (item.kind === "message") {
|
|
49163
|
+
return { id: item.message.id, item };
|
|
48823
49164
|
}
|
|
48824
|
-
return { id:
|
|
49165
|
+
return { id: item.messages[0].id, item };
|
|
48825
49166
|
});
|
|
48826
49167
|
const toolResultMap = import_react24.useMemo(() => {
|
|
48827
49168
|
const map = new Map;
|
|
@@ -48855,14 +49196,14 @@ function Messages3({
|
|
|
48855
49196
|
width: "100%",
|
|
48856
49197
|
children: [
|
|
48857
49198
|
historicalItems.map((item) => {
|
|
48858
|
-
if (item.
|
|
49199
|
+
if (item.item.kind === "message") {
|
|
48859
49200
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MessageBubble, {
|
|
48860
|
-
message: item.
|
|
49201
|
+
message: item.item.message,
|
|
48861
49202
|
queuedMessageIds
|
|
48862
49203
|
}, item.id, false, undefined, this);
|
|
48863
49204
|
}
|
|
48864
49205
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(CombinedToolMessage, {
|
|
48865
|
-
messages: item.
|
|
49206
|
+
messages: item.item.messages
|
|
48866
49207
|
}, item.id, false, undefined, this);
|
|
48867
49208
|
}),
|
|
48868
49209
|
visibleActivity.map((entry) => {
|
|
@@ -49006,11 +49347,35 @@ function CombinedToolMessage({ messages }) {
|
|
|
49006
49347
|
allToolResults.push(...msg.toolResults);
|
|
49007
49348
|
}
|
|
49008
49349
|
}
|
|
49009
|
-
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(
|
|
49010
|
-
|
|
49011
|
-
|
|
49350
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
49351
|
+
marginY: 1,
|
|
49352
|
+
children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(ToolCallPanel, {
|
|
49353
|
+
toolCalls: allToolCalls,
|
|
49354
|
+
toolResults: allToolResults
|
|
49355
|
+
}, undefined, false, undefined, this)
|
|
49012
49356
|
}, undefined, false, undefined, this);
|
|
49013
49357
|
}
|
|
49358
|
+
function estimateGroupedToolLines(messages, messageWidth) {
|
|
49359
|
+
const toolCalls = [];
|
|
49360
|
+
const toolResults = [];
|
|
49361
|
+
for (const msg of messages) {
|
|
49362
|
+
if (msg.toolCalls)
|
|
49363
|
+
toolCalls.push(...msg.toolCalls);
|
|
49364
|
+
if (msg.toolResults)
|
|
49365
|
+
toolResults.push(...msg.toolResults);
|
|
49366
|
+
}
|
|
49367
|
+
if (toolCalls.length === 0)
|
|
49368
|
+
return 0;
|
|
49369
|
+
const synthetic = {
|
|
49370
|
+
id: "grouped-tool-call",
|
|
49371
|
+
role: "assistant",
|
|
49372
|
+
content: "",
|
|
49373
|
+
timestamp: 0,
|
|
49374
|
+
toolCalls,
|
|
49375
|
+
toolResults: toolResults.length > 0 ? toolResults : undefined
|
|
49376
|
+
};
|
|
49377
|
+
return estimateMessageLines(synthetic, messageWidth);
|
|
49378
|
+
}
|
|
49014
49379
|
function MessageBubble({ message, queuedMessageIds }) {
|
|
49015
49380
|
const isUser = message.role === "user";
|
|
49016
49381
|
const isSystem = message.role === "system";
|
|
@@ -49157,7 +49522,7 @@ function ToolCallPanel({
|
|
|
49157
49522
|
const statusColor = result ? result.isError ? "red" : "green" : "yellow";
|
|
49158
49523
|
const displayName = getToolDisplayName(toolCall);
|
|
49159
49524
|
const context2 = getToolContext(toolCall);
|
|
49160
|
-
const maxLine = Math.max(
|
|
49525
|
+
const maxLine = Math.max(1, innerWidth - 2);
|
|
49161
49526
|
const summaryLine = truncate(formatToolCall(toolCall), maxLine);
|
|
49162
49527
|
const resultText = result ? indentMultiline(truncateToolResult(result, 4, 400), " ") : "";
|
|
49163
49528
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
@@ -49333,8 +49698,9 @@ function formatScheduleCall(input) {
|
|
|
49333
49698
|
return "Listing scheduled tasks";
|
|
49334
49699
|
case "create":
|
|
49335
49700
|
const cmd = truncate(String(input.command || ""), 30);
|
|
49336
|
-
const
|
|
49337
|
-
|
|
49701
|
+
const when = input.cron ? `cron ${input.cron}` : String(input.at || "");
|
|
49702
|
+
const schedule = when ? ` (${truncate(String(when), 40)})` : "";
|
|
49703
|
+
return `Creating schedule: "${cmd}"${schedule}`;
|
|
49338
49704
|
case "update":
|
|
49339
49705
|
return `Updating schedule: ${input.id || "unknown"}`;
|
|
49340
49706
|
case "delete":
|
|
@@ -49589,7 +49955,7 @@ function ProcessingIndicator({
|
|
|
49589
49955
|
var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
|
|
49590
49956
|
function WelcomeBanner({ version, model, directory }) {
|
|
49591
49957
|
const homeDir = process.env.HOME || "";
|
|
49592
|
-
const displayDir = directory.startsWith(homeDir) ? "~" + directory.slice(homeDir.length) : directory;
|
|
49958
|
+
const displayDir = homeDir && directory.startsWith(homeDir) ? "~" + directory.slice(homeDir.length) : directory;
|
|
49593
49959
|
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
49594
49960
|
flexDirection: "column",
|
|
49595
49961
|
marginBottom: 1,
|
|
@@ -49675,7 +50041,7 @@ function formatSessionTime(timestamp) {
|
|
|
49675
50041
|
}
|
|
49676
50042
|
function formatPath(cwd2) {
|
|
49677
50043
|
const home = process.env.HOME || "";
|
|
49678
|
-
if (cwd2.startsWith(home)) {
|
|
50044
|
+
if (home && cwd2.startsWith(home)) {
|
|
49679
50045
|
return "~" + cwd2.slice(home.length);
|
|
49680
50046
|
}
|
|
49681
50047
|
return cwd2;
|
|
@@ -49831,6 +50197,16 @@ function wrapTextLines(text, wrapChars) {
|
|
|
49831
50197
|
function stripAnsi6(text) {
|
|
49832
50198
|
return text.replace(/\x1B\[[0-9;]*m/g, "");
|
|
49833
50199
|
}
|
|
50200
|
+
function countWrappedLines2(lines, maxWidth) {
|
|
50201
|
+
if (!maxWidth || maxWidth <= 0)
|
|
50202
|
+
return lines.length;
|
|
50203
|
+
let total = 0;
|
|
50204
|
+
for (const line of lines) {
|
|
50205
|
+
const visible = stripAnsi6(line).length;
|
|
50206
|
+
total += Math.max(1, Math.ceil(visible / maxWidth));
|
|
50207
|
+
}
|
|
50208
|
+
return total;
|
|
50209
|
+
}
|
|
49834
50210
|
function chunkRenderedLines(lines, chunkLines) {
|
|
49835
50211
|
const chunks = [];
|
|
49836
50212
|
let current = [];
|
|
@@ -49881,31 +50257,36 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
49881
50257
|
continue;
|
|
49882
50258
|
}
|
|
49883
50259
|
if (msg.role === "assistant") {
|
|
49884
|
-
const
|
|
50260
|
+
const assistantWidth = options?.maxWidth ? Math.max(1, options.maxWidth - 2) : undefined;
|
|
50261
|
+
const rendered = renderMarkdown(content, { maxWidth: assistantWidth });
|
|
49885
50262
|
const renderedLines = rendered.split(`
|
|
49886
50263
|
`);
|
|
49887
50264
|
if (renderedLines.length <= chunkLines) {
|
|
49888
|
-
|
|
50265
|
+
const lineCount = countWrappedLines2(renderedLines, assistantWidth);
|
|
50266
|
+
display.push({ ...msg, content: rendered, __rendered: true, __lineCount: lineCount });
|
|
49889
50267
|
continue;
|
|
49890
50268
|
}
|
|
49891
50269
|
const chunks2 = chunkRenderedLines(renderedLines, chunkLines);
|
|
49892
50270
|
for (let i = 0;i < chunks2.length; i++) {
|
|
49893
50271
|
const chunkContent = chunks2[i].join(`
|
|
49894
50272
|
`);
|
|
50273
|
+
const lineCount = countWrappedLines2(chunks2[i], assistantWidth);
|
|
49895
50274
|
display.push({
|
|
49896
50275
|
...msg,
|
|
49897
50276
|
id: `${msg.id}::chunk-${i}`,
|
|
49898
50277
|
content: chunkContent,
|
|
49899
50278
|
__rendered: true,
|
|
50279
|
+
__lineCount: lineCount,
|
|
49900
50280
|
toolCalls: i === chunks2.length - 1 ? msg.toolCalls : undefined,
|
|
49901
50281
|
toolResults: i === chunks2.length - 1 ? msg.toolResults : undefined
|
|
49902
50282
|
});
|
|
49903
50283
|
}
|
|
49904
50284
|
continue;
|
|
49905
50285
|
}
|
|
49906
|
-
const
|
|
50286
|
+
const effectiveWrap = msg.role === "user" ? Math.max(1, wrapChars - 2) : wrapChars;
|
|
50287
|
+
const lines = wrapTextLines(content, effectiveWrap);
|
|
49907
50288
|
if (lines.length <= chunkLines) {
|
|
49908
|
-
display.push(msg);
|
|
50289
|
+
display.push({ ...msg, __lineCount: lines.length });
|
|
49909
50290
|
continue;
|
|
49910
50291
|
}
|
|
49911
50292
|
const chunks = chunkRenderedLines(lines, chunkLines);
|
|
@@ -49916,6 +50297,7 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
49916
50297
|
...msg,
|
|
49917
50298
|
id: `${msg.id}::chunk-${i}`,
|
|
49918
50299
|
content: chunkContent,
|
|
50300
|
+
__lineCount: chunks[i].length,
|
|
49919
50301
|
toolCalls: i === chunks.length - 1 ? msg.toolCalls : undefined,
|
|
49920
50302
|
toolResults: i === chunks.length - 1 ? msg.toolResults : undefined
|
|
49921
50303
|
});
|
|
@@ -49951,6 +50333,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
49951
50333
|
const [scrollOffset, setScrollOffset] = import_react29.useState(0);
|
|
49952
50334
|
const [autoScroll, setAutoScroll] = import_react29.useState(true);
|
|
49953
50335
|
const [skills, setSkills] = import_react29.useState([]);
|
|
50336
|
+
const [commands, setCommands] = import_react29.useState([]);
|
|
49954
50337
|
const responseRef = import_react29.useRef("");
|
|
49955
50338
|
const toolCallsRef = import_react29.useRef([]);
|
|
49956
50339
|
const toolResultsRef = import_react29.useRef([]);
|
|
@@ -49979,6 +50362,25 @@ function App2({ cwd: cwd2, version }) {
|
|
|
49979
50362
|
return parts.join(`
|
|
49980
50363
|
`).trim();
|
|
49981
50364
|
}, []);
|
|
50365
|
+
const loadSessionMetadata = import_react29.useCallback(async (session) => {
|
|
50366
|
+
try {
|
|
50367
|
+
const [loadedSkills, loadedCommands] = await Promise.all([
|
|
50368
|
+
session.client.getSkills(),
|
|
50369
|
+
session.client.getCommands()
|
|
50370
|
+
]);
|
|
50371
|
+
setSkills(loadedSkills.map((s) => ({
|
|
50372
|
+
name: s.name,
|
|
50373
|
+
description: s.description || "",
|
|
50374
|
+
argumentHint: s.argumentHint
|
|
50375
|
+
})));
|
|
50376
|
+
setCommands(loadedCommands.map((cmd) => ({
|
|
50377
|
+
name: cmd.name.startsWith("/") ? cmd.name : `/${cmd.name}`,
|
|
50378
|
+
description: cmd.description || ""
|
|
50379
|
+
})));
|
|
50380
|
+
} catch (err) {
|
|
50381
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
50382
|
+
}
|
|
50383
|
+
}, []);
|
|
49982
50384
|
const finalizeResponse = import_react29.useCallback((status) => {
|
|
49983
50385
|
const baseContent = buildFullResponse();
|
|
49984
50386
|
const hasContent = baseContent.length > 0;
|
|
@@ -50247,12 +50649,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50247
50649
|
});
|
|
50248
50650
|
const session = await registry.createSession(cwd2);
|
|
50249
50651
|
setActiveSessionId(session.id);
|
|
50250
|
-
|
|
50251
|
-
setSkills(loadedSkills.map((s) => ({
|
|
50252
|
-
name: s.name,
|
|
50253
|
-
description: s.description || "",
|
|
50254
|
-
argumentHint: s.argumentHint
|
|
50255
|
-
})));
|
|
50652
|
+
await loadSessionMetadata(session);
|
|
50256
50653
|
setEnergyState(session.client.getEnergyState() ?? undefined);
|
|
50257
50654
|
setVoiceState(session.client.getVoiceState() ?? undefined);
|
|
50258
50655
|
setIdentityInfo(session.client.getIdentityInfo() ?? undefined);
|
|
@@ -50266,7 +50663,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50266
50663
|
return () => {
|
|
50267
50664
|
registry.closeAll();
|
|
50268
50665
|
};
|
|
50269
|
-
}, [cwd2, registry, handleChunk, finalizeResponse, resetTurnState]);
|
|
50666
|
+
}, [cwd2, registry, handleChunk, finalizeResponse, resetTurnState, loadSessionMetadata]);
|
|
50270
50667
|
const processQueue = import_react29.useCallback(async () => {
|
|
50271
50668
|
const activeSession2 = registryRef.current.getActiveSession();
|
|
50272
50669
|
if (!activeSession2 || !activeSessionId)
|
|
@@ -50336,6 +50733,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50336
50733
|
}, [activityLog, renderWidth, wrapChars]);
|
|
50337
50734
|
const reservedLines = import_react29.useMemo(() => {
|
|
50338
50735
|
let lines = 0;
|
|
50736
|
+
lines += 2;
|
|
50339
50737
|
if (showWelcome) {
|
|
50340
50738
|
lines += 4;
|
|
50341
50739
|
}
|
|
@@ -50367,9 +50765,9 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50367
50765
|
lines += 3;
|
|
50368
50766
|
}
|
|
50369
50767
|
lines += 1;
|
|
50370
|
-
lines +=
|
|
50768
|
+
lines += 3;
|
|
50371
50769
|
if (isProcessing) {
|
|
50372
|
-
lines +=
|
|
50770
|
+
lines += 1;
|
|
50373
50771
|
}
|
|
50374
50772
|
lines += 2;
|
|
50375
50773
|
return lines;
|
|
@@ -50436,6 +50834,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50436
50834
|
setEnergyState(session.client.getEnergyState() ?? undefined);
|
|
50437
50835
|
setVoiceState(session.client.getVoiceState() ?? undefined);
|
|
50438
50836
|
setIdentityInfo(session.client.getIdentityInfo() ?? undefined);
|
|
50837
|
+
await loadSessionMetadata(session);
|
|
50439
50838
|
}
|
|
50440
50839
|
await registry.switchSession(sessionId);
|
|
50441
50840
|
setActiveSessionId(sessionId);
|
|
@@ -50453,6 +50852,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50453
50852
|
setEnergyState(newSession.client.getEnergyState() ?? undefined);
|
|
50454
50853
|
setVoiceState(newSession.client.getVoiceState() ?? undefined);
|
|
50455
50854
|
setIdentityInfo(newSession.client.getIdentityInfo() ?? undefined);
|
|
50855
|
+
await loadSessionMetadata(newSession);
|
|
50456
50856
|
} catch (err) {
|
|
50457
50857
|
setError(err instanceof Error ? err.message : "Failed to create session");
|
|
50458
50858
|
}
|
|
@@ -50783,6 +51183,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50783
51183
|
onSubmit: handleSubmit,
|
|
50784
51184
|
isProcessing,
|
|
50785
51185
|
queueLength: activeQueue.length + inlineCount,
|
|
51186
|
+
commands,
|
|
50786
51187
|
skills
|
|
50787
51188
|
}, undefined, false, undefined, this),
|
|
50788
51189
|
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Status, {
|
|
@@ -50978,7 +51379,7 @@ function formatStreamEvent(chunk) {
|
|
|
50978
51379
|
|
|
50979
51380
|
// packages/terminal/src/index.tsx
|
|
50980
51381
|
var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
50981
|
-
var VERSION3 = "0.6.
|
|
51382
|
+
var VERSION3 = "0.6.35";
|
|
50982
51383
|
process.env.ASSISTANTS_VERSION ??= VERSION3;
|
|
50983
51384
|
function parseArgs(argv) {
|
|
50984
51385
|
const args = argv.slice(2);
|
|
@@ -51134,4 +51535,4 @@ if (options.print !== null) {
|
|
|
51134
51535
|
});
|
|
51135
51536
|
}
|
|
51136
51537
|
|
|
51137
|
-
//# debugId=
|
|
51538
|
+
//# debugId=2F2CC5B1781D557164756E2164756E21
|