@hasna/assistants 0.6.34 → 0.6.36
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 +435 -180
- package/dist/index.js.map +20 -20
- 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
|
|
28329
|
+
import { readFileSync as readFileSync4, existsSync as existsSync9 } from "fs";
|
|
28330
|
+
import { homedir as homedir11 } from "os";
|
|
28332
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 :
|
|
28334
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir11();
|
|
28336
28335
|
const secretsPath = join14(homeDir, ".secrets");
|
|
28337
|
-
if (
|
|
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]+)["']?/);
|
|
@@ -37325,15 +37324,15 @@ var DEFAULT_CONFIG = {
|
|
|
37325
37324
|
},
|
|
37326
37325
|
energy: {
|
|
37327
37326
|
enabled: true,
|
|
37328
|
-
regenRate:
|
|
37329
|
-
lowEnergyThreshold:
|
|
37330
|
-
criticalThreshold:
|
|
37331
|
-
maxEnergy:
|
|
37327
|
+
regenRate: 500,
|
|
37328
|
+
lowEnergyThreshold: 3000,
|
|
37329
|
+
criticalThreshold: 1000,
|
|
37330
|
+
maxEnergy: 1e4,
|
|
37332
37331
|
costs: {
|
|
37333
|
-
message:
|
|
37334
|
-
toolCall:
|
|
37335
|
-
llmCall:
|
|
37336
|
-
longContext:
|
|
37332
|
+
message: 200,
|
|
37333
|
+
toolCall: 500,
|
|
37334
|
+
llmCall: 300,
|
|
37335
|
+
longContext: 1000
|
|
37337
37336
|
}
|
|
37338
37337
|
},
|
|
37339
37338
|
validation: {
|
|
@@ -37747,7 +37746,7 @@ function isErrorResult(result) {
|
|
|
37747
37746
|
// packages/core/src/tools/connector.ts
|
|
37748
37747
|
init_errors();
|
|
37749
37748
|
import { homedir as homedir2 } from "os";
|
|
37750
|
-
import { join as join3, delimiter, dirname as dirname2 } from "path";
|
|
37749
|
+
import { join as join3, delimiter, dirname as dirname2, extname } from "path";
|
|
37751
37750
|
import { readdirSync, statSync, existsSync as existsSync2, mkdirSync, writeFileSync, readFileSync as readFileSync2 } from "fs";
|
|
37752
37751
|
function resolveTimeout(resolve) {
|
|
37753
37752
|
resolve({ exitCode: 1 });
|
|
@@ -37835,7 +37834,11 @@ class ConnectorBridge {
|
|
|
37835
37834
|
if (!stats.isFile()) {
|
|
37836
37835
|
continue;
|
|
37837
37836
|
}
|
|
37838
|
-
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
|
+
}
|
|
37839
37842
|
if (name && !name.includes(".") && name.length > 1) {
|
|
37840
37843
|
connectorNames.add(name);
|
|
37841
37844
|
}
|
|
@@ -37889,6 +37892,7 @@ class ConnectorBridge {
|
|
|
37889
37892
|
async discover(connectorNames) {
|
|
37890
37893
|
const names = connectorNames && connectorNames.length > 0 ? connectorNames : this.autoDiscoverConnectorNames();
|
|
37891
37894
|
if (names.length === 0) {
|
|
37895
|
+
this.connectors = new Map;
|
|
37892
37896
|
return [];
|
|
37893
37897
|
}
|
|
37894
37898
|
const uncached = [];
|
|
@@ -37932,16 +37936,17 @@ class ConnectorBridge {
|
|
|
37932
37936
|
};
|
|
37933
37937
|
}
|
|
37934
37938
|
async populateCache(name) {
|
|
37935
|
-
const cli =
|
|
37939
|
+
const cli = await this.resolveConnectorCli(name);
|
|
37936
37940
|
try {
|
|
37937
37941
|
let timeoutId = null;
|
|
37938
37942
|
const timeoutPromise = new Promise((resolve) => {
|
|
37939
37943
|
timeoutId = setTimeout(resolveTimeout, 500, resolve);
|
|
37940
37944
|
});
|
|
37941
|
-
|
|
37942
|
-
|
|
37943
|
-
|
|
37944
|
-
|
|
37945
|
+
if (!cli) {
|
|
37946
|
+
ConnectorBridge.cache.set(name, null);
|
|
37947
|
+
return;
|
|
37948
|
+
}
|
|
37949
|
+
const result = await Promise.race([Bun.$`which ${cli}`.quiet().nothrow(), timeoutPromise]);
|
|
37945
37950
|
if (timeoutId) {
|
|
37946
37951
|
clearTimeout(timeoutId);
|
|
37947
37952
|
}
|
|
@@ -37955,6 +37960,30 @@ class ConnectorBridge {
|
|
|
37955
37960
|
ConnectorBridge.cache.set(name, null);
|
|
37956
37961
|
}
|
|
37957
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
|
+
}
|
|
37958
37987
|
async discoverConnector(name, cli) {
|
|
37959
37988
|
try {
|
|
37960
37989
|
const helpResult = await Bun.$`${cli} --help`.quiet();
|
|
@@ -38494,14 +38523,16 @@ ${stderr || stdout}`.trim(), {
|
|
|
38494
38523
|
|
|
38495
38524
|
// packages/core/src/tools/filesystem.ts
|
|
38496
38525
|
import { join as join4, resolve as resolve3, dirname as dirname3, sep } from "path";
|
|
38526
|
+
import { homedir as homedir5 } from "os";
|
|
38497
38527
|
init_errors();
|
|
38498
38528
|
var {Glob } = globalThis.Bun;
|
|
38499
38529
|
|
|
38500
38530
|
// packages/core/src/validation/paths.ts
|
|
38501
|
-
import { resolve, normalize } from "path";
|
|
38531
|
+
import { resolve, normalize, relative, isAbsolute } from "path";
|
|
38532
|
+
import { homedir as homedir3 } from "os";
|
|
38502
38533
|
import { lstat, realpath } from "fs/promises";
|
|
38503
38534
|
async function validatePath(inputPath, options = {}) {
|
|
38504
|
-
const normalized = normalize(inputPath);
|
|
38535
|
+
const normalized = normalize(expandHome(inputPath));
|
|
38505
38536
|
const resolved = resolve(normalized);
|
|
38506
38537
|
const allowedPaths = options.allowedPaths?.map((p) => resolve(p));
|
|
38507
38538
|
const blockedPaths = options.blockedPaths?.map((p) => resolve(p));
|
|
@@ -38522,7 +38553,7 @@ async function validatePath(inputPath, options = {}) {
|
|
|
38522
38553
|
}
|
|
38523
38554
|
} catch {}
|
|
38524
38555
|
}
|
|
38525
|
-
if (blockedPaths && blockedPaths.some((blocked) => resolved
|
|
38556
|
+
if (blockedPaths && blockedPaths.some((blocked) => isWithinPath(resolved, blocked))) {
|
|
38526
38557
|
return { valid: false, resolved, error: "Path is in blocked list" };
|
|
38527
38558
|
}
|
|
38528
38559
|
if (!isWithinAllowed(resolved, allowedPaths)) {
|
|
@@ -38530,15 +38561,35 @@ async function validatePath(inputPath, options = {}) {
|
|
|
38530
38561
|
}
|
|
38531
38562
|
return { valid: true, resolved };
|
|
38532
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
|
+
}
|
|
38533
38572
|
function isWithinAllowed(path, allowed) {
|
|
38534
38573
|
if (!allowed || allowed.length === 0)
|
|
38535
38574
|
return true;
|
|
38536
38575
|
return allowed.some((allowedPath) => path === allowedPath || path.startsWith(`${allowedPath}/`));
|
|
38537
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
|
+
}
|
|
38538
38589
|
|
|
38539
38590
|
// packages/core/src/security/path-validator.ts
|
|
38540
|
-
import { homedir as
|
|
38541
|
-
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";
|
|
38542
38593
|
import { lstat as lstat2, realpath as realpath2 } from "fs/promises";
|
|
38543
38594
|
var PROTECTED_PATHS = [
|
|
38544
38595
|
"/etc/passwd",
|
|
@@ -38550,11 +38601,12 @@ var PROTECTED_PATHS = [
|
|
|
38550
38601
|
"~/.kube/config"
|
|
38551
38602
|
];
|
|
38552
38603
|
async function isPathSafe(targetPath, operation, options = {}) {
|
|
38553
|
-
const
|
|
38554
|
-
const
|
|
38604
|
+
const expandedTarget = expandHome2(targetPath);
|
|
38605
|
+
const resolved = resolve2(expandedTarget);
|
|
38606
|
+
const home = homedir4();
|
|
38555
38607
|
for (const protectedPath of PROTECTED_PATHS) {
|
|
38556
38608
|
const expanded = protectedPath.replace("~", home);
|
|
38557
|
-
if (resolved
|
|
38609
|
+
if (isWithinPath2(resolved, expanded)) {
|
|
38558
38610
|
return {
|
|
38559
38611
|
safe: false,
|
|
38560
38612
|
reason: `Cannot ${operation} protected path: ${protectedPath}`
|
|
@@ -38576,6 +38628,24 @@ async function isPathSafe(targetPath, operation, options = {}) {
|
|
|
38576
38628
|
} catch {}
|
|
38577
38629
|
return { safe: true };
|
|
38578
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
|
+
}
|
|
38579
38649
|
|
|
38580
38650
|
// packages/core/src/tools/filesystem.ts
|
|
38581
38651
|
var currentSessionId = "default";
|
|
@@ -38592,6 +38662,17 @@ function isInScriptsFolder(path, cwd2, sessionId) {
|
|
|
38592
38662
|
}
|
|
38593
38663
|
|
|
38594
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
|
+
}
|
|
38595
38676
|
static registerAll(registry, sessionId) {
|
|
38596
38677
|
if (sessionId) {
|
|
38597
38678
|
currentSessionId = sessionId;
|
|
@@ -38644,7 +38725,7 @@ class FilesystemTools {
|
|
|
38644
38725
|
suggestion: "Provide a valid file path."
|
|
38645
38726
|
});
|
|
38646
38727
|
}
|
|
38647
|
-
const path =
|
|
38728
|
+
const path = FilesystemTools.resolveInputPath(baseCwd, rawPath);
|
|
38648
38729
|
const offset = (input.offset || 1) - 1;
|
|
38649
38730
|
const limitRaw = input.limit;
|
|
38650
38731
|
const limit = typeof limitRaw === "number" && limitRaw > 0 ? Math.floor(limitRaw) : undefined;
|
|
@@ -38703,7 +38784,10 @@ class FilesystemTools {
|
|
|
38703
38784
|
});
|
|
38704
38785
|
}
|
|
38705
38786
|
const content = await file.text();
|
|
38706
|
-
const
|
|
38787
|
+
const normalized = content.replace(/\r\n/g, `
|
|
38788
|
+
`).replace(/\r/g, `
|
|
38789
|
+
`);
|
|
38790
|
+
const lines = normalized.split(`
|
|
38707
38791
|
`);
|
|
38708
38792
|
const startLine = Math.max(0, offset);
|
|
38709
38793
|
const endLine = limit ? startLine + limit : lines.length;
|
|
@@ -38859,7 +38943,7 @@ class FilesystemTools {
|
|
|
38859
38943
|
static globExecutor = async (input) => {
|
|
38860
38944
|
const pattern = String(input.pattern || "").trim();
|
|
38861
38945
|
const baseCwd = input.cwd || process.cwd();
|
|
38862
|
-
const searchPath =
|
|
38946
|
+
const searchPath = FilesystemTools.resolveInputPath(baseCwd, input.path || ".");
|
|
38863
38947
|
try {
|
|
38864
38948
|
if (!pattern) {
|
|
38865
38949
|
throw new ToolExecutionError("Pattern is required", {
|
|
@@ -38960,7 +39044,7 @@ class FilesystemTools {
|
|
|
38960
39044
|
static grepExecutor = async (input) => {
|
|
38961
39045
|
const pattern = String(input.pattern || "").trim();
|
|
38962
39046
|
const baseCwd = input.cwd || process.cwd();
|
|
38963
|
-
const searchPath =
|
|
39047
|
+
const searchPath = FilesystemTools.resolveInputPath(baseCwd, input.path || ".");
|
|
38964
39048
|
const globPattern = input.glob || "**/*";
|
|
38965
39049
|
const caseSensitive = input.caseSensitive || false;
|
|
38966
39050
|
try {
|
|
@@ -39064,7 +39148,7 @@ class FilesystemTools {
|
|
|
39064
39148
|
};
|
|
39065
39149
|
static readPdfExecutor = async (input) => {
|
|
39066
39150
|
const baseCwd = input.cwd || process.cwd();
|
|
39067
|
-
const path =
|
|
39151
|
+
const path = FilesystemTools.resolveInputPath(baseCwd, String(input.path || ""));
|
|
39068
39152
|
try {
|
|
39069
39153
|
const safety = await isPathSafe(path, "read", { cwd: baseCwd });
|
|
39070
39154
|
if (!safety.safe) {
|
|
@@ -39983,13 +40067,19 @@ function getNextCronRun(expression, fromTime, timeZone) {
|
|
|
39983
40067
|
|
|
39984
40068
|
// packages/core/src/scheduler/store.ts
|
|
39985
40069
|
var DEFAULT_LOCK_TTL_MS = 10 * 60 * 1000;
|
|
40070
|
+
var SAFE_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
39986
40071
|
function schedulesDir(cwd2) {
|
|
39987
40072
|
return join6(getProjectConfigDir(cwd2), "schedules");
|
|
39988
40073
|
}
|
|
39989
40074
|
function locksDir(cwd2) {
|
|
39990
40075
|
return join6(schedulesDir(cwd2), "locks");
|
|
39991
40076
|
}
|
|
40077
|
+
function isSafeId(id) {
|
|
40078
|
+
return SAFE_ID_PATTERN.test(id);
|
|
40079
|
+
}
|
|
39992
40080
|
function schedulePath(cwd2, id) {
|
|
40081
|
+
if (!isSafeId(id))
|
|
40082
|
+
return null;
|
|
39993
40083
|
return join6(schedulesDir(cwd2), `${id}.json`);
|
|
39994
40084
|
}
|
|
39995
40085
|
function lockPath(cwd2, id) {
|
|
@@ -40022,11 +40112,17 @@ async function listSchedules(cwd2) {
|
|
|
40022
40112
|
async function saveSchedule(cwd2, schedule) {
|
|
40023
40113
|
await ensureDirs(cwd2);
|
|
40024
40114
|
const path = schedulePath(cwd2, schedule.id);
|
|
40115
|
+
if (!path) {
|
|
40116
|
+
throw new Error(`Invalid schedule id: ${schedule.id}`);
|
|
40117
|
+
}
|
|
40025
40118
|
await writeFile(path, JSON.stringify(schedule, null, 2), "utf-8");
|
|
40026
40119
|
}
|
|
40027
40120
|
async function deleteSchedule(cwd2, id) {
|
|
40028
40121
|
try {
|
|
40029
|
-
|
|
40122
|
+
const path = schedulePath(cwd2, id);
|
|
40123
|
+
if (!path)
|
|
40124
|
+
return false;
|
|
40125
|
+
await unlink(path);
|
|
40030
40126
|
return true;
|
|
40031
40127
|
} catch {
|
|
40032
40128
|
return false;
|
|
@@ -40064,7 +40160,10 @@ async function getDueSchedules(cwd2, nowTime) {
|
|
|
40064
40160
|
}
|
|
40065
40161
|
async function updateSchedule(cwd2, id, updater) {
|
|
40066
40162
|
try {
|
|
40067
|
-
const
|
|
40163
|
+
const path = schedulePath(cwd2, id);
|
|
40164
|
+
if (!path)
|
|
40165
|
+
return null;
|
|
40166
|
+
const raw = await readFile(path, "utf-8");
|
|
40068
40167
|
const schedule = JSON.parse(raw);
|
|
40069
40168
|
const updated = updater(schedule);
|
|
40070
40169
|
await saveSchedule(cwd2, updated);
|
|
@@ -40074,6 +40173,8 @@ async function updateSchedule(cwd2, id, updater) {
|
|
|
40074
40173
|
}
|
|
40075
40174
|
}
|
|
40076
40175
|
async function acquireScheduleLock(cwd2, id, ownerId, ttlMs = DEFAULT_LOCK_TTL_MS, allowRetry = true) {
|
|
40176
|
+
if (!isSafeId(id))
|
|
40177
|
+
return false;
|
|
40077
40178
|
await ensureDirs(cwd2);
|
|
40078
40179
|
const path = lockPath(cwd2, id);
|
|
40079
40180
|
const now2 = Date.now();
|
|
@@ -40106,6 +40207,8 @@ async function acquireScheduleLock(cwd2, id, ownerId, ttlMs = DEFAULT_LOCK_TTL_M
|
|
|
40106
40207
|
return false;
|
|
40107
40208
|
}
|
|
40108
40209
|
async function releaseScheduleLock(cwd2, id, ownerId) {
|
|
40210
|
+
if (!isSafeId(id))
|
|
40211
|
+
return;
|
|
40109
40212
|
const path = lockPath(cwd2, id);
|
|
40110
40213
|
try {
|
|
40111
40214
|
const raw = await readFile(path, "utf-8");
|
|
@@ -40116,6 +40219,8 @@ async function releaseScheduleLock(cwd2, id, ownerId) {
|
|
|
40116
40219
|
} catch {}
|
|
40117
40220
|
}
|
|
40118
40221
|
async function refreshScheduleLock(cwd2, id, ownerId) {
|
|
40222
|
+
if (!isSafeId(id))
|
|
40223
|
+
return;
|
|
40119
40224
|
const path = lockPath(cwd2, id);
|
|
40120
40225
|
try {
|
|
40121
40226
|
const raw = await readFile(path, "utf-8");
|
|
@@ -40128,7 +40233,10 @@ async function refreshScheduleLock(cwd2, id, ownerId) {
|
|
|
40128
40233
|
}
|
|
40129
40234
|
async function readSchedule(cwd2, id) {
|
|
40130
40235
|
try {
|
|
40131
|
-
const
|
|
40236
|
+
const path = schedulePath(cwd2, id);
|
|
40237
|
+
if (!path)
|
|
40238
|
+
return null;
|
|
40239
|
+
const raw = await readFile(path, "utf-8");
|
|
40132
40240
|
const schedule = JSON.parse(raw);
|
|
40133
40241
|
if (!schedule?.id)
|
|
40134
40242
|
return null;
|
|
@@ -40344,7 +40452,7 @@ init_src();
|
|
|
40344
40452
|
import { existsSync as existsSync4, writeFileSync as writeFileSync3, unlinkSync } from "fs";
|
|
40345
40453
|
import { tmpdir } from "os";
|
|
40346
40454
|
import { join as join7 } from "path";
|
|
40347
|
-
import { homedir as
|
|
40455
|
+
import { homedir as homedir6 } from "os";
|
|
40348
40456
|
async function getViuPath() {
|
|
40349
40457
|
const explicitPath = process.env.ASSISTANTS_VIU_PATH || process.env.VIU_PATH;
|
|
40350
40458
|
if (explicitPath) {
|
|
@@ -40356,7 +40464,7 @@ async function getViuPath() {
|
|
|
40356
40464
|
} catch {}
|
|
40357
40465
|
}
|
|
40358
40466
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
40359
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
40467
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir6();
|
|
40360
40468
|
const locations = [
|
|
40361
40469
|
"viu",
|
|
40362
40470
|
join7(homeDir, ".cargo", "bin", "viu"),
|
|
@@ -40505,14 +40613,14 @@ Respond with ALLOW or DENY on the first line, followed by a short reason.`,
|
|
|
40505
40613
|
// packages/core/src/skills/loader.ts
|
|
40506
40614
|
init_src();
|
|
40507
40615
|
import { join as join8, basename, dirname as dirname4 } from "path";
|
|
40508
|
-
import { homedir as
|
|
40616
|
+
import { homedir as homedir7 } from "os";
|
|
40509
40617
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
40510
40618
|
|
|
40511
40619
|
class SkillLoader {
|
|
40512
40620
|
skills = new Map;
|
|
40513
40621
|
async loadAll(projectDir = process.cwd()) {
|
|
40514
40622
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
40515
|
-
const userHome = envHome && envHome.trim().length > 0 ? envHome :
|
|
40623
|
+
const userHome = envHome && envHome.trim().length > 0 ? envHome : homedir7();
|
|
40516
40624
|
const userSkillsDir = join8(userHome, ".assistants", "shared", "skills");
|
|
40517
40625
|
await this.loadFromDirectory(userSkillsDir);
|
|
40518
40626
|
const projectSkillsDir = join8(projectDir, ".assistants", "skills");
|
|
@@ -40728,6 +40836,7 @@ class HookLoader {
|
|
|
40728
40836
|
}
|
|
40729
40837
|
// packages/core/src/hooks/executor.ts
|
|
40730
40838
|
init_src();
|
|
40839
|
+
import { existsSync as existsSync5 } from "fs";
|
|
40731
40840
|
function killSpawnedProcess(proc) {
|
|
40732
40841
|
proc.kill();
|
|
40733
40842
|
}
|
|
@@ -40813,8 +40922,9 @@ class HookExecutor {
|
|
|
40813
40922
|
if (!hook.command)
|
|
40814
40923
|
return null;
|
|
40815
40924
|
try {
|
|
40925
|
+
const cwd2 = input.cwd && existsSync5(input.cwd) ? input.cwd : process.cwd();
|
|
40816
40926
|
const proc = Bun.spawn(["bash", "-c", hook.command], {
|
|
40817
|
-
cwd:
|
|
40927
|
+
cwd: cwd2,
|
|
40818
40928
|
stdin: "pipe",
|
|
40819
40929
|
stdout: "pipe",
|
|
40820
40930
|
stderr: "pipe"
|
|
@@ -41191,7 +41301,7 @@ init_src();
|
|
|
41191
41301
|
// packages/core/src/sessions/verification.ts
|
|
41192
41302
|
init_src();
|
|
41193
41303
|
import { join as join9 } from "path";
|
|
41194
|
-
import { existsSync as
|
|
41304
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4, readdirSync as readdirSync2 } from "fs";
|
|
41195
41305
|
|
|
41196
41306
|
class VerificationSessionStore {
|
|
41197
41307
|
basePath;
|
|
@@ -41202,7 +41312,7 @@ class VerificationSessionStore {
|
|
|
41202
41312
|
this.ensureDirectory();
|
|
41203
41313
|
}
|
|
41204
41314
|
ensureDirectory() {
|
|
41205
|
-
if (!
|
|
41315
|
+
if (!existsSync6(this.basePath)) {
|
|
41206
41316
|
mkdirSync3(this.basePath, { recursive: true });
|
|
41207
41317
|
}
|
|
41208
41318
|
}
|
|
@@ -41228,7 +41338,7 @@ class VerificationSessionStore {
|
|
|
41228
41338
|
}
|
|
41229
41339
|
get(id) {
|
|
41230
41340
|
const filePath = join9(this.basePath, `${id}.json`);
|
|
41231
|
-
if (!
|
|
41341
|
+
if (!existsSync6(filePath)) {
|
|
41232
41342
|
return null;
|
|
41233
41343
|
}
|
|
41234
41344
|
try {
|
|
@@ -41276,7 +41386,7 @@ class VerificationSessionStore {
|
|
|
41276
41386
|
this.save(session);
|
|
41277
41387
|
}
|
|
41278
41388
|
listFiles() {
|
|
41279
|
-
if (!
|
|
41389
|
+
if (!existsSync6(this.basePath)) {
|
|
41280
41390
|
return [];
|
|
41281
41391
|
}
|
|
41282
41392
|
return readdirSync2(this.basePath).filter((f) => f.endsWith(".json"));
|
|
@@ -41467,9 +41577,9 @@ function createScopeVerificationHook() {
|
|
|
41467
41577
|
};
|
|
41468
41578
|
}
|
|
41469
41579
|
// packages/core/src/commands/loader.ts
|
|
41470
|
-
import { existsSync as
|
|
41471
|
-
import { join as join10, basename as basename2, extname } from "path";
|
|
41472
|
-
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";
|
|
41473
41583
|
|
|
41474
41584
|
class CommandLoader {
|
|
41475
41585
|
commands = new Map;
|
|
@@ -41480,14 +41590,14 @@ class CommandLoader {
|
|
|
41480
41590
|
async loadAll() {
|
|
41481
41591
|
this.commands.clear();
|
|
41482
41592
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
41483
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
41593
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir8();
|
|
41484
41594
|
const globalDir = join10(homeDir, ".assistants", "commands");
|
|
41485
41595
|
await this.loadFromDirectory(globalDir, "global");
|
|
41486
41596
|
const projectDir = join10(this.cwd, ".assistants", "commands");
|
|
41487
41597
|
await this.loadFromDirectory(projectDir, "project");
|
|
41488
41598
|
}
|
|
41489
41599
|
async loadFromDirectory(dir, source, prefix = "") {
|
|
41490
|
-
if (!
|
|
41600
|
+
if (!existsSync7(dir))
|
|
41491
41601
|
return;
|
|
41492
41602
|
const entries = readdirSync3(dir);
|
|
41493
41603
|
for (const entry of entries) {
|
|
@@ -41496,7 +41606,7 @@ class CommandLoader {
|
|
|
41496
41606
|
if (stat.isDirectory()) {
|
|
41497
41607
|
const newPrefix = prefix ? `${prefix}:${entry}` : entry;
|
|
41498
41608
|
await this.loadFromDirectory(fullPath, source, newPrefix);
|
|
41499
|
-
} else if (stat.isFile() &&
|
|
41609
|
+
} else if (stat.isFile() && extname2(entry) === ".md") {
|
|
41500
41610
|
const command = await this.loadCommandFile(fullPath, prefix);
|
|
41501
41611
|
if (command) {
|
|
41502
41612
|
this.commands.set(command.name, command);
|
|
@@ -41527,15 +41637,14 @@ class CommandLoader {
|
|
|
41527
41637
|
}
|
|
41528
41638
|
}
|
|
41529
41639
|
parseFrontmatter(content) {
|
|
41530
|
-
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]*)$/;
|
|
41531
41641
|
const match = content.match(frontmatterRegex);
|
|
41532
41642
|
if (!match) {
|
|
41533
41643
|
return { frontmatter: {}, body: content };
|
|
41534
41644
|
}
|
|
41535
41645
|
const [, yamlContent, body] = match;
|
|
41536
41646
|
const frontmatter = {};
|
|
41537
|
-
const lines = yamlContent.split(
|
|
41538
|
-
`);
|
|
41647
|
+
const lines = yamlContent.split(/\r?\n/);
|
|
41539
41648
|
let currentListKey = null;
|
|
41540
41649
|
for (const rawLine of lines) {
|
|
41541
41650
|
const line = rawLine.trimEnd();
|
|
@@ -41667,10 +41776,16 @@ Use /help to see available commands.
|
|
|
41667
41776
|
}
|
|
41668
41777
|
if (!inCodeBlock && trimmed.startsWith("!")) {
|
|
41669
41778
|
const command = trimmed.slice(1).trim();
|
|
41779
|
+
if (!command) {
|
|
41780
|
+
processedLines.push(line);
|
|
41781
|
+
continue;
|
|
41782
|
+
}
|
|
41670
41783
|
const output = await this.executeShell(command, cwd2);
|
|
41671
|
-
|
|
41672
|
-
|
|
41673
|
-
\`\`\``
|
|
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
|
+
`));
|
|
41674
41789
|
} else {
|
|
41675
41790
|
processedLines.push(line);
|
|
41676
41791
|
}
|
|
@@ -41723,18 +41838,24 @@ ${stderr}`;
|
|
|
41723
41838
|
}
|
|
41724
41839
|
// packages/core/src/commands/builtin.ts
|
|
41725
41840
|
import { join as join13 } from "path";
|
|
41726
|
-
import { homedir as
|
|
41727
|
-
import { existsSync as
|
|
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";
|
|
41728
41843
|
init_src();
|
|
41729
41844
|
|
|
41730
41845
|
// packages/core/src/projects/store.ts
|
|
41731
41846
|
init_src();
|
|
41732
41847
|
import { join as join11 } from "path";
|
|
41733
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_-]+$/;
|
|
41734
41850
|
function projectsDir(cwd2) {
|
|
41735
41851
|
return join11(cwd2, ".assistants", "projects");
|
|
41736
41852
|
}
|
|
41853
|
+
function isSafeId2(id) {
|
|
41854
|
+
return SAFE_ID_PATTERN2.test(id);
|
|
41855
|
+
}
|
|
41737
41856
|
function projectPath(cwd2, id) {
|
|
41857
|
+
if (!isSafeId2(id))
|
|
41858
|
+
return null;
|
|
41738
41859
|
return join11(projectsDir(cwd2), `${id}.json`);
|
|
41739
41860
|
}
|
|
41740
41861
|
async function ensureProjectsDir(cwd2) {
|
|
@@ -41766,7 +41887,10 @@ async function listProjects(cwd2) {
|
|
|
41766
41887
|
}
|
|
41767
41888
|
async function readProject(cwd2, id) {
|
|
41768
41889
|
try {
|
|
41769
|
-
const
|
|
41890
|
+
const path = projectPath(cwd2, id);
|
|
41891
|
+
if (!path)
|
|
41892
|
+
return null;
|
|
41893
|
+
const raw = await readFile2(path, "utf-8");
|
|
41770
41894
|
const project = JSON.parse(raw);
|
|
41771
41895
|
if (!project?.id || !project?.name)
|
|
41772
41896
|
return null;
|
|
@@ -41782,11 +41906,18 @@ async function findProjectByName(cwd2, name) {
|
|
|
41782
41906
|
}
|
|
41783
41907
|
async function saveProject(cwd2, project) {
|
|
41784
41908
|
await ensureProjectsDir(cwd2);
|
|
41785
|
-
|
|
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");
|
|
41786
41914
|
}
|
|
41787
41915
|
async function deleteProject(cwd2, id) {
|
|
41788
41916
|
try {
|
|
41789
|
-
|
|
41917
|
+
const path = projectPath(cwd2, id);
|
|
41918
|
+
if (!path)
|
|
41919
|
+
return false;
|
|
41920
|
+
await unlink2(path);
|
|
41790
41921
|
return true;
|
|
41791
41922
|
} catch {
|
|
41792
41923
|
return false;
|
|
@@ -41827,7 +41958,7 @@ function hasProjectNameConflict(projects, name) {
|
|
|
41827
41958
|
|
|
41828
41959
|
// packages/core/src/projects/context.ts
|
|
41829
41960
|
import { readFile as readFile3 } from "fs/promises";
|
|
41830
|
-
import { homedir as
|
|
41961
|
+
import { homedir as homedir9 } from "os";
|
|
41831
41962
|
import { resolve as resolve4, join as join12 } from "path";
|
|
41832
41963
|
var DEFAULT_MAX_FILE_BYTES = 12000;
|
|
41833
41964
|
function singleLine(value) {
|
|
@@ -41847,7 +41978,7 @@ function normalizeEntryLabel(entry) {
|
|
|
41847
41978
|
}
|
|
41848
41979
|
async function renderFileEntry(entry, options) {
|
|
41849
41980
|
const rawPath = entry.value.trim();
|
|
41850
|
-
const expandedPath = rawPath === "~" ?
|
|
41981
|
+
const expandedPath = rawPath === "~" ? homedir9() : rawPath.startsWith("~/") ? join12(homedir9(), rawPath.slice(2)) : rawPath;
|
|
41851
41982
|
const resolved = resolve4(options.cwd, expandedPath);
|
|
41852
41983
|
const validation = await validatePath(resolved, { allowedPaths: [options.cwd] });
|
|
41853
41984
|
if (!validation.valid) {
|
|
@@ -43679,12 +43810,12 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43679
43810
|
message += `**Config File Locations:**
|
|
43680
43811
|
`;
|
|
43681
43812
|
for (const path of configPaths) {
|
|
43682
|
-
const exists =
|
|
43813
|
+
const exists = existsSync8(path);
|
|
43683
43814
|
message += ` ${exists ? "\u2713" : "\u25CB"} ${path}
|
|
43684
43815
|
`;
|
|
43685
43816
|
}
|
|
43686
43817
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
43687
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
43818
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir10();
|
|
43688
43819
|
message += `
|
|
43689
43820
|
**Commands Directories:**
|
|
43690
43821
|
`;
|
|
@@ -43723,7 +43854,7 @@ Please summarize the last interaction and suggest 2-3 next steps.
|
|
|
43723
43854
|
- Ask a follow-up question if needed
|
|
43724
43855
|
`;
|
|
43725
43856
|
const examplePath = join13(commandsDir, "reflect.md");
|
|
43726
|
-
if (!
|
|
43857
|
+
if (!existsSync8(examplePath)) {
|
|
43727
43858
|
writeFileSync5(examplePath, exampleCommand);
|
|
43728
43859
|
}
|
|
43729
43860
|
let message = `
|
|
@@ -44652,18 +44783,18 @@ class RecoveryManager {
|
|
|
44652
44783
|
}
|
|
44653
44784
|
// packages/core/src/energy/types.ts
|
|
44654
44785
|
var DEFAULT_ENERGY_COSTS = {
|
|
44655
|
-
message:
|
|
44656
|
-
toolCall:
|
|
44657
|
-
llmCall:
|
|
44658
|
-
longContext:
|
|
44786
|
+
message: 200,
|
|
44787
|
+
toolCall: 500,
|
|
44788
|
+
llmCall: 300,
|
|
44789
|
+
longContext: 1000
|
|
44659
44790
|
};
|
|
44660
44791
|
var DEFAULT_ENERGY_CONFIG = {
|
|
44661
44792
|
enabled: true,
|
|
44662
44793
|
costs: DEFAULT_ENERGY_COSTS,
|
|
44663
|
-
regenRate:
|
|
44664
|
-
lowEnergyThreshold:
|
|
44665
|
-
criticalThreshold:
|
|
44666
|
-
maxEnergy:
|
|
44794
|
+
regenRate: 500,
|
|
44795
|
+
lowEnergyThreshold: 3000,
|
|
44796
|
+
criticalThreshold: 1000,
|
|
44797
|
+
maxEnergy: 1e4
|
|
44667
44798
|
};
|
|
44668
44799
|
function buildEnergyConfig(config) {
|
|
44669
44800
|
return {
|
|
@@ -44887,15 +45018,15 @@ function validateToolCalls(toolCalls, tools) {
|
|
|
44887
45018
|
}
|
|
44888
45019
|
|
|
44889
45020
|
// packages/core/src/voice/utils.ts
|
|
44890
|
-
import { existsSync as
|
|
44891
|
-
import { homedir as
|
|
45021
|
+
import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
|
|
45022
|
+
import { homedir as homedir12 } from "os";
|
|
44892
45023
|
import { join as join15 } from "path";
|
|
44893
45024
|
import { spawnSync } from "child_process";
|
|
44894
45025
|
function loadApiKeyFromSecrets2(key) {
|
|
44895
45026
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
44896
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
45027
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir12();
|
|
44897
45028
|
const secretsPath = join15(homeDir, ".secrets");
|
|
44898
|
-
if (!
|
|
45029
|
+
if (!existsSync10(secretsPath))
|
|
44899
45030
|
return;
|
|
44900
45031
|
try {
|
|
44901
45032
|
const content = readFileSync5(secretsPath, "utf-8");
|
|
@@ -45399,13 +45530,13 @@ class VoiceManager {
|
|
|
45399
45530
|
}
|
|
45400
45531
|
// packages/core/src/identity/assistant-manager.ts
|
|
45401
45532
|
init_src();
|
|
45402
|
-
import { existsSync as
|
|
45533
|
+
import { existsSync as existsSync12 } from "fs";
|
|
45403
45534
|
import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile7, rm as rm2 } from "fs/promises";
|
|
45404
45535
|
import { join as join20 } from "path";
|
|
45405
45536
|
|
|
45406
45537
|
// packages/core/src/identity/identity-manager.ts
|
|
45407
45538
|
init_src();
|
|
45408
|
-
import { existsSync as
|
|
45539
|
+
import { existsSync as existsSync11 } from "fs";
|
|
45409
45540
|
import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile6, rm } from "fs/promises";
|
|
45410
45541
|
import { join as join19 } from "path";
|
|
45411
45542
|
var DEFAULT_PROFILE = {
|
|
@@ -45555,7 +45686,7 @@ class IdentityManager {
|
|
|
45555
45686
|
`);
|
|
45556
45687
|
}
|
|
45557
45688
|
async readIndex() {
|
|
45558
|
-
if (!
|
|
45689
|
+
if (!existsSync11(this.indexPath)) {
|
|
45559
45690
|
return { identities: [] };
|
|
45560
45691
|
}
|
|
45561
45692
|
try {
|
|
@@ -45580,7 +45711,7 @@ class IdentityManager {
|
|
|
45580
45711
|
}
|
|
45581
45712
|
async readIdentity(id) {
|
|
45582
45713
|
const path2 = this.identityPath(id);
|
|
45583
|
-
if (!
|
|
45714
|
+
if (!existsSync11(path2))
|
|
45584
45715
|
return null;
|
|
45585
45716
|
try {
|
|
45586
45717
|
const raw = await readFile7(path2, "utf-8");
|
|
@@ -45594,7 +45725,7 @@ class IdentityManager {
|
|
|
45594
45725
|
await writeFile6(this.identityPath(identity.id), JSON.stringify(identity, null, 2));
|
|
45595
45726
|
}
|
|
45596
45727
|
async readActive() {
|
|
45597
|
-
if (!
|
|
45728
|
+
if (!existsSync11(this.activePath))
|
|
45598
45729
|
return null;
|
|
45599
45730
|
try {
|
|
45600
45731
|
const raw = await readFile7(this.activePath, "utf-8");
|
|
@@ -45609,7 +45740,7 @@ class IdentityManager {
|
|
|
45609
45740
|
await writeFile6(this.activePath, JSON.stringify({ id }, null, 2));
|
|
45610
45741
|
}
|
|
45611
45742
|
async loadAssistant() {
|
|
45612
|
-
if (!
|
|
45743
|
+
if (!existsSync11(this.assistantConfigPath()))
|
|
45613
45744
|
return null;
|
|
45614
45745
|
try {
|
|
45615
45746
|
const raw = await readFile7(this.assistantConfigPath(), "utf-8");
|
|
@@ -45727,7 +45858,7 @@ class AssistantManager {
|
|
|
45727
45858
|
return new IdentityManager(assistantId, this.basePath);
|
|
45728
45859
|
}
|
|
45729
45860
|
async readIndex() {
|
|
45730
|
-
if (!
|
|
45861
|
+
if (!existsSync12(this.indexPath)) {
|
|
45731
45862
|
return { assistants: [] };
|
|
45732
45863
|
}
|
|
45733
45864
|
try {
|
|
@@ -45752,7 +45883,7 @@ class AssistantManager {
|
|
|
45752
45883
|
}
|
|
45753
45884
|
async readAssistant(id) {
|
|
45754
45885
|
const configPath = this.assistantConfigPath(id);
|
|
45755
|
-
if (!
|
|
45886
|
+
if (!existsSync12(configPath))
|
|
45756
45887
|
return null;
|
|
45757
45888
|
try {
|
|
45758
45889
|
const raw = await readFile8(configPath, "utf-8");
|
|
@@ -45767,7 +45898,7 @@ class AssistantManager {
|
|
|
45767
45898
|
await writeFile7(this.assistantConfigPath(assistant.id), JSON.stringify(assistant, null, 2));
|
|
45768
45899
|
}
|
|
45769
45900
|
async readActive() {
|
|
45770
|
-
if (!
|
|
45901
|
+
if (!existsSync12(this.activePath))
|
|
45771
45902
|
return null;
|
|
45772
45903
|
try {
|
|
45773
45904
|
const raw = await readFile8(this.activePath, "utf-8");
|
|
@@ -46222,7 +46353,7 @@ class AgentLoop {
|
|
|
46222
46353
|
if (toolInput.cwd === undefined) {
|
|
46223
46354
|
toolInput.cwd = this.cwd;
|
|
46224
46355
|
}
|
|
46225
|
-
if (toolInput.sessionId ===
|
|
46356
|
+
if (typeof toolInput.sessionId !== "string" || toolInput.sessionId.length === 0) {
|
|
46226
46357
|
toolInput.sessionId = this.sessionId;
|
|
46227
46358
|
}
|
|
46228
46359
|
toolCall.input = toolInput;
|
|
@@ -46258,7 +46389,7 @@ class AgentLoop {
|
|
|
46258
46389
|
if (input.cwd === undefined) {
|
|
46259
46390
|
input.cwd = this.cwd;
|
|
46260
46391
|
}
|
|
46261
|
-
if (input.sessionId ===
|
|
46392
|
+
if (typeof input.sessionId !== "string" || input.sessionId.length === 0) {
|
|
46262
46393
|
input.sessionId = this.sessionId;
|
|
46263
46394
|
}
|
|
46264
46395
|
if (preHookResult?.continue === false || preHookResult?.permissionDecision === "deny") {
|
|
@@ -46995,7 +47126,7 @@ init_anthropic();
|
|
|
46995
47126
|
init_src();
|
|
46996
47127
|
|
|
46997
47128
|
// packages/core/src/logger.ts
|
|
46998
|
-
import { existsSync as
|
|
47129
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, appendFileSync, readdirSync as readdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
46999
47130
|
import { join as join22 } from "path";
|
|
47000
47131
|
class Logger {
|
|
47001
47132
|
logDir;
|
|
@@ -47009,7 +47140,7 @@ class Logger {
|
|
|
47009
47140
|
this.logFile = join22(this.logDir, `${date}.log`);
|
|
47010
47141
|
}
|
|
47011
47142
|
ensureDir(dir) {
|
|
47012
|
-
if (!
|
|
47143
|
+
if (!existsSync13(dir)) {
|
|
47013
47144
|
mkdirSync8(dir, { recursive: true });
|
|
47014
47145
|
}
|
|
47015
47146
|
}
|
|
@@ -47055,7 +47186,7 @@ class SessionStorage {
|
|
|
47055
47186
|
this.sessionFile = join22(this.sessionsDir, `${sessionId}.json`);
|
|
47056
47187
|
}
|
|
47057
47188
|
ensureDir(dir) {
|
|
47058
|
-
if (!
|
|
47189
|
+
if (!existsSync13(dir)) {
|
|
47059
47190
|
mkdirSync8(dir, { recursive: true });
|
|
47060
47191
|
}
|
|
47061
47192
|
}
|
|
@@ -47069,7 +47200,7 @@ class SessionStorage {
|
|
|
47069
47200
|
}
|
|
47070
47201
|
load() {
|
|
47071
47202
|
try {
|
|
47072
|
-
if (!
|
|
47203
|
+
if (!existsSync13(this.sessionFile))
|
|
47073
47204
|
return null;
|
|
47074
47205
|
return JSON.parse(readFileSync8(this.sessionFile, "utf-8"));
|
|
47075
47206
|
} catch {
|
|
@@ -47079,7 +47210,7 @@ class SessionStorage {
|
|
|
47079
47210
|
static getActiveAssistantId() {
|
|
47080
47211
|
try {
|
|
47081
47212
|
const activePath = join22(getConfigDir(), "active.json");
|
|
47082
|
-
if (!
|
|
47213
|
+
if (!existsSync13(activePath))
|
|
47083
47214
|
return null;
|
|
47084
47215
|
const raw = readFileSync8(activePath, "utf-8");
|
|
47085
47216
|
const data = JSON.parse(raw);
|
|
@@ -47093,7 +47224,7 @@ class SessionStorage {
|
|
|
47093
47224
|
const resolvedId = assistantId ?? SessionStorage.getActiveAssistantId();
|
|
47094
47225
|
if (resolvedId) {
|
|
47095
47226
|
const assistantDir = join22(root, "assistants", resolvedId, "sessions");
|
|
47096
|
-
if (
|
|
47227
|
+
if (existsSync13(assistantDir)) {
|
|
47097
47228
|
return assistantDir;
|
|
47098
47229
|
}
|
|
47099
47230
|
}
|
|
@@ -47101,7 +47232,7 @@ class SessionStorage {
|
|
|
47101
47232
|
}
|
|
47102
47233
|
static listSessions(assistantId) {
|
|
47103
47234
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
47104
|
-
if (!
|
|
47235
|
+
if (!existsSync13(sessionsDir))
|
|
47105
47236
|
return [];
|
|
47106
47237
|
const sessions = [];
|
|
47107
47238
|
const files = readdirSync4(sessionsDir);
|
|
@@ -47131,7 +47262,7 @@ class SessionStorage {
|
|
|
47131
47262
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
47132
47263
|
const sessionFile = join22(sessionsDir, `${sessionId}.json`);
|
|
47133
47264
|
try {
|
|
47134
|
-
if (!
|
|
47265
|
+
if (!existsSync13(sessionFile))
|
|
47135
47266
|
return null;
|
|
47136
47267
|
return JSON.parse(readFileSync8(sessionFile, "utf-8"));
|
|
47137
47268
|
} catch {
|
|
@@ -47154,7 +47285,7 @@ function initAssistantsDir() {
|
|
|
47154
47285
|
join22(baseDir, "migration")
|
|
47155
47286
|
];
|
|
47156
47287
|
for (const dir of dirs) {
|
|
47157
|
-
if (!
|
|
47288
|
+
if (!existsSync13(dir)) {
|
|
47158
47289
|
mkdirSync8(dir, { recursive: true });
|
|
47159
47290
|
}
|
|
47160
47291
|
}
|
|
@@ -47978,14 +48109,19 @@ function parseMarkdown(text, options) {
|
|
|
47978
48109
|
codeBlocks.push(match);
|
|
47979
48110
|
return `@@CODEBLOCK${codeBlocks.length - 1}@@`;
|
|
47980
48111
|
});
|
|
48112
|
+
const inlineCodeBlocks = [];
|
|
48113
|
+
result = result.replace(/`([^`\n]+)`/g, (_, code) => {
|
|
48114
|
+
inlineCodeBlocks.push(code);
|
|
48115
|
+
return `@@INLINECODE${inlineCodeBlocks.length - 1}@@`;
|
|
48116
|
+
});
|
|
47981
48117
|
const blockSections = [];
|
|
47982
48118
|
if (!options?.skipBlocks) {
|
|
47983
48119
|
result = extractBlockSections(result, blockSections);
|
|
47984
48120
|
}
|
|
47985
|
-
result = result.replace(
|
|
47986
|
-
result = result.replace(/__(
|
|
47987
|
-
result = result.replace(
|
|
47988
|
-
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)}`);
|
|
47989
48125
|
result = result.replace(/`([^`]+)`/g, (_, code) => source_default.dim(code));
|
|
47990
48126
|
result = result.replace(/^### (.+)$/gm, (_, text2) => source_default.bold(text2));
|
|
47991
48127
|
result = result.replace(/^## (.+)$/gm, (_, text2) => source_default.bold(text2));
|
|
@@ -48008,6 +48144,10 @@ function parseMarkdown(text, options) {
|
|
|
48008
48144
|
const code = block.replace(/```\w*\n?/g, "").replace(/```$/g, "").trim();
|
|
48009
48145
|
return source_default.dim(code);
|
|
48010
48146
|
});
|
|
48147
|
+
result = result.replace(/@@INLINECODE(\d+)@@/g, (_, index) => {
|
|
48148
|
+
const code = inlineCodeBlocks[parseInt(index, 10)] ?? "";
|
|
48149
|
+
return source_default.dim(code);
|
|
48150
|
+
});
|
|
48011
48151
|
return result.trimEnd();
|
|
48012
48152
|
}
|
|
48013
48153
|
var ALLOWED_BLOCK_TYPES = new Set(["info", "success", "warning", "error", "note", "command"]);
|
|
@@ -48243,7 +48383,7 @@ function renderBlockSection(section, maxWidth) {
|
|
|
48243
48383
|
if (section.kind === "grid") {
|
|
48244
48384
|
const adjustedWidth2 = maxWidth ? Math.max(20, maxWidth - section.indent.length) : undefined;
|
|
48245
48385
|
if (section.cards.length === 0) {
|
|
48246
|
-
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(`
|
|
48247
48387
|
`);
|
|
48248
48388
|
}
|
|
48249
48389
|
return renderCardGrid(section.cards, section.columns, adjustedWidth2, section.indent);
|
|
@@ -48375,7 +48515,15 @@ function formatMarkdownTables(text, maxWidth) {
|
|
|
48375
48515
|
const lines = text.split(`
|
|
48376
48516
|
`);
|
|
48377
48517
|
const output = [];
|
|
48378
|
-
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
|
+
};
|
|
48379
48527
|
const hasPipes = (line) => line.includes("|");
|
|
48380
48528
|
let i = 0;
|
|
48381
48529
|
while (i < lines.length) {
|
|
@@ -48402,7 +48550,31 @@ function formatMarkdownTables(text, maxWidth) {
|
|
|
48402
48550
|
function parseTableRow(line) {
|
|
48403
48551
|
const trimmed = line.trim();
|
|
48404
48552
|
const withoutEdges = trimmed.replace(/^\|/, "").replace(/\|$/, "");
|
|
48405
|
-
|
|
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());
|
|
48406
48578
|
}
|
|
48407
48579
|
function renderTable(header, rows, maxWidth) {
|
|
48408
48580
|
const colCount = Math.max(header.length, ...rows.map((r) => r.length));
|
|
@@ -48616,11 +48788,17 @@ function wrapAnsiLine(line, width) {
|
|
|
48616
48788
|
const result = [];
|
|
48617
48789
|
let current = "";
|
|
48618
48790
|
let visible = 0;
|
|
48791
|
+
let activeAnsi = "";
|
|
48619
48792
|
let i = 0;
|
|
48620
48793
|
while (i < line.length) {
|
|
48621
48794
|
const match = line.slice(i).match(/^\x1b\[[0-9;]*m/);
|
|
48622
48795
|
if (match) {
|
|
48623
48796
|
current += match[0];
|
|
48797
|
+
if (match[0] === "\x1B[0m") {
|
|
48798
|
+
activeAnsi = "";
|
|
48799
|
+
} else {
|
|
48800
|
+
activeAnsi += match[0];
|
|
48801
|
+
}
|
|
48624
48802
|
i += match[0].length;
|
|
48625
48803
|
continue;
|
|
48626
48804
|
}
|
|
@@ -48629,7 +48807,7 @@ function wrapAnsiLine(line, width) {
|
|
|
48629
48807
|
i += 1;
|
|
48630
48808
|
if (visible >= width) {
|
|
48631
48809
|
result.push(current);
|
|
48632
|
-
current =
|
|
48810
|
+
current = activeAnsi;
|
|
48633
48811
|
visible = 0;
|
|
48634
48812
|
}
|
|
48635
48813
|
}
|
|
@@ -48640,6 +48818,7 @@ function wrapAnsiLine(line, width) {
|
|
|
48640
48818
|
function truncateAnsi(line, width) {
|
|
48641
48819
|
if (stripAnsi2(line).length <= width)
|
|
48642
48820
|
return line;
|
|
48821
|
+
const hasAnsi = /\x1b\[[0-9;]*m/.test(line);
|
|
48643
48822
|
if (width <= 3) {
|
|
48644
48823
|
let result = "";
|
|
48645
48824
|
let visible2 = 0;
|
|
@@ -48655,7 +48834,7 @@ function truncateAnsi(line, width) {
|
|
|
48655
48834
|
visible2 += 1;
|
|
48656
48835
|
i2 += 1;
|
|
48657
48836
|
}
|
|
48658
|
-
return result;
|
|
48837
|
+
return hasAnsi && !result.endsWith("\x1B[0m") ? result + "\x1B[0m" : result;
|
|
48659
48838
|
}
|
|
48660
48839
|
const suffix = "...";
|
|
48661
48840
|
const target = Math.max(0, width - suffix.length);
|
|
@@ -48673,7 +48852,8 @@ function truncateAnsi(line, width) {
|
|
|
48673
48852
|
visible += 1;
|
|
48674
48853
|
i += 1;
|
|
48675
48854
|
}
|
|
48676
|
-
|
|
48855
|
+
const truncated = current + suffix;
|
|
48856
|
+
return hasAnsi && !truncated.endsWith("\x1B[0m") ? truncated + "\x1B[0m" : truncated;
|
|
48677
48857
|
}
|
|
48678
48858
|
|
|
48679
48859
|
// packages/terminal/src/components/toolDisplay.ts
|
|
@@ -48866,7 +49046,7 @@ function estimateMessageLines(message, maxWidth) {
|
|
|
48866
49046
|
const hasContent = contentLines.length > 0;
|
|
48867
49047
|
const prefixWidth = message.role === "user" || message.role === "assistant" ? 2 : 0;
|
|
48868
49048
|
const effectiveWidth = maxWidth ? Math.max(1, maxWidth - prefixWidth) : maxWidth;
|
|
48869
|
-
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;
|
|
48870
49050
|
let lines = hasContent ? Math.max(1, wrappedLines) : 0;
|
|
48871
49051
|
if (message.role === "assistant" && message.toolCalls?.length) {
|
|
48872
49052
|
lines += estimateToolPanelLines(message.toolCalls, message.toolResults, hasContent);
|
|
@@ -48878,6 +49058,27 @@ function estimateMessageLines(message, maxWidth) {
|
|
|
48878
49058
|
}
|
|
48879
49059
|
return lines;
|
|
48880
49060
|
}
|
|
49061
|
+
function estimateGroupedToolMessagesLines(messages, maxWidth) {
|
|
49062
|
+
const toolCalls = [];
|
|
49063
|
+
const toolResults = [];
|
|
49064
|
+
for (const msg of messages) {
|
|
49065
|
+
if (msg.toolCalls)
|
|
49066
|
+
toolCalls.push(...msg.toolCalls);
|
|
49067
|
+
if (msg.toolResults)
|
|
49068
|
+
toolResults.push(...msg.toolResults);
|
|
49069
|
+
}
|
|
49070
|
+
if (toolCalls.length === 0)
|
|
49071
|
+
return 0;
|
|
49072
|
+
const synthetic = {
|
|
49073
|
+
id: "grouped-tool-call",
|
|
49074
|
+
role: "assistant",
|
|
49075
|
+
content: "",
|
|
49076
|
+
timestamp: 0,
|
|
49077
|
+
toolCalls,
|
|
49078
|
+
toolResults: toolResults.length > 0 ? toolResults : undefined
|
|
49079
|
+
};
|
|
49080
|
+
return estimateMessageLines(synthetic, maxWidth);
|
|
49081
|
+
}
|
|
48881
49082
|
function countWrappedLines(lines, maxWidth) {
|
|
48882
49083
|
if (!maxWidth || maxWidth <= 0) {
|
|
48883
49084
|
return lines.length;
|
|
@@ -48927,6 +49128,34 @@ function isContinuationChunk(id) {
|
|
|
48927
49128
|
const idx = Number(match[1]);
|
|
48928
49129
|
return Number.isFinite(idx) && idx > 0;
|
|
48929
49130
|
}
|
|
49131
|
+
function groupConsecutiveToolMessages(messages) {
|
|
49132
|
+
const groups = [];
|
|
49133
|
+
let currentToolGroup = [];
|
|
49134
|
+
for (const msg of messages) {
|
|
49135
|
+
const isToolOnlyAssistant = msg.role === "assistant" && (!msg.content || !msg.content.trim()) && msg.toolCalls && msg.toolCalls.length > 0;
|
|
49136
|
+
if (isToolOnlyAssistant) {
|
|
49137
|
+
currentToolGroup.push(msg);
|
|
49138
|
+
} else {
|
|
49139
|
+
if (currentToolGroup.length > 0) {
|
|
49140
|
+
if (currentToolGroup.length === 1) {
|
|
49141
|
+
groups.push({ type: "single", message: currentToolGroup[0] });
|
|
49142
|
+
} else {
|
|
49143
|
+
groups.push({ type: "grouped", messages: currentToolGroup });
|
|
49144
|
+
}
|
|
49145
|
+
currentToolGroup = [];
|
|
49146
|
+
}
|
|
49147
|
+
groups.push({ type: "single", message: msg });
|
|
49148
|
+
}
|
|
49149
|
+
}
|
|
49150
|
+
if (currentToolGroup.length > 0) {
|
|
49151
|
+
if (currentToolGroup.length === 1) {
|
|
49152
|
+
groups.push({ type: "single", message: currentToolGroup[0] });
|
|
49153
|
+
} else {
|
|
49154
|
+
groups.push({ type: "grouped", messages: currentToolGroup });
|
|
49155
|
+
}
|
|
49156
|
+
}
|
|
49157
|
+
return groups;
|
|
49158
|
+
}
|
|
48930
49159
|
|
|
48931
49160
|
// packages/terminal/src/components/Messages.tsx
|
|
48932
49161
|
var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -48946,11 +49175,13 @@ function Messages3({
|
|
|
48946
49175
|
const columns = stdout?.columns ?? 80;
|
|
48947
49176
|
const messageWidth = Math.max(1, columns - 2);
|
|
48948
49177
|
const wrapWidth = messageWidth;
|
|
49178
|
+
const messageGroups = import_react24.useMemo(() => groupConsecutiveToolMessages(messages), [messages]);
|
|
49179
|
+
const messageItems = import_react24.useMemo(() => {
|
|
49180
|
+
return messageGroups.map((group) => group.type === "single" ? { kind: "message", message: group.message } : { kind: "grouped", messages: group.messages });
|
|
49181
|
+
}, [messageGroups]);
|
|
48949
49182
|
const items = import_react24.useMemo(() => {
|
|
48950
49183
|
const output = [];
|
|
48951
|
-
|
|
48952
|
-
output.push({ kind: "message", message });
|
|
48953
|
-
}
|
|
49184
|
+
output.push(...messageItems);
|
|
48954
49185
|
for (const entry of activityLog) {
|
|
48955
49186
|
output.push({ kind: "activity", entry });
|
|
48956
49187
|
}
|
|
@@ -48962,7 +49193,7 @@ function Messages3({
|
|
|
48962
49193
|
const lineSpans = import_react24.useMemo(() => {
|
|
48963
49194
|
let cursor = 0;
|
|
48964
49195
|
return items.map((item, index) => {
|
|
48965
|
-
const lines = item.kind === "activity" ? estimateActivityEntryLines(item.entry, wrapWidth, messageWidth) : estimateMessageLines(item.message, messageWidth);
|
|
49196
|
+
const lines = item.kind === "activity" ? estimateActivityEntryLines(item.entry, wrapWidth, messageWidth) : item.kind === "grouped" ? estimateGroupedToolMessagesLines(item.messages, messageWidth) : estimateMessageLines(item.message, messageWidth);
|
|
48966
49197
|
const start = cursor;
|
|
48967
49198
|
cursor += lines;
|
|
48968
49199
|
return { item, index, start, end: cursor, lines };
|
|
@@ -48972,16 +49203,15 @@ function Messages3({
|
|
|
48972
49203
|
const endLine = Math.max(0, totalLines - scrollOffsetLines);
|
|
48973
49204
|
const startLine = Math.max(0, endLine - maxVisibleLines);
|
|
48974
49205
|
const visibleSpans = lineSpans.filter((span) => span.end > startLine && span.start < endLine);
|
|
48975
|
-
const
|
|
49206
|
+
const visibleMessageItems = visibleSpans.filter((span) => span.item.kind === "message" || span.item.kind === "grouped").map((span) => span.item);
|
|
48976
49207
|
const visibleActivity = visibleSpans.filter((span) => span.item.kind === "activity").map((span) => span.item.entry);
|
|
48977
49208
|
const visibleStreaming = visibleSpans.filter((span) => span.item.kind === "streaming").map((span) => span.item.message);
|
|
48978
49209
|
const showCurrentResponse = Boolean(currentResponse) && streamingMessages.length === 0;
|
|
48979
|
-
const
|
|
48980
|
-
|
|
48981
|
-
|
|
48982
|
-
return { id: group.message.id, group };
|
|
49210
|
+
const historicalItems = visibleMessageItems.map((item) => {
|
|
49211
|
+
if (item.kind === "message") {
|
|
49212
|
+
return { id: item.message.id, item };
|
|
48983
49213
|
}
|
|
48984
|
-
return { id:
|
|
49214
|
+
return { id: item.messages[0].id, item };
|
|
48985
49215
|
});
|
|
48986
49216
|
const toolResultMap = import_react24.useMemo(() => {
|
|
48987
49217
|
const map = new Map;
|
|
@@ -49015,14 +49245,14 @@ function Messages3({
|
|
|
49015
49245
|
width: "100%",
|
|
49016
49246
|
children: [
|
|
49017
49247
|
historicalItems.map((item) => {
|
|
49018
|
-
if (item.
|
|
49248
|
+
if (item.item.kind === "message") {
|
|
49019
49249
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MessageBubble, {
|
|
49020
|
-
message: item.
|
|
49250
|
+
message: item.item.message,
|
|
49021
49251
|
queuedMessageIds
|
|
49022
49252
|
}, item.id, false, undefined, this);
|
|
49023
49253
|
}
|
|
49024
49254
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(CombinedToolMessage, {
|
|
49025
|
-
messages: item.
|
|
49255
|
+
messages: item.item.messages
|
|
49026
49256
|
}, item.id, false, undefined, this);
|
|
49027
49257
|
}),
|
|
49028
49258
|
visibleActivity.map((entry) => {
|
|
@@ -49127,34 +49357,6 @@ function formatDuration(ms) {
|
|
|
49127
49357
|
const secs = totalSeconds % 60;
|
|
49128
49358
|
return `${mins}m ${secs}s`;
|
|
49129
49359
|
}
|
|
49130
|
-
function groupConsecutiveToolMessages(messages) {
|
|
49131
|
-
const groups = [];
|
|
49132
|
-
let currentToolGroup = [];
|
|
49133
|
-
for (const msg of messages) {
|
|
49134
|
-
const isToolOnlyAssistant = msg.role === "assistant" && (!msg.content || !msg.content.trim()) && msg.toolCalls && msg.toolCalls.length > 0;
|
|
49135
|
-
if (isToolOnlyAssistant) {
|
|
49136
|
-
currentToolGroup.push(msg);
|
|
49137
|
-
} else {
|
|
49138
|
-
if (currentToolGroup.length > 0) {
|
|
49139
|
-
if (currentToolGroup.length === 1) {
|
|
49140
|
-
groups.push({ type: "single", message: currentToolGroup[0] });
|
|
49141
|
-
} else {
|
|
49142
|
-
groups.push({ type: "grouped", messages: currentToolGroup });
|
|
49143
|
-
}
|
|
49144
|
-
currentToolGroup = [];
|
|
49145
|
-
}
|
|
49146
|
-
groups.push({ type: "single", message: msg });
|
|
49147
|
-
}
|
|
49148
|
-
}
|
|
49149
|
-
if (currentToolGroup.length > 0) {
|
|
49150
|
-
if (currentToolGroup.length === 1) {
|
|
49151
|
-
groups.push({ type: "single", message: currentToolGroup[0] });
|
|
49152
|
-
} else {
|
|
49153
|
-
groups.push({ type: "grouped", messages: currentToolGroup });
|
|
49154
|
-
}
|
|
49155
|
-
}
|
|
49156
|
-
return groups;
|
|
49157
|
-
}
|
|
49158
49360
|
function CombinedToolMessage({ messages }) {
|
|
49159
49361
|
const allToolCalls = [];
|
|
49160
49362
|
const allToolResults = [];
|
|
@@ -49166,9 +49368,12 @@ function CombinedToolMessage({ messages }) {
|
|
|
49166
49368
|
allToolResults.push(...msg.toolResults);
|
|
49167
49369
|
}
|
|
49168
49370
|
}
|
|
49169
|
-
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(
|
|
49170
|
-
|
|
49171
|
-
|
|
49371
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
49372
|
+
marginY: 1,
|
|
49373
|
+
children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(ToolCallPanel, {
|
|
49374
|
+
toolCalls: allToolCalls,
|
|
49375
|
+
toolResults: allToolResults
|
|
49376
|
+
}, undefined, false, undefined, this)
|
|
49172
49377
|
}, undefined, false, undefined, this);
|
|
49173
49378
|
}
|
|
49174
49379
|
function MessageBubble({ message, queuedMessageIds }) {
|
|
@@ -49317,7 +49522,7 @@ function ToolCallPanel({
|
|
|
49317
49522
|
const statusColor = result ? result.isError ? "red" : "green" : "yellow";
|
|
49318
49523
|
const displayName = getToolDisplayName(toolCall);
|
|
49319
49524
|
const context2 = getToolContext(toolCall);
|
|
49320
|
-
const maxLine = Math.max(
|
|
49525
|
+
const maxLine = Math.max(1, innerWidth - 2);
|
|
49321
49526
|
const summaryLine = truncate(formatToolCall(toolCall), maxLine);
|
|
49322
49527
|
const resultText = result ? indentMultiline(truncateToolResult(result, 4, 400), " ") : "";
|
|
49323
49528
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
@@ -49493,8 +49698,9 @@ function formatScheduleCall(input) {
|
|
|
49493
49698
|
return "Listing scheduled tasks";
|
|
49494
49699
|
case "create":
|
|
49495
49700
|
const cmd = truncate(String(input.command || ""), 30);
|
|
49496
|
-
const
|
|
49497
|
-
|
|
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}`;
|
|
49498
49704
|
case "update":
|
|
49499
49705
|
return `Updating schedule: ${input.id || "unknown"}`;
|
|
49500
49706
|
case "delete":
|
|
@@ -49991,6 +50197,16 @@ function wrapTextLines(text, wrapChars) {
|
|
|
49991
50197
|
function stripAnsi6(text) {
|
|
49992
50198
|
return text.replace(/\x1B\[[0-9;]*m/g, "");
|
|
49993
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
|
+
}
|
|
49994
50210
|
function chunkRenderedLines(lines, chunkLines) {
|
|
49995
50211
|
const chunks = [];
|
|
49996
50212
|
let current = [];
|
|
@@ -50046,18 +50262,21 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
50046
50262
|
const renderedLines = rendered.split(`
|
|
50047
50263
|
`);
|
|
50048
50264
|
if (renderedLines.length <= chunkLines) {
|
|
50049
|
-
|
|
50265
|
+
const lineCount = countWrappedLines2(renderedLines, assistantWidth);
|
|
50266
|
+
display.push({ ...msg, content: rendered, __rendered: true, __lineCount: lineCount });
|
|
50050
50267
|
continue;
|
|
50051
50268
|
}
|
|
50052
50269
|
const chunks2 = chunkRenderedLines(renderedLines, chunkLines);
|
|
50053
50270
|
for (let i = 0;i < chunks2.length; i++) {
|
|
50054
50271
|
const chunkContent = chunks2[i].join(`
|
|
50055
50272
|
`);
|
|
50273
|
+
const lineCount = countWrappedLines2(chunks2[i], assistantWidth);
|
|
50056
50274
|
display.push({
|
|
50057
50275
|
...msg,
|
|
50058
50276
|
id: `${msg.id}::chunk-${i}`,
|
|
50059
50277
|
content: chunkContent,
|
|
50060
50278
|
__rendered: true,
|
|
50279
|
+
__lineCount: lineCount,
|
|
50061
50280
|
toolCalls: i === chunks2.length - 1 ? msg.toolCalls : undefined,
|
|
50062
50281
|
toolResults: i === chunks2.length - 1 ? msg.toolResults : undefined
|
|
50063
50282
|
});
|
|
@@ -50067,7 +50286,7 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
50067
50286
|
const effectiveWrap = msg.role === "user" ? Math.max(1, wrapChars - 2) : wrapChars;
|
|
50068
50287
|
const lines = wrapTextLines(content, effectiveWrap);
|
|
50069
50288
|
if (lines.length <= chunkLines) {
|
|
50070
|
-
display.push(msg);
|
|
50289
|
+
display.push({ ...msg, __lineCount: lines.length });
|
|
50071
50290
|
continue;
|
|
50072
50291
|
}
|
|
50073
50292
|
const chunks = chunkRenderedLines(lines, chunkLines);
|
|
@@ -50078,6 +50297,7 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
50078
50297
|
...msg,
|
|
50079
50298
|
id: `${msg.id}::chunk-${i}`,
|
|
50080
50299
|
content: chunkContent,
|
|
50300
|
+
__lineCount: chunks[i].length,
|
|
50081
50301
|
toolCalls: i === chunks.length - 1 ? msg.toolCalls : undefined,
|
|
50082
50302
|
toolResults: i === chunks.length - 1 ? msg.toolResults : undefined
|
|
50083
50303
|
});
|
|
@@ -50113,6 +50333,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50113
50333
|
const [scrollOffset, setScrollOffset] = import_react29.useState(0);
|
|
50114
50334
|
const [autoScroll, setAutoScroll] = import_react29.useState(true);
|
|
50115
50335
|
const [skills, setSkills] = import_react29.useState([]);
|
|
50336
|
+
const [commands, setCommands] = import_react29.useState([]);
|
|
50116
50337
|
const responseRef = import_react29.useRef("");
|
|
50117
50338
|
const toolCallsRef = import_react29.useRef([]);
|
|
50118
50339
|
const toolResultsRef = import_react29.useRef([]);
|
|
@@ -50141,6 +50362,25 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50141
50362
|
return parts.join(`
|
|
50142
50363
|
`).trim();
|
|
50143
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
|
+
}, []);
|
|
50144
50384
|
const finalizeResponse = import_react29.useCallback((status) => {
|
|
50145
50385
|
const baseContent = buildFullResponse();
|
|
50146
50386
|
const hasContent = baseContent.length > 0;
|
|
@@ -50409,12 +50649,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50409
50649
|
});
|
|
50410
50650
|
const session = await registry.createSession(cwd2);
|
|
50411
50651
|
setActiveSessionId(session.id);
|
|
50412
|
-
|
|
50413
|
-
setSkills(loadedSkills.map((s) => ({
|
|
50414
|
-
name: s.name,
|
|
50415
|
-
description: s.description || "",
|
|
50416
|
-
argumentHint: s.argumentHint
|
|
50417
|
-
})));
|
|
50652
|
+
await loadSessionMetadata(session);
|
|
50418
50653
|
setEnergyState(session.client.getEnergyState() ?? undefined);
|
|
50419
50654
|
setVoiceState(session.client.getVoiceState() ?? undefined);
|
|
50420
50655
|
setIdentityInfo(session.client.getIdentityInfo() ?? undefined);
|
|
@@ -50428,7 +50663,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50428
50663
|
return () => {
|
|
50429
50664
|
registry.closeAll();
|
|
50430
50665
|
};
|
|
50431
|
-
}, [cwd2, registry, handleChunk, finalizeResponse, resetTurnState]);
|
|
50666
|
+
}, [cwd2, registry, handleChunk, finalizeResponse, resetTurnState, loadSessionMetadata]);
|
|
50432
50667
|
const processQueue = import_react29.useCallback(async () => {
|
|
50433
50668
|
const activeSession2 = registryRef.current.getActiveSession();
|
|
50434
50669
|
if (!activeSession2 || !activeSessionId)
|
|
@@ -50498,6 +50733,8 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50498
50733
|
}, [activityLog, renderWidth, wrapChars]);
|
|
50499
50734
|
const reservedLines = import_react29.useMemo(() => {
|
|
50500
50735
|
let lines = 0;
|
|
50736
|
+
const wrapWidth = Math.max(1, (columns ?? 80) - 2);
|
|
50737
|
+
lines += 2;
|
|
50501
50738
|
if (showWelcome) {
|
|
50502
50739
|
lines += 4;
|
|
50503
50740
|
}
|
|
@@ -50512,16 +50749,23 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50512
50749
|
const hasMore = activeQueue.length + inlineCount > MAX_QUEUED_PREVIEW;
|
|
50513
50750
|
lines += 2;
|
|
50514
50751
|
lines += 1;
|
|
50515
|
-
|
|
50752
|
+
const previewWidth = Math.max(1, wrapWidth - 2);
|
|
50753
|
+
const previewItems = [...activeInline, ...activeQueue].slice(0, MAX_QUEUED_PREVIEW);
|
|
50754
|
+
const previewLines = previewItems.reduce((sum, queued) => {
|
|
50755
|
+
const label = queued.mode === "inline" ? "\u21B3" : "\u23F3";
|
|
50756
|
+
const text = `${label} ${truncateQueued(queued.content)}`;
|
|
50757
|
+
return sum + countWrappedLines2([text], previewWidth);
|
|
50758
|
+
}, 0);
|
|
50759
|
+
lines += Math.max(previewCount, previewLines);
|
|
50516
50760
|
if (hasMore)
|
|
50517
50761
|
lines += 1;
|
|
50518
50762
|
}
|
|
50519
50763
|
if (error2) {
|
|
50520
50764
|
const parsed = parseErrorMessage(error2);
|
|
50521
|
-
const messageLines = parsed.message ? parsed.message.split(`
|
|
50522
|
-
`)
|
|
50523
|
-
const suggestionLines = parsed.suggestion ? parsed.suggestion.split(`
|
|
50524
|
-
`)
|
|
50765
|
+
const messageLines = parsed.message ? countWrappedLines2(parsed.message.split(`
|
|
50766
|
+
`), wrapWidth) : 1;
|
|
50767
|
+
const suggestionLines = parsed.suggestion ? countWrappedLines2(parsed.suggestion.split(`
|
|
50768
|
+
`), wrapWidth) : 0;
|
|
50525
50769
|
lines += 2;
|
|
50526
50770
|
lines += Math.max(1, messageLines) + suggestionLines;
|
|
50527
50771
|
}
|
|
@@ -50529,9 +50773,9 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50529
50773
|
lines += 3;
|
|
50530
50774
|
}
|
|
50531
50775
|
lines += 1;
|
|
50532
|
-
lines +=
|
|
50776
|
+
lines += 3;
|
|
50533
50777
|
if (isProcessing) {
|
|
50534
|
-
lines +=
|
|
50778
|
+
lines += 1;
|
|
50535
50779
|
}
|
|
50536
50780
|
lines += 2;
|
|
50537
50781
|
return lines;
|
|
@@ -50542,7 +50786,8 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50542
50786
|
scrollOffset,
|
|
50543
50787
|
error2,
|
|
50544
50788
|
isProcessing,
|
|
50545
|
-
showWelcome
|
|
50789
|
+
showWelcome,
|
|
50790
|
+
columns
|
|
50546
50791
|
]);
|
|
50547
50792
|
const displayMessages = import_react29.useMemo(() => buildDisplayMessages(messages, MESSAGE_CHUNK_LINES, wrapChars, { maxWidth: renderWidth }), [messages, wrapChars, renderWidth]);
|
|
50548
50793
|
const streamingMessages = import_react29.useMemo(() => {
|
|
@@ -50557,8 +50802,15 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50557
50802
|
return buildDisplayMessages([streamingMessage], MESSAGE_CHUNK_LINES, wrapChars, { maxWidth: renderWidth });
|
|
50558
50803
|
}, [currentResponse, isProcessing, wrapChars, renderWidth]);
|
|
50559
50804
|
const displayLineCount = import_react29.useMemo(() => {
|
|
50560
|
-
const
|
|
50561
|
-
|
|
50805
|
+
const grouped = groupConsecutiveToolMessages(displayMessages);
|
|
50806
|
+
const groupedLines = grouped.reduce((sum, group) => {
|
|
50807
|
+
if (group.type === "single") {
|
|
50808
|
+
return sum + estimateMessageLines(group.message, renderWidth);
|
|
50809
|
+
}
|
|
50810
|
+
return sum + estimateGroupedToolMessagesLines(group.messages, renderWidth);
|
|
50811
|
+
}, 0);
|
|
50812
|
+
const streamingLines = streamingMessages.reduce((sum, msg) => sum + estimateMessageLines(msg, renderWidth), 0);
|
|
50813
|
+
return groupedLines + streamingLines;
|
|
50562
50814
|
}, [displayMessages, streamingMessages, renderWidth]);
|
|
50563
50815
|
const totalLineCount = displayLineCount + activityLogLineCount;
|
|
50564
50816
|
import_react29.useEffect(() => {
|
|
@@ -50598,6 +50850,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50598
50850
|
setEnergyState(session.client.getEnergyState() ?? undefined);
|
|
50599
50851
|
setVoiceState(session.client.getVoiceState() ?? undefined);
|
|
50600
50852
|
setIdentityInfo(session.client.getIdentityInfo() ?? undefined);
|
|
50853
|
+
await loadSessionMetadata(session);
|
|
50601
50854
|
}
|
|
50602
50855
|
await registry.switchSession(sessionId);
|
|
50603
50856
|
setActiveSessionId(sessionId);
|
|
@@ -50615,6 +50868,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50615
50868
|
setEnergyState(newSession.client.getEnergyState() ?? undefined);
|
|
50616
50869
|
setVoiceState(newSession.client.getVoiceState() ?? undefined);
|
|
50617
50870
|
setIdentityInfo(newSession.client.getIdentityInfo() ?? undefined);
|
|
50871
|
+
await loadSessionMetadata(newSession);
|
|
50618
50872
|
} catch (err) {
|
|
50619
50873
|
setError(err instanceof Error ? err.message : "Failed to create session");
|
|
50620
50874
|
}
|
|
@@ -50945,6 +51199,7 @@ function App2({ cwd: cwd2, version }) {
|
|
|
50945
51199
|
onSubmit: handleSubmit,
|
|
50946
51200
|
isProcessing,
|
|
50947
51201
|
queueLength: activeQueue.length + inlineCount,
|
|
51202
|
+
commands,
|
|
50948
51203
|
skills
|
|
50949
51204
|
}, undefined, false, undefined, this),
|
|
50950
51205
|
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Status, {
|
|
@@ -51140,7 +51395,7 @@ function formatStreamEvent(chunk) {
|
|
|
51140
51395
|
|
|
51141
51396
|
// packages/terminal/src/index.tsx
|
|
51142
51397
|
var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
51143
|
-
var VERSION3 = "0.6.
|
|
51398
|
+
var VERSION3 = "0.6.36";
|
|
51144
51399
|
process.env.ASSISTANTS_VERSION ??= VERSION3;
|
|
51145
51400
|
function parseArgs(argv) {
|
|
51146
51401
|
const args = argv.slice(2);
|
|
@@ -51296,4 +51551,4 @@ if (options.print !== null) {
|
|
|
51296
51551
|
});
|
|
51297
51552
|
}
|
|
51298
51553
|
|
|
51299
|
-
//# debugId=
|
|
51554
|
+
//# debugId=D20D9C4F4FE5D66664756E2164756E21
|