@hasna/assistants 0.6.31 → 0.6.34
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 +299 -123
- package/dist/index.js.map +21 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28328,12 +28328,12 @@ __export(exports_anthropic, {
|
|
|
28328
28328
|
AnthropicClient: () => AnthropicClient
|
|
28329
28329
|
});
|
|
28330
28330
|
import { readFileSync as readFileSync4, existsSync as existsSync8 } from "fs";
|
|
28331
|
-
import { homedir as
|
|
28332
|
-
import { join as
|
|
28331
|
+
import { homedir as homedir9 } from "os";
|
|
28332
|
+
import { join as join14 } from "path";
|
|
28333
28333
|
function loadApiKeyFromSecrets() {
|
|
28334
28334
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
28335
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
28336
|
-
const secretsPath =
|
|
28335
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir9();
|
|
28336
|
+
const secretsPath = join14(homeDir, ".secrets");
|
|
28337
28337
|
if (existsSync8(secretsPath)) {
|
|
28338
28338
|
try {
|
|
28339
28339
|
const content = readFileSync4(secretsPath, "utf-8");
|
|
@@ -36578,7 +36578,7 @@ var import_react29 = __toESM(require_react(), 1);
|
|
|
36578
36578
|
|
|
36579
36579
|
// packages/core/src/agent/loop.ts
|
|
36580
36580
|
init_src();
|
|
36581
|
-
import { join as
|
|
36581
|
+
import { join as join21 } from "path";
|
|
36582
36582
|
|
|
36583
36583
|
// packages/core/src/agent/context.ts
|
|
36584
36584
|
init_src();
|
|
@@ -36645,9 +36645,14 @@ class AgentContext {
|
|
|
36645
36645
|
return message;
|
|
36646
36646
|
}
|
|
36647
36647
|
extractPdfAttachment(content) {
|
|
36648
|
+
if (!content)
|
|
36649
|
+
return null;
|
|
36648
36650
|
try {
|
|
36649
36651
|
const parsed = JSON.parse(content);
|
|
36650
36652
|
if (parsed && parsed.__pdf_attachment__ === true) {
|
|
36653
|
+
if (!parsed.data || typeof parsed.data !== "string") {
|
|
36654
|
+
return null;
|
|
36655
|
+
}
|
|
36651
36656
|
return {
|
|
36652
36657
|
type: "pdf",
|
|
36653
36658
|
source: {
|
|
@@ -36682,7 +36687,8 @@ class AgentContext {
|
|
|
36682
36687
|
this.messages = this.messages.filter((msg) => {
|
|
36683
36688
|
if (msg.role !== "system")
|
|
36684
36689
|
return true;
|
|
36685
|
-
|
|
36690
|
+
const content = msg.content ?? "";
|
|
36691
|
+
return !predicate(content);
|
|
36686
36692
|
});
|
|
36687
36693
|
}
|
|
36688
36694
|
getMessages() {
|
|
@@ -36698,15 +36704,18 @@ class AgentContext {
|
|
|
36698
36704
|
if (this.messages.length <= this.maxMessages) {
|
|
36699
36705
|
return;
|
|
36700
36706
|
}
|
|
36701
|
-
|
|
36707
|
+
let systemMessages = this.messages.filter((m) => m.role === "system");
|
|
36702
36708
|
const nonSystemMessages = this.messages.filter((m) => m.role !== "system");
|
|
36703
|
-
|
|
36704
|
-
|
|
36709
|
+
if (systemMessages.length > this.maxMessages) {
|
|
36710
|
+
systemMessages = systemMessages.slice(-this.maxMessages);
|
|
36711
|
+
}
|
|
36712
|
+
const targetCount = Math.max(0, this.maxMessages - systemMessages.length);
|
|
36713
|
+
let recentMessages = targetCount > 0 ? nonSystemMessages.slice(-targetCount) : [];
|
|
36705
36714
|
while (recentMessages.length > 0 && recentMessages[0].toolResults) {
|
|
36706
36715
|
const firstIndex = nonSystemMessages.indexOf(recentMessages[0]);
|
|
36707
36716
|
if (firstIndex > 0) {
|
|
36708
36717
|
recentMessages = nonSystemMessages.slice(firstIndex - 1);
|
|
36709
|
-
if (recentMessages.length > targetCount + 1) {
|
|
36718
|
+
if (recentMessages.length > targetCount + 1 && targetCount > 0) {
|
|
36710
36719
|
recentMessages = recentMessages.slice(-(targetCount + 1));
|
|
36711
36720
|
}
|
|
36712
36721
|
} else {
|
|
@@ -36868,7 +36877,33 @@ class ContextManager {
|
|
|
36868
36877
|
summarizedCount: 0
|
|
36869
36878
|
};
|
|
36870
36879
|
}
|
|
36871
|
-
|
|
36880
|
+
let summary = "";
|
|
36881
|
+
try {
|
|
36882
|
+
summary = await this.summarizer.summarize(toSummarize);
|
|
36883
|
+
} catch {
|
|
36884
|
+
const tokens = this.tokenCounter.countMessages(messages);
|
|
36885
|
+
this.state.totalTokens = tokens;
|
|
36886
|
+
this.state.messageCount = messages.length;
|
|
36887
|
+
return {
|
|
36888
|
+
messages,
|
|
36889
|
+
summarized: false,
|
|
36890
|
+
tokensBefore: tokens,
|
|
36891
|
+
tokensAfter: tokens,
|
|
36892
|
+
summarizedCount: 0
|
|
36893
|
+
};
|
|
36894
|
+
}
|
|
36895
|
+
if (!summary.trim()) {
|
|
36896
|
+
const tokens = this.tokenCounter.countMessages(messages);
|
|
36897
|
+
this.state.totalTokens = tokens;
|
|
36898
|
+
this.state.messageCount = messages.length;
|
|
36899
|
+
return {
|
|
36900
|
+
messages,
|
|
36901
|
+
summarized: false,
|
|
36902
|
+
tokensBefore: tokens,
|
|
36903
|
+
tokensAfter: tokens,
|
|
36904
|
+
summarizedCount: 0
|
|
36905
|
+
};
|
|
36906
|
+
}
|
|
36872
36907
|
const summaryMessage = {
|
|
36873
36908
|
id: generateId(),
|
|
36874
36909
|
role: "system",
|
|
@@ -36903,7 +36938,8 @@ ${summary}`,
|
|
|
36903
36938
|
};
|
|
36904
36939
|
}
|
|
36905
36940
|
isSummaryMessage(message) {
|
|
36906
|
-
|
|
36941
|
+
const content = message.content ?? "";
|
|
36942
|
+
return message.role === "system" && content.trim().startsWith(SUMMARY_TAG);
|
|
36907
36943
|
}
|
|
36908
36944
|
partitionMessages(messages) {
|
|
36909
36945
|
const keepRecent = Math.max(0, this.config.keepRecentMessages);
|
|
@@ -37047,7 +37083,8 @@ class HybridSummarizer {
|
|
|
37047
37083
|
const paths = new Set;
|
|
37048
37084
|
const pathRegex = /(?:\.?\/|[A-Za-z]:\\)[\w\-.\/\\]+\.[A-Za-z0-9]+/g;
|
|
37049
37085
|
for (const msg of messages) {
|
|
37050
|
-
const
|
|
37086
|
+
const content = msg.content ?? "";
|
|
37087
|
+
const matches = content.match(pathRegex);
|
|
37051
37088
|
if (matches) {
|
|
37052
37089
|
for (const match of matches) {
|
|
37053
37090
|
paths.add(match.replace(/\\/g, "/"));
|
|
@@ -37059,7 +37096,8 @@ class HybridSummarizer {
|
|
|
37059
37096
|
extractCommands(messages) {
|
|
37060
37097
|
const commands = new Set;
|
|
37061
37098
|
for (const msg of messages) {
|
|
37062
|
-
const
|
|
37099
|
+
const content = msg.content ?? "";
|
|
37100
|
+
const lines = content.split(`
|
|
37063
37101
|
`);
|
|
37064
37102
|
for (const line of lines) {
|
|
37065
37103
|
const trimmed = line.trim();
|
|
@@ -37084,7 +37122,8 @@ class HybridSummarizer {
|
|
|
37084
37122
|
extractErrors(messages) {
|
|
37085
37123
|
const errors = new Set;
|
|
37086
37124
|
for (const msg of messages) {
|
|
37087
|
-
const
|
|
37125
|
+
const content = msg.content ?? "";
|
|
37126
|
+
const lines = content.split(`
|
|
37088
37127
|
`);
|
|
37089
37128
|
for (const line of lines) {
|
|
37090
37129
|
if (/error|failed|exception/i.test(line)) {
|
|
@@ -38516,12 +38555,10 @@ async function isPathSafe(targetPath, operation, options = {}) {
|
|
|
38516
38555
|
for (const protectedPath of PROTECTED_PATHS) {
|
|
38517
38556
|
const expanded = protectedPath.replace("~", home);
|
|
38518
38557
|
if (resolved.startsWith(expanded)) {
|
|
38519
|
-
|
|
38520
|
-
|
|
38521
|
-
|
|
38522
|
-
|
|
38523
|
-
};
|
|
38524
|
-
}
|
|
38558
|
+
return {
|
|
38559
|
+
safe: false,
|
|
38560
|
+
reason: `Cannot ${operation} protected path: ${protectedPath}`
|
|
38561
|
+
};
|
|
38525
38562
|
}
|
|
38526
38563
|
}
|
|
38527
38564
|
try {
|
|
@@ -38596,9 +38633,21 @@ class FilesystemTools {
|
|
|
38596
38633
|
};
|
|
38597
38634
|
static readExecutor = async (input) => {
|
|
38598
38635
|
const baseCwd = input.cwd || process.cwd();
|
|
38599
|
-
const
|
|
38636
|
+
const rawPath = String(input.path || "").trim();
|
|
38637
|
+
if (!rawPath) {
|
|
38638
|
+
throw new ToolExecutionError("File path is required", {
|
|
38639
|
+
toolName: "read",
|
|
38640
|
+
toolInput: input,
|
|
38641
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38642
|
+
recoverable: false,
|
|
38643
|
+
retryable: false,
|
|
38644
|
+
suggestion: "Provide a valid file path."
|
|
38645
|
+
});
|
|
38646
|
+
}
|
|
38647
|
+
const path = resolve3(baseCwd, rawPath);
|
|
38600
38648
|
const offset = (input.offset || 1) - 1;
|
|
38601
|
-
const
|
|
38649
|
+
const limitRaw = input.limit;
|
|
38650
|
+
const limit = typeof limitRaw === "number" && limitRaw > 0 ? Math.floor(limitRaw) : undefined;
|
|
38602
38651
|
try {
|
|
38603
38652
|
const safety = await isPathSafe(path, "read", { cwd: baseCwd });
|
|
38604
38653
|
if (!safety.safe) {
|
|
@@ -38704,6 +38753,16 @@ class FilesystemTools {
|
|
|
38704
38753
|
const filename = input.filename || input.path;
|
|
38705
38754
|
const content = input.content;
|
|
38706
38755
|
const baseCwd = input.cwd || process.cwd();
|
|
38756
|
+
if (typeof content !== "string") {
|
|
38757
|
+
throw new ToolExecutionError("Content must be a string", {
|
|
38758
|
+
toolName: "write",
|
|
38759
|
+
toolInput: input,
|
|
38760
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38761
|
+
recoverable: false,
|
|
38762
|
+
retryable: false,
|
|
38763
|
+
suggestion: "Provide string content to write."
|
|
38764
|
+
});
|
|
38765
|
+
}
|
|
38707
38766
|
const scriptsFolder = getScriptsFolder(baseCwd, input.sessionId);
|
|
38708
38767
|
if (!filename || !filename.trim()) {
|
|
38709
38768
|
throw new ToolExecutionError("Filename is required", {
|
|
@@ -38798,13 +38857,55 @@ class FilesystemTools {
|
|
|
38798
38857
|
}
|
|
38799
38858
|
};
|
|
38800
38859
|
static globExecutor = async (input) => {
|
|
38801
|
-
const pattern = input.pattern;
|
|
38860
|
+
const pattern = String(input.pattern || "").trim();
|
|
38802
38861
|
const baseCwd = input.cwd || process.cwd();
|
|
38803
38862
|
const searchPath = resolve3(baseCwd, input.path || ".");
|
|
38804
38863
|
try {
|
|
38864
|
+
if (!pattern) {
|
|
38865
|
+
throw new ToolExecutionError("Pattern is required", {
|
|
38866
|
+
toolName: "glob",
|
|
38867
|
+
toolInput: input,
|
|
38868
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38869
|
+
recoverable: false,
|
|
38870
|
+
retryable: false
|
|
38871
|
+
});
|
|
38872
|
+
}
|
|
38873
|
+
const safety = await isPathSafe(searchPath, "read", { cwd: baseCwd });
|
|
38874
|
+
if (!safety.safe) {
|
|
38875
|
+
getSecurityLogger().log({
|
|
38876
|
+
eventType: "path_violation",
|
|
38877
|
+
severity: "high",
|
|
38878
|
+
details: {
|
|
38879
|
+
tool: "glob",
|
|
38880
|
+
path: searchPath,
|
|
38881
|
+
reason: safety.reason || "Blocked path"
|
|
38882
|
+
},
|
|
38883
|
+
sessionId: input.sessionId || "unknown"
|
|
38884
|
+
});
|
|
38885
|
+
throw new ToolExecutionError(safety.reason || "Blocked path", {
|
|
38886
|
+
toolName: "glob",
|
|
38887
|
+
toolInput: input,
|
|
38888
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
38889
|
+
recoverable: false,
|
|
38890
|
+
retryable: false
|
|
38891
|
+
});
|
|
38892
|
+
}
|
|
38893
|
+
const validated = await validatePath(searchPath, {
|
|
38894
|
+
allowSymlinks: true,
|
|
38895
|
+
allowedPaths: [baseCwd, searchPath]
|
|
38896
|
+
});
|
|
38897
|
+
if (!validated.valid) {
|
|
38898
|
+
throw new ToolExecutionError(validated.error || "Invalid path", {
|
|
38899
|
+
toolName: "glob",
|
|
38900
|
+
toolInput: input,
|
|
38901
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38902
|
+
recoverable: false,
|
|
38903
|
+
retryable: false
|
|
38904
|
+
});
|
|
38905
|
+
}
|
|
38805
38906
|
const glob = new Glob(pattern);
|
|
38806
38907
|
const matches = [];
|
|
38807
|
-
for await (const file of glob.scan({ cwd:
|
|
38908
|
+
for await (const file of glob.scan({ cwd: validated.resolved })) {
|
|
38808
38909
|
matches.push(file);
|
|
38809
38910
|
if (matches.length >= 1000)
|
|
38810
38911
|
break;
|
|
@@ -38857,18 +38958,60 @@ class FilesystemTools {
|
|
|
38857
38958
|
}
|
|
38858
38959
|
};
|
|
38859
38960
|
static grepExecutor = async (input) => {
|
|
38860
|
-
const pattern = input.pattern;
|
|
38961
|
+
const pattern = String(input.pattern || "").trim();
|
|
38861
38962
|
const baseCwd = input.cwd || process.cwd();
|
|
38862
38963
|
const searchPath = resolve3(baseCwd, input.path || ".");
|
|
38863
38964
|
const globPattern = input.glob || "**/*";
|
|
38864
38965
|
const caseSensitive = input.caseSensitive || false;
|
|
38865
38966
|
try {
|
|
38967
|
+
if (!pattern) {
|
|
38968
|
+
throw new ToolExecutionError("Pattern is required", {
|
|
38969
|
+
toolName: "grep",
|
|
38970
|
+
toolInput: input,
|
|
38971
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
38972
|
+
recoverable: false,
|
|
38973
|
+
retryable: false
|
|
38974
|
+
});
|
|
38975
|
+
}
|
|
38976
|
+
const safety = await isPathSafe(searchPath, "read", { cwd: baseCwd });
|
|
38977
|
+
if (!safety.safe) {
|
|
38978
|
+
getSecurityLogger().log({
|
|
38979
|
+
eventType: "path_violation",
|
|
38980
|
+
severity: "high",
|
|
38981
|
+
details: {
|
|
38982
|
+
tool: "grep",
|
|
38983
|
+
path: searchPath,
|
|
38984
|
+
reason: safety.reason || "Blocked path"
|
|
38985
|
+
},
|
|
38986
|
+
sessionId: input.sessionId || "unknown"
|
|
38987
|
+
});
|
|
38988
|
+
throw new ToolExecutionError(safety.reason || "Blocked path", {
|
|
38989
|
+
toolName: "grep",
|
|
38990
|
+
toolInput: input,
|
|
38991
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
38992
|
+
recoverable: false,
|
|
38993
|
+
retryable: false
|
|
38994
|
+
});
|
|
38995
|
+
}
|
|
38996
|
+
const validated = await validatePath(searchPath, {
|
|
38997
|
+
allowSymlinks: true,
|
|
38998
|
+
allowedPaths: [baseCwd, searchPath]
|
|
38999
|
+
});
|
|
39000
|
+
if (!validated.valid) {
|
|
39001
|
+
throw new ToolExecutionError(validated.error || "Invalid path", {
|
|
39002
|
+
toolName: "grep",
|
|
39003
|
+
toolInput: input,
|
|
39004
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
39005
|
+
recoverable: false,
|
|
39006
|
+
retryable: false
|
|
39007
|
+
});
|
|
39008
|
+
}
|
|
38866
39009
|
const flags = caseSensitive ? "" : "i";
|
|
38867
39010
|
const regex2 = new RegExp(pattern, flags);
|
|
38868
39011
|
const results = [];
|
|
38869
39012
|
const glob = new Glob(globPattern);
|
|
38870
|
-
for await (const file of glob.scan({ cwd:
|
|
38871
|
-
const filePath = join4(
|
|
39013
|
+
for await (const file of glob.scan({ cwd: validated.resolved })) {
|
|
39014
|
+
const filePath = join4(validated.resolved, file);
|
|
38872
39015
|
try {
|
|
38873
39016
|
const content = await Bun.file(filePath).text();
|
|
38874
39017
|
const lines = content.split(`
|
|
@@ -39895,7 +40038,10 @@ function computeNextRun(schedule, fromTime) {
|
|
|
39895
40038
|
if (schedule.schedule.kind === "once") {
|
|
39896
40039
|
if (!schedule.schedule.at)
|
|
39897
40040
|
return;
|
|
39898
|
-
|
|
40041
|
+
const next = parseScheduledTime(schedule.schedule.at, validTimezone);
|
|
40042
|
+
if (!next || next <= fromTime)
|
|
40043
|
+
return;
|
|
40044
|
+
return next;
|
|
39899
40045
|
}
|
|
39900
40046
|
if (schedule.schedule.kind === "cron") {
|
|
39901
40047
|
if (!schedule.schedule.cron)
|
|
@@ -39911,6 +40057,8 @@ async function getDueSchedules(cwd2, nowTime) {
|
|
|
39911
40057
|
return false;
|
|
39912
40058
|
if (!schedule.nextRunAt)
|
|
39913
40059
|
return false;
|
|
40060
|
+
if (!Number.isFinite(schedule.nextRunAt))
|
|
40061
|
+
return false;
|
|
39914
40062
|
return schedule.nextRunAt <= nowTime;
|
|
39915
40063
|
});
|
|
39916
40064
|
}
|
|
@@ -40026,6 +40174,9 @@ function parseDateTime(value) {
|
|
|
40026
40174
|
if (!Number.isFinite(year) || !Number.isFinite(month) || !Number.isFinite(day) || !Number.isFinite(hour) || !Number.isFinite(minute) || !Number.isFinite(second)) {
|
|
40027
40175
|
return null;
|
|
40028
40176
|
}
|
|
40177
|
+
if (month < 1 || month > 12 || day < 1 || day > 31 || hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) {
|
|
40178
|
+
return null;
|
|
40179
|
+
}
|
|
40029
40180
|
return { year, month, day, hour, minute, second };
|
|
40030
40181
|
}
|
|
40031
40182
|
function hasTimeZoneOffset(value) {
|
|
@@ -40164,11 +40315,21 @@ class SchedulerTool {
|
|
|
40164
40315
|
const id = String(input.id || "").trim();
|
|
40165
40316
|
if (!id)
|
|
40166
40317
|
return "Error: id is required.";
|
|
40318
|
+
let nextRunAt;
|
|
40319
|
+
if (action === "resume") {
|
|
40320
|
+
const schedule = await readSchedule(cwd2, id);
|
|
40321
|
+
if (!schedule)
|
|
40322
|
+
return `Schedule ${id} not found.`;
|
|
40323
|
+
nextRunAt = computeNextRun(schedule, Date.now());
|
|
40324
|
+
if (!nextRunAt) {
|
|
40325
|
+
return `Error: unable to compute next run for schedule ${id}.`;
|
|
40326
|
+
}
|
|
40327
|
+
}
|
|
40167
40328
|
const updated = await updateSchedule(cwd2, id, (s) => ({
|
|
40168
40329
|
...s,
|
|
40169
40330
|
status: action === "pause" ? "paused" : "active",
|
|
40170
40331
|
updatedAt: Date.now(),
|
|
40171
|
-
nextRunAt: action === "resume" ?
|
|
40332
|
+
nextRunAt: action === "resume" ? nextRunAt : s.nextRunAt
|
|
40172
40333
|
}));
|
|
40173
40334
|
if (!updated)
|
|
40174
40335
|
return `Schedule ${id} not found.`;
|
|
@@ -40653,6 +40814,7 @@ class HookExecutor {
|
|
|
40653
40814
|
return null;
|
|
40654
40815
|
try {
|
|
40655
40816
|
const proc = Bun.spawn(["bash", "-c", hook.command], {
|
|
40817
|
+
cwd: input.cwd || process.cwd(),
|
|
40656
40818
|
stdin: "pipe",
|
|
40657
40819
|
stdout: "pipe",
|
|
40658
40820
|
stderr: "pipe"
|
|
@@ -41187,11 +41349,11 @@ function summarizeConversation(messages) {
|
|
|
41187
41349
|
if (msg.role === "user") {
|
|
41188
41350
|
if (msg.toolResults && msg.toolResults.length > 0) {
|
|
41189
41351
|
for (const result of msg.toolResults) {
|
|
41190
|
-
const content = result.content.slice(0, 500);
|
|
41352
|
+
const content = (result.content || "").slice(0, 500);
|
|
41191
41353
|
summary.push(`[Tool Result - ${result.toolName || "unknown"}]: ${content}`);
|
|
41192
41354
|
}
|
|
41193
41355
|
} else {
|
|
41194
|
-
summary.push(`User: ${msg.content.slice(0, 300)}`);
|
|
41356
|
+
summary.push(`User: ${(msg.content ?? "").slice(0, 300)}`);
|
|
41195
41357
|
}
|
|
41196
41358
|
} else if (msg.role === "assistant") {
|
|
41197
41359
|
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
@@ -41200,8 +41362,9 @@ function summarizeConversation(messages) {
|
|
|
41200
41362
|
summary.push(`[Tool Call - ${call.name}]: ${input}`);
|
|
41201
41363
|
}
|
|
41202
41364
|
}
|
|
41203
|
-
|
|
41204
|
-
|
|
41365
|
+
const assistantContent = msg.content ?? "";
|
|
41366
|
+
if (assistantContent.trim()) {
|
|
41367
|
+
summary.push(`Assistant: ${assistantContent.slice(0, 300)}`);
|
|
41205
41368
|
}
|
|
41206
41369
|
}
|
|
41207
41370
|
}
|
|
@@ -41559,8 +41722,8 @@ ${stderr}`;
|
|
|
41559
41722
|
}
|
|
41560
41723
|
}
|
|
41561
41724
|
// packages/core/src/commands/builtin.ts
|
|
41562
|
-
import { join as
|
|
41563
|
-
import { homedir as
|
|
41725
|
+
import { join as join13 } from "path";
|
|
41726
|
+
import { homedir as homedir8, platform as platform2, release, arch } from "os";
|
|
41564
41727
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
41565
41728
|
init_src();
|
|
41566
41729
|
|
|
@@ -41664,23 +41827,28 @@ function hasProjectNameConflict(projects, name) {
|
|
|
41664
41827
|
|
|
41665
41828
|
// packages/core/src/projects/context.ts
|
|
41666
41829
|
import { readFile as readFile3 } from "fs/promises";
|
|
41667
|
-
import {
|
|
41830
|
+
import { homedir as homedir7 } from "os";
|
|
41831
|
+
import { resolve as resolve4, join as join12 } from "path";
|
|
41668
41832
|
var DEFAULT_MAX_FILE_BYTES = 12000;
|
|
41833
|
+
function singleLine(value) {
|
|
41834
|
+
return value.replace(/[\r\n]+/g, " ").trim();
|
|
41835
|
+
}
|
|
41669
41836
|
function formatPlan(plan) {
|
|
41670
41837
|
const lines = [];
|
|
41671
|
-
lines.push(`- ${plan.title} (${plan.steps.length} steps)`);
|
|
41838
|
+
lines.push(`- ${singleLine(plan.title)} (${plan.steps.length} steps)`);
|
|
41672
41839
|
for (const step of plan.steps) {
|
|
41673
|
-
lines.push(` - [${step.status}] ${step.text}`);
|
|
41840
|
+
lines.push(` - [${step.status}] ${singleLine(step.text)}`);
|
|
41674
41841
|
}
|
|
41675
41842
|
return lines.join(`
|
|
41676
41843
|
`);
|
|
41677
41844
|
}
|
|
41678
41845
|
function normalizeEntryLabel(entry) {
|
|
41679
|
-
return entry.label ? entry.label
|
|
41846
|
+
return entry.label ? singleLine(entry.label) : singleLine(entry.value);
|
|
41680
41847
|
}
|
|
41681
41848
|
async function renderFileEntry(entry, options) {
|
|
41682
41849
|
const rawPath = entry.value.trim();
|
|
41683
|
-
const
|
|
41850
|
+
const expandedPath = rawPath === "~" ? homedir7() : rawPath.startsWith("~/") ? join12(homedir7(), rawPath.slice(2)) : rawPath;
|
|
41851
|
+
const resolved = resolve4(options.cwd, expandedPath);
|
|
41684
41852
|
const validation = await validatePath(resolved, { allowedPaths: [options.cwd] });
|
|
41685
41853
|
if (!validation.valid) {
|
|
41686
41854
|
return `- File: ${rawPath} (unavailable: ${validation.error || "invalid path"})`;
|
|
@@ -41812,7 +41980,7 @@ function splitArgs(input) {
|
|
|
41812
41980
|
args.push(current);
|
|
41813
41981
|
return args;
|
|
41814
41982
|
}
|
|
41815
|
-
function
|
|
41983
|
+
function singleLine2(value) {
|
|
41816
41984
|
return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
41817
41985
|
}
|
|
41818
41986
|
|
|
@@ -42651,12 +42819,12 @@ No context entries for project "${project.name}".
|
|
|
42651
42819
|
return { handled: true };
|
|
42652
42820
|
}
|
|
42653
42821
|
let output = `
|
|
42654
|
-
**Context Entries (${
|
|
42822
|
+
**Context Entries (${singleLine2(project.name)})**
|
|
42655
42823
|
|
|
42656
42824
|
`;
|
|
42657
42825
|
for (const entry of project.context) {
|
|
42658
|
-
const label = entry.label ? ` (${
|
|
42659
|
-
output += `- ${entry.id} [${entry.type}] ${
|
|
42826
|
+
const label = entry.label ? ` (${singleLine2(entry.label)})` : "";
|
|
42827
|
+
output += `- ${entry.id} [${entry.type}] ${singleLine2(entry.value)}${label}
|
|
42660
42828
|
`;
|
|
42661
42829
|
}
|
|
42662
42830
|
context.emit("text", output);
|
|
@@ -42803,7 +42971,7 @@ No projects found. Use /projects new <name>.
|
|
|
42803
42971
|
`;
|
|
42804
42972
|
for (const project of projects) {
|
|
42805
42973
|
const marker = project.id === activeId ? "*" : " ";
|
|
42806
|
-
output += `${marker} ${
|
|
42974
|
+
output += `${marker} ${singleLine2(project.name)} (${project.id})
|
|
42807
42975
|
`;
|
|
42808
42976
|
}
|
|
42809
42977
|
context.emit("text", output);
|
|
@@ -42865,13 +43033,13 @@ No projects found. Use /projects new <name>.
|
|
|
42865
43033
|
return { handled: true };
|
|
42866
43034
|
}
|
|
42867
43035
|
let output = `
|
|
42868
|
-
**Project: ${
|
|
43036
|
+
**Project: ${singleLine2(project.name)}**
|
|
42869
43037
|
|
|
42870
43038
|
`;
|
|
42871
43039
|
output += `ID: ${project.id}
|
|
42872
43040
|
`;
|
|
42873
43041
|
if (project.description) {
|
|
42874
|
-
output += `Description: ${
|
|
43042
|
+
output += `Description: ${singleLine2(project.description)}
|
|
42875
43043
|
`;
|
|
42876
43044
|
}
|
|
42877
43045
|
output += `Context entries: ${project.context.length}
|
|
@@ -42997,11 +43165,11 @@ No plans for project "${project.name}".
|
|
|
42997
43165
|
return { handled: true };
|
|
42998
43166
|
}
|
|
42999
43167
|
let output = `
|
|
43000
|
-
**Plans (${
|
|
43168
|
+
**Plans (${singleLine2(project.name)})**
|
|
43001
43169
|
|
|
43002
43170
|
`;
|
|
43003
43171
|
for (const plan of project.plans) {
|
|
43004
|
-
output += `- ${plan.id} ${
|
|
43172
|
+
output += `- ${plan.id} ${singleLine2(plan.title)} (${plan.steps.length} steps)
|
|
43005
43173
|
`;
|
|
43006
43174
|
}
|
|
43007
43175
|
context.emit("text", output);
|
|
@@ -43057,7 +43225,7 @@ No plans for project "${project.name}".
|
|
|
43057
43225
|
return { handled: true };
|
|
43058
43226
|
}
|
|
43059
43227
|
let output = `
|
|
43060
|
-
**Plan: ${
|
|
43228
|
+
**Plan: ${singleLine2(plan.title)}**
|
|
43061
43229
|
|
|
43062
43230
|
`;
|
|
43063
43231
|
output += `ID: ${plan.id}
|
|
@@ -43067,7 +43235,7 @@ No plans for project "${project.name}".
|
|
|
43067
43235
|
`;
|
|
43068
43236
|
} else {
|
|
43069
43237
|
for (const step of plan.steps) {
|
|
43070
|
-
output += `- ${step.id} [${step.status}] ${
|
|
43238
|
+
output += `- ${step.id} [${step.status}] ${singleLine2(step.text)}
|
|
43071
43239
|
`;
|
|
43072
43240
|
}
|
|
43073
43241
|
}
|
|
@@ -43500,9 +43668,9 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43500
43668
|
content: "",
|
|
43501
43669
|
handler: async (args, context) => {
|
|
43502
43670
|
const configPaths = [
|
|
43503
|
-
|
|
43504
|
-
|
|
43505
|
-
|
|
43671
|
+
join13(context.cwd, ".assistants", "config.json"),
|
|
43672
|
+
join13(context.cwd, ".assistants", "config.local.json"),
|
|
43673
|
+
join13(getConfigDir(), "config.json")
|
|
43506
43674
|
];
|
|
43507
43675
|
let message = `
|
|
43508
43676
|
**Configuration**
|
|
@@ -43516,13 +43684,13 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43516
43684
|
`;
|
|
43517
43685
|
}
|
|
43518
43686
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
43519
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
43687
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir8();
|
|
43520
43688
|
message += `
|
|
43521
43689
|
**Commands Directories:**
|
|
43522
43690
|
`;
|
|
43523
|
-
message += ` - Project: ${
|
|
43691
|
+
message += ` - Project: ${join13(context.cwd, ".assistants", "commands")}
|
|
43524
43692
|
`;
|
|
43525
|
-
message += ` - Global: ${
|
|
43693
|
+
message += ` - Global: ${join13(homeDir, ".assistants", "commands")}
|
|
43526
43694
|
`;
|
|
43527
43695
|
context.emit("text", message);
|
|
43528
43696
|
context.emit("done");
|
|
@@ -43538,7 +43706,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
43538
43706
|
selfHandled: true,
|
|
43539
43707
|
content: "",
|
|
43540
43708
|
handler: async (args, context) => {
|
|
43541
|
-
const commandsDir =
|
|
43709
|
+
const commandsDir = join13(context.cwd, ".assistants", "commands");
|
|
43542
43710
|
mkdirSync4(commandsDir, { recursive: true });
|
|
43543
43711
|
const exampleCommand = `---
|
|
43544
43712
|
name: reflect
|
|
@@ -43554,7 +43722,7 @@ Please summarize the last interaction and suggest 2-3 next steps.
|
|
|
43554
43722
|
- Focus on clarity
|
|
43555
43723
|
- Ask a follow-up question if needed
|
|
43556
43724
|
`;
|
|
43557
|
-
const examplePath =
|
|
43725
|
+
const examplePath = join13(commandsDir, "reflect.md");
|
|
43558
43726
|
if (!existsSync7(examplePath)) {
|
|
43559
43727
|
writeFileSync5(examplePath, exampleCommand);
|
|
43560
43728
|
}
|
|
@@ -44720,13 +44888,13 @@ function validateToolCalls(toolCalls, tools) {
|
|
|
44720
44888
|
|
|
44721
44889
|
// packages/core/src/voice/utils.ts
|
|
44722
44890
|
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
|
|
44723
|
-
import { homedir as
|
|
44724
|
-
import { join as
|
|
44891
|
+
import { homedir as homedir10 } from "os";
|
|
44892
|
+
import { join as join15 } from "path";
|
|
44725
44893
|
import { spawnSync } from "child_process";
|
|
44726
44894
|
function loadApiKeyFromSecrets2(key) {
|
|
44727
44895
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
44728
|
-
const homeDir = envHome && envHome.trim().length > 0 ? envHome :
|
|
44729
|
-
const secretsPath =
|
|
44896
|
+
const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir10();
|
|
44897
|
+
const secretsPath = join15(homeDir, ".secrets");
|
|
44730
44898
|
if (!existsSync9(secretsPath))
|
|
44731
44899
|
return;
|
|
44732
44900
|
try {
|
|
@@ -44800,7 +44968,7 @@ class SystemSTT {
|
|
|
44800
44968
|
// packages/core/src/voice/tts.ts
|
|
44801
44969
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
44802
44970
|
import { tmpdir as tmpdir2 } from "os";
|
|
44803
|
-
import { join as
|
|
44971
|
+
import { join as join16 } from "path";
|
|
44804
44972
|
import { readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
44805
44973
|
class ElevenLabsTTS {
|
|
44806
44974
|
apiKey;
|
|
@@ -44904,7 +45072,7 @@ class SystemTTS {
|
|
|
44904
45072
|
if (!say) {
|
|
44905
45073
|
throw new Error('System TTS not available: missing "say" command.');
|
|
44906
45074
|
}
|
|
44907
|
-
const output =
|
|
45075
|
+
const output = join16(tmpdir2(), `assistants-tts-${Date.now()}.aiff`);
|
|
44908
45076
|
const args = [];
|
|
44909
45077
|
if (this.voiceId) {
|
|
44910
45078
|
args.push("-v", this.voiceId);
|
|
@@ -44926,7 +45094,7 @@ class SystemTTS {
|
|
|
44926
45094
|
}
|
|
44927
45095
|
const espeak = findExecutable("espeak") || findExecutable("espeak-ng");
|
|
44928
45096
|
if (espeak) {
|
|
44929
|
-
const output =
|
|
45097
|
+
const output = join16(tmpdir2(), `assistants-tts-${Date.now()}.wav`);
|
|
44930
45098
|
const args = ["-w", output];
|
|
44931
45099
|
if (this.voiceId) {
|
|
44932
45100
|
args.push("-v", this.voiceId);
|
|
@@ -44953,14 +45121,14 @@ class SystemTTS {
|
|
|
44953
45121
|
// packages/core/src/voice/player.ts
|
|
44954
45122
|
import { spawn } from "child_process";
|
|
44955
45123
|
import { tmpdir as tmpdir3 } from "os";
|
|
44956
|
-
import { join as
|
|
45124
|
+
import { join as join17 } from "path";
|
|
44957
45125
|
import { unlink as unlink4, writeFileSync as writeFileSync6 } from "fs";
|
|
44958
45126
|
class AudioPlayer {
|
|
44959
45127
|
currentProcess = null;
|
|
44960
45128
|
playing = false;
|
|
44961
45129
|
async play(audio, options = {}) {
|
|
44962
45130
|
const format = options.format ?? "mp3";
|
|
44963
|
-
const tempFile =
|
|
45131
|
+
const tempFile = join17(tmpdir3(), `assistants-audio-${Date.now()}.${format}`);
|
|
44964
45132
|
writeFileSync6(tempFile, Buffer.from(audio));
|
|
44965
45133
|
const player = this.resolvePlayer(format);
|
|
44966
45134
|
if (!player) {
|
|
@@ -45028,7 +45196,7 @@ class AudioPlayer {
|
|
|
45028
45196
|
// packages/core/src/voice/recorder.ts
|
|
45029
45197
|
import { spawn as spawn2 } from "child_process";
|
|
45030
45198
|
import { tmpdir as tmpdir4 } from "os";
|
|
45031
|
-
import { join as
|
|
45199
|
+
import { join as join18 } from "path";
|
|
45032
45200
|
import { readFileSync as readFileSync7, unlink as unlink5 } from "fs";
|
|
45033
45201
|
class AudioRecorder {
|
|
45034
45202
|
currentProcess = null;
|
|
@@ -45039,7 +45207,7 @@ class AudioRecorder {
|
|
|
45039
45207
|
const duration = options.durationSeconds ?? 5;
|
|
45040
45208
|
const sampleRate = options.sampleRate ?? 16000;
|
|
45041
45209
|
const channels = options.channels ?? 1;
|
|
45042
|
-
const output =
|
|
45210
|
+
const output = join18(tmpdir4(), `assistants-record-${Date.now()}.wav`);
|
|
45043
45211
|
const recorder = this.resolveRecorder(sampleRate, channels, duration, output);
|
|
45044
45212
|
if (!recorder) {
|
|
45045
45213
|
throw new Error("No supported audio recorder found. Install sox or ffmpeg.");
|
|
@@ -45233,13 +45401,13 @@ class VoiceManager {
|
|
|
45233
45401
|
init_src();
|
|
45234
45402
|
import { existsSync as existsSync11 } from "fs";
|
|
45235
45403
|
import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile7, rm as rm2 } from "fs/promises";
|
|
45236
|
-
import { join as
|
|
45404
|
+
import { join as join20 } from "path";
|
|
45237
45405
|
|
|
45238
45406
|
// packages/core/src/identity/identity-manager.ts
|
|
45239
45407
|
init_src();
|
|
45240
45408
|
import { existsSync as existsSync10 } from "fs";
|
|
45241
45409
|
import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile6, rm } from "fs/promises";
|
|
45242
|
-
import { join as
|
|
45410
|
+
import { join as join19 } from "path";
|
|
45243
45411
|
var DEFAULT_PROFILE = {
|
|
45244
45412
|
displayName: "Assistant",
|
|
45245
45413
|
timezone: "UTC",
|
|
@@ -45269,19 +45437,19 @@ class IdentityManager {
|
|
|
45269
45437
|
this.basePath = basePath;
|
|
45270
45438
|
}
|
|
45271
45439
|
get identitiesRoot() {
|
|
45272
|
-
return
|
|
45440
|
+
return join19(this.basePath, "assistants", this.assistantId, "identities");
|
|
45273
45441
|
}
|
|
45274
45442
|
get indexPath() {
|
|
45275
|
-
return
|
|
45443
|
+
return join19(this.identitiesRoot, "index.json");
|
|
45276
45444
|
}
|
|
45277
45445
|
get activePath() {
|
|
45278
|
-
return
|
|
45446
|
+
return join19(this.identitiesRoot, "active.json");
|
|
45279
45447
|
}
|
|
45280
45448
|
identityPath(id) {
|
|
45281
|
-
return
|
|
45449
|
+
return join19(this.identitiesRoot, `${id}.json`);
|
|
45282
45450
|
}
|
|
45283
45451
|
assistantConfigPath() {
|
|
45284
|
-
return
|
|
45452
|
+
return join19(this.basePath, "assistants", this.assistantId, "config.json");
|
|
45285
45453
|
}
|
|
45286
45454
|
async initialize() {
|
|
45287
45455
|
await mkdir4(this.identitiesRoot, { recursive: true });
|
|
@@ -45465,16 +45633,16 @@ class AssistantManager {
|
|
|
45465
45633
|
this.basePath = basePath;
|
|
45466
45634
|
}
|
|
45467
45635
|
get assistantsRoot() {
|
|
45468
|
-
return
|
|
45636
|
+
return join20(this.basePath, "assistants");
|
|
45469
45637
|
}
|
|
45470
45638
|
get indexPath() {
|
|
45471
|
-
return
|
|
45639
|
+
return join20(this.assistantsRoot, "index.json");
|
|
45472
45640
|
}
|
|
45473
45641
|
get activePath() {
|
|
45474
|
-
return
|
|
45642
|
+
return join20(this.basePath, "active.json");
|
|
45475
45643
|
}
|
|
45476
45644
|
assistantConfigPath(id) {
|
|
45477
|
-
return
|
|
45645
|
+
return join20(this.assistantsRoot, id, "config.json");
|
|
45478
45646
|
}
|
|
45479
45647
|
async initialize() {
|
|
45480
45648
|
await mkdir5(this.assistantsRoot, { recursive: true });
|
|
@@ -45528,7 +45696,7 @@ class AssistantManager {
|
|
|
45528
45696
|
if (!this.assistants.has(id)) {
|
|
45529
45697
|
throw new Error(`Assistant ${id} not found`);
|
|
45530
45698
|
}
|
|
45531
|
-
await rm2(
|
|
45699
|
+
await rm2(join20(this.assistantsRoot, id), { recursive: true, force: true });
|
|
45532
45700
|
this.assistants.delete(id);
|
|
45533
45701
|
await this.removeFromIndex(id);
|
|
45534
45702
|
if (this.activeId === id) {
|
|
@@ -45594,7 +45762,7 @@ class AssistantManager {
|
|
|
45594
45762
|
}
|
|
45595
45763
|
}
|
|
45596
45764
|
async persistAssistant(assistant) {
|
|
45597
|
-
const dir =
|
|
45765
|
+
const dir = join20(this.assistantsRoot, assistant.id);
|
|
45598
45766
|
await mkdir5(dir, { recursive: true });
|
|
45599
45767
|
await writeFile7(this.assistantConfigPath(assistant.id), JSON.stringify(assistant, null, 2));
|
|
45600
45768
|
}
|
|
@@ -46436,7 +46604,7 @@ ${content.trim()}`);
|
|
|
46436
46604
|
const heartbeatConfig = this.buildHeartbeatConfig(this.config);
|
|
46437
46605
|
if (!heartbeatConfig)
|
|
46438
46606
|
return;
|
|
46439
|
-
const statePath =
|
|
46607
|
+
const statePath = join21(getConfigDir(), "state", `${this.sessionId}.json`);
|
|
46440
46608
|
this.heartbeatManager = new HeartbeatManager(heartbeatConfig);
|
|
46441
46609
|
this.heartbeatPersistence = new StatePersistence(statePath);
|
|
46442
46610
|
this.heartbeatRecovery = new RecoveryManager(this.heartbeatPersistence, heartbeatConfig.persistPath, heartbeatConfig.staleThresholdMs, {
|
|
@@ -46485,7 +46653,7 @@ ${content.trim()}`);
|
|
|
46485
46653
|
async startEnergySystem() {
|
|
46486
46654
|
if (!this.config || this.config.energy?.enabled === false)
|
|
46487
46655
|
return;
|
|
46488
|
-
const statePath =
|
|
46656
|
+
const statePath = join21(getConfigDir(), "energy", "state.json");
|
|
46489
46657
|
this.energyManager = new EnergyManager(this.config.energy, new EnergyStorage(statePath));
|
|
46490
46658
|
await this.energyManager.initialize();
|
|
46491
46659
|
this.refreshEnergyEffects();
|
|
@@ -46662,7 +46830,7 @@ ${this.identityContext}`);
|
|
|
46662
46830
|
for (const msg of messages) {
|
|
46663
46831
|
if (msg.role !== "system")
|
|
46664
46832
|
continue;
|
|
46665
|
-
const content = msg.content.trim();
|
|
46833
|
+
const content = (msg.content ?? "").trim();
|
|
46666
46834
|
if (!content)
|
|
46667
46835
|
continue;
|
|
46668
46836
|
if (parts.includes(content))
|
|
@@ -46731,7 +46899,7 @@ ${this.identityContext}`);
|
|
|
46731
46899
|
return null;
|
|
46732
46900
|
const intervalMs = Math.max(1000, config.heartbeat?.intervalMs ?? 15000);
|
|
46733
46901
|
const staleThresholdMs = Math.max(intervalMs * 2, config.heartbeat?.staleThresholdMs ?? 120000);
|
|
46734
|
-
const persistPath = config.heartbeat?.persistPath ??
|
|
46902
|
+
const persistPath = config.heartbeat?.persistPath ?? join21(getConfigDir(), "heartbeats", `${this.sessionId}.json`);
|
|
46735
46903
|
return {
|
|
46736
46904
|
intervalMs,
|
|
46737
46905
|
staleThresholdMs,
|
|
@@ -46828,17 +46996,17 @@ init_src();
|
|
|
46828
46996
|
|
|
46829
46997
|
// packages/core/src/logger.ts
|
|
46830
46998
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, appendFileSync, readdirSync as readdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
46831
|
-
import { join as
|
|
46999
|
+
import { join as join22 } from "path";
|
|
46832
47000
|
class Logger {
|
|
46833
47001
|
logDir;
|
|
46834
47002
|
logFile;
|
|
46835
47003
|
sessionId;
|
|
46836
47004
|
constructor(sessionId, basePath) {
|
|
46837
47005
|
this.sessionId = sessionId;
|
|
46838
|
-
this.logDir =
|
|
47006
|
+
this.logDir = join22(basePath || getConfigDir(), "logs");
|
|
46839
47007
|
this.ensureDir(this.logDir);
|
|
46840
47008
|
const date = new Date().toISOString().split("T")[0];
|
|
46841
|
-
this.logFile =
|
|
47009
|
+
this.logFile = join22(this.logDir, `${date}.log`);
|
|
46842
47010
|
}
|
|
46843
47011
|
ensureDir(dir) {
|
|
46844
47012
|
if (!existsSync12(dir)) {
|
|
@@ -46882,9 +47050,9 @@ class SessionStorage {
|
|
|
46882
47050
|
constructor(sessionId, basePath, assistantId) {
|
|
46883
47051
|
this.sessionId = sessionId;
|
|
46884
47052
|
const root = basePath || getConfigDir();
|
|
46885
|
-
this.sessionsDir = assistantId ?
|
|
47053
|
+
this.sessionsDir = assistantId ? join22(root, "assistants", assistantId, "sessions") : join22(root, "sessions");
|
|
46886
47054
|
this.ensureDir(this.sessionsDir);
|
|
46887
|
-
this.sessionFile =
|
|
47055
|
+
this.sessionFile = join22(this.sessionsDir, `${sessionId}.json`);
|
|
46888
47056
|
}
|
|
46889
47057
|
ensureDir(dir) {
|
|
46890
47058
|
if (!existsSync12(dir)) {
|
|
@@ -46910,7 +47078,7 @@ class SessionStorage {
|
|
|
46910
47078
|
}
|
|
46911
47079
|
static getActiveAssistantId() {
|
|
46912
47080
|
try {
|
|
46913
|
-
const activePath =
|
|
47081
|
+
const activePath = join22(getConfigDir(), "active.json");
|
|
46914
47082
|
if (!existsSync12(activePath))
|
|
46915
47083
|
return null;
|
|
46916
47084
|
const raw = readFileSync8(activePath, "utf-8");
|
|
@@ -46924,12 +47092,12 @@ class SessionStorage {
|
|
|
46924
47092
|
const root = getConfigDir();
|
|
46925
47093
|
const resolvedId = assistantId ?? SessionStorage.getActiveAssistantId();
|
|
46926
47094
|
if (resolvedId) {
|
|
46927
|
-
const assistantDir =
|
|
47095
|
+
const assistantDir = join22(root, "assistants", resolvedId, "sessions");
|
|
46928
47096
|
if (existsSync12(assistantDir)) {
|
|
46929
47097
|
return assistantDir;
|
|
46930
47098
|
}
|
|
46931
47099
|
}
|
|
46932
|
-
return
|
|
47100
|
+
return join22(root, "sessions");
|
|
46933
47101
|
}
|
|
46934
47102
|
static listSessions(assistantId) {
|
|
46935
47103
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
@@ -46941,7 +47109,7 @@ class SessionStorage {
|
|
|
46941
47109
|
if (!file.endsWith(".json"))
|
|
46942
47110
|
continue;
|
|
46943
47111
|
try {
|
|
46944
|
-
const filePath =
|
|
47112
|
+
const filePath = join22(sessionsDir, file);
|
|
46945
47113
|
const stat = Bun.file(filePath);
|
|
46946
47114
|
const content = JSON.parse(readFileSync8(filePath, "utf-8"));
|
|
46947
47115
|
sessions.push({
|
|
@@ -46961,7 +47129,7 @@ class SessionStorage {
|
|
|
46961
47129
|
}
|
|
46962
47130
|
static loadSession(sessionId, assistantId) {
|
|
46963
47131
|
const sessionsDir = SessionStorage.resolveSessionsDir(assistantId);
|
|
46964
|
-
const sessionFile =
|
|
47132
|
+
const sessionFile = join22(sessionsDir, `${sessionId}.json`);
|
|
46965
47133
|
try {
|
|
46966
47134
|
if (!existsSync12(sessionFile))
|
|
46967
47135
|
return null;
|
|
@@ -46975,15 +47143,15 @@ function initAssistantsDir() {
|
|
|
46975
47143
|
const baseDir = getConfigDir();
|
|
46976
47144
|
const dirs = [
|
|
46977
47145
|
baseDir,
|
|
46978
|
-
|
|
46979
|
-
|
|
46980
|
-
|
|
46981
|
-
|
|
46982
|
-
|
|
46983
|
-
|
|
46984
|
-
|
|
46985
|
-
|
|
46986
|
-
|
|
47146
|
+
join22(baseDir, "logs"),
|
|
47147
|
+
join22(baseDir, "assistants"),
|
|
47148
|
+
join22(baseDir, "shared", "skills"),
|
|
47149
|
+
join22(baseDir, "commands"),
|
|
47150
|
+
join22(baseDir, "temp"),
|
|
47151
|
+
join22(baseDir, "heartbeats"),
|
|
47152
|
+
join22(baseDir, "state"),
|
|
47153
|
+
join22(baseDir, "energy"),
|
|
47154
|
+
join22(baseDir, "migration")
|
|
46987
47155
|
];
|
|
46988
47156
|
for (const dir of dirs) {
|
|
46989
47157
|
if (!existsSync12(dir)) {
|
|
@@ -47543,6 +47711,13 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47543
47711
|
return skills.filter((skill) => skill.name.toLowerCase().startsWith(search));
|
|
47544
47712
|
}, [value, autocompleteMode, skills]);
|
|
47545
47713
|
const autocompleteItems = autocompleteMode === "skill" ? filteredSkills : filteredCommands;
|
|
47714
|
+
import_react23.useEffect(() => {
|
|
47715
|
+
if (autocompleteItems.length === 0) {
|
|
47716
|
+
setSelectedIndex(0);
|
|
47717
|
+
return;
|
|
47718
|
+
}
|
|
47719
|
+
setSelectedIndex((prev) => Math.min(prev, autocompleteItems.length - 1));
|
|
47720
|
+
}, [autocompleteItems.length]);
|
|
47546
47721
|
use_input_default((input, key) => {
|
|
47547
47722
|
if (key.tab) {
|
|
47548
47723
|
if (autocompleteItems.length > 0) {
|
|
@@ -47632,7 +47807,7 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47632
47807
|
const visibleSkills = getVisibleItems(filteredSkills);
|
|
47633
47808
|
const visibleCommands = getVisibleItems(filteredCommands);
|
|
47634
47809
|
const { stdout } = use_stdout_default();
|
|
47635
|
-
const terminalWidth = stdout?.columns ?? 80;
|
|
47810
|
+
const terminalWidth = Math.max(10, (stdout?.columns ?? 80) - 2);
|
|
47636
47811
|
const lines = value.split(`
|
|
47637
47812
|
`);
|
|
47638
47813
|
const lineCount = lines.length;
|
|
@@ -47642,16 +47817,15 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47642
47817
|
children: [
|
|
47643
47818
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
47644
47819
|
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
47645
|
-
|
|
47646
|
-
children: "
|
|
47820
|
+
color: "#666666",
|
|
47821
|
+
children: "-".repeat(terminalWidth)
|
|
47647
47822
|
}, undefined, false, undefined, this)
|
|
47648
47823
|
}, undefined, false, undefined, this),
|
|
47649
47824
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
47650
47825
|
paddingY: 0,
|
|
47651
47826
|
children: [
|
|
47652
47827
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
47653
|
-
|
|
47654
|
-
color: isProcessing ? undefined : "cyan",
|
|
47828
|
+
color: isProcessing ? "gray" : "cyan",
|
|
47655
47829
|
children: "> "
|
|
47656
47830
|
}, undefined, false, undefined, this),
|
|
47657
47831
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
@@ -47668,7 +47842,7 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47668
47842
|
lineCount > 1 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
47669
47843
|
marginLeft: 2,
|
|
47670
47844
|
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
47671
|
-
|
|
47845
|
+
color: "gray",
|
|
47672
47846
|
children: [
|
|
47673
47847
|
"(",
|
|
47674
47848
|
lineCount,
|
|
@@ -47678,8 +47852,8 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = []
|
|
|
47678
47852
|
}, undefined, false, undefined, this),
|
|
47679
47853
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
47680
47854
|
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
47681
|
-
|
|
47682
|
-
children: "
|
|
47855
|
+
color: "#666666",
|
|
47856
|
+
children: "-".repeat(terminalWidth)
|
|
47683
47857
|
}, undefined, false, undefined, this)
|
|
47684
47858
|
}, undefined, false, undefined, this),
|
|
47685
47859
|
isProcessing && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
@@ -48228,7 +48402,7 @@ function formatMarkdownTables(text, maxWidth) {
|
|
|
48228
48402
|
function parseTableRow(line) {
|
|
48229
48403
|
const trimmed = line.trim();
|
|
48230
48404
|
const withoutEdges = trimmed.replace(/^\|/, "").replace(/\|$/, "");
|
|
48231
|
-
return withoutEdges.split("|").map((cell) => cell.trim());
|
|
48405
|
+
return withoutEdges.split("|").map((cell) => cell.replace(/[\r\n]+/g, " ").trim());
|
|
48232
48406
|
}
|
|
48233
48407
|
function renderTable(header, rows, maxWidth) {
|
|
48234
48408
|
const colCount = Math.max(header.length, ...rows.map((r) => r.length));
|
|
@@ -48523,7 +48697,7 @@ function truncateToolResult(toolResult, maxLines = 15, maxChars = 3000) {
|
|
|
48523
48697
|
if (content.length > maxChars) {
|
|
48524
48698
|
content = content.slice(0, maxChars) + "...";
|
|
48525
48699
|
}
|
|
48526
|
-
return prefix + content.
|
|
48700
|
+
return prefix + content.trimEnd();
|
|
48527
48701
|
}
|
|
48528
48702
|
function formatToolResultNicely(toolName, content, isError) {
|
|
48529
48703
|
if (isError) {
|
|
@@ -49575,7 +49749,7 @@ function ProcessingIndicator({
|
|
|
49575
49749
|
var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
|
|
49576
49750
|
function WelcomeBanner({ version, model, directory }) {
|
|
49577
49751
|
const homeDir = process.env.HOME || "";
|
|
49578
|
-
const displayDir = directory.startsWith(homeDir) ? "~" + directory.slice(homeDir.length) : directory;
|
|
49752
|
+
const displayDir = homeDir && directory.startsWith(homeDir) ? "~" + directory.slice(homeDir.length) : directory;
|
|
49579
49753
|
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
49580
49754
|
flexDirection: "column",
|
|
49581
49755
|
marginBottom: 1,
|
|
@@ -49661,7 +49835,7 @@ function formatSessionTime(timestamp) {
|
|
|
49661
49835
|
}
|
|
49662
49836
|
function formatPath(cwd2) {
|
|
49663
49837
|
const home = process.env.HOME || "";
|
|
49664
|
-
if (cwd2.startsWith(home)) {
|
|
49838
|
+
if (home && cwd2.startsWith(home)) {
|
|
49665
49839
|
return "~" + cwd2.slice(home.length);
|
|
49666
49840
|
}
|
|
49667
49841
|
return cwd2;
|
|
@@ -49867,7 +50041,8 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
49867
50041
|
continue;
|
|
49868
50042
|
}
|
|
49869
50043
|
if (msg.role === "assistant") {
|
|
49870
|
-
const
|
|
50044
|
+
const assistantWidth = options?.maxWidth ? Math.max(1, options.maxWidth - 2) : undefined;
|
|
50045
|
+
const rendered = renderMarkdown(content, { maxWidth: assistantWidth });
|
|
49871
50046
|
const renderedLines = rendered.split(`
|
|
49872
50047
|
`);
|
|
49873
50048
|
if (renderedLines.length <= chunkLines) {
|
|
@@ -49889,7 +50064,8 @@ function buildDisplayMessages(messages, chunkLines, wrapChars, options) {
|
|
|
49889
50064
|
}
|
|
49890
50065
|
continue;
|
|
49891
50066
|
}
|
|
49892
|
-
const
|
|
50067
|
+
const effectiveWrap = msg.role === "user" ? Math.max(1, wrapChars - 2) : wrapChars;
|
|
50068
|
+
const lines = wrapTextLines(content, effectiveWrap);
|
|
49893
50069
|
if (lines.length <= chunkLines) {
|
|
49894
50070
|
display.push(msg);
|
|
49895
50071
|
continue;
|
|
@@ -50964,7 +51140,7 @@ function formatStreamEvent(chunk) {
|
|
|
50964
51140
|
|
|
50965
51141
|
// packages/terminal/src/index.tsx
|
|
50966
51142
|
var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
50967
|
-
var VERSION3 = "0.6.
|
|
51143
|
+
var VERSION3 = "0.6.34";
|
|
50968
51144
|
process.env.ASSISTANTS_VERSION ??= VERSION3;
|
|
50969
51145
|
function parseArgs(argv) {
|
|
50970
51146
|
const args = argv.slice(2);
|
|
@@ -51120,4 +51296,4 @@ if (options.print !== null) {
|
|
|
51120
51296
|
});
|
|
51121
51297
|
}
|
|
51122
51298
|
|
|
51123
|
-
//# debugId=
|
|
51299
|
+
//# debugId=83E7550093AA9F2D64756E2164756E21
|