scream-code 0.11.7 → 0.11.8
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.
|
@@ -7,7 +7,7 @@ import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } fr
|
|
|
7
7
|
import "./suppress-sqlite-warning-C2VB0doZ.mjs";
|
|
8
8
|
import { C as join$1, D as resolve$1, E as relative$1, S as isAbsolute$1, T as parse$7, a as isSupportedFile, b as basename$1, i as ingestFile, r as ingestDirectory, t as multiSearch, w as normalize, x as dirname$2, y as KnowledgeStore } from "./src-BH9W5k24.mjs";
|
|
9
9
|
import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
|
|
10
|
-
import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-
|
|
10
|
+
import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-DYHGTG6m.mjs";
|
|
11
11
|
import { createRequire } from "node:module";
|
|
12
12
|
import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
|
|
13
13
|
import * as fs$1 from "node:fs/promises";
|
|
@@ -119233,6 +119233,77 @@ function parsePositiveInt(value) {
|
|
|
119233
119233
|
return n;
|
|
119234
119234
|
}
|
|
119235
119235
|
//#endregion
|
|
119236
|
+
//#region ../../packages/agent-core/src/session/provider-balance.ts
|
|
119237
|
+
const fetchers = [{
|
|
119238
|
+
matches: (baseUrl) => {
|
|
119239
|
+
try {
|
|
119240
|
+
return new URL(baseUrl).hostname === "api.deepseek.com";
|
|
119241
|
+
} catch {
|
|
119242
|
+
return false;
|
|
119243
|
+
}
|
|
119244
|
+
},
|
|
119245
|
+
fetch: async (baseUrl, apiKey) => {
|
|
119246
|
+
try {
|
|
119247
|
+
const root = new URL(baseUrl).origin;
|
|
119248
|
+
const res = await fetch(`${root}/user/balance`, {
|
|
119249
|
+
headers: {
|
|
119250
|
+
Accept: "application/json",
|
|
119251
|
+
Authorization: `Bearer ${apiKey}`
|
|
119252
|
+
},
|
|
119253
|
+
signal: AbortSignal.timeout(5e3)
|
|
119254
|
+
});
|
|
119255
|
+
if (!res.ok) return null;
|
|
119256
|
+
const info = (await res.json()).balance_infos?.[0];
|
|
119257
|
+
if (info?.total_balance === void 0) return null;
|
|
119258
|
+
return {
|
|
119259
|
+
currency: info.currency ?? "",
|
|
119260
|
+
totalBalance: info.total_balance
|
|
119261
|
+
};
|
|
119262
|
+
} catch {
|
|
119263
|
+
return null;
|
|
119264
|
+
}
|
|
119265
|
+
}
|
|
119266
|
+
}, {
|
|
119267
|
+
matches: (baseUrl) => {
|
|
119268
|
+
try {
|
|
119269
|
+
return new URL(baseUrl).hostname === "api.moonshot.cn";
|
|
119270
|
+
} catch {
|
|
119271
|
+
return false;
|
|
119272
|
+
}
|
|
119273
|
+
},
|
|
119274
|
+
fetch: async (baseUrl, apiKey) => {
|
|
119275
|
+
try {
|
|
119276
|
+
const root = new URL(baseUrl).origin;
|
|
119277
|
+
const res = await fetch(`${root}/v1/users/me/balance`, {
|
|
119278
|
+
headers: {
|
|
119279
|
+
Accept: "application/json",
|
|
119280
|
+
Authorization: `Bearer ${apiKey}`
|
|
119281
|
+
},
|
|
119282
|
+
signal: AbortSignal.timeout(5e3)
|
|
119283
|
+
});
|
|
119284
|
+
if (!res.ok) return null;
|
|
119285
|
+
const data = await res.json();
|
|
119286
|
+
if (typeof data.data?.available_balance !== "number") return null;
|
|
119287
|
+
return {
|
|
119288
|
+
currency: "CNY",
|
|
119289
|
+
totalBalance: data.data.available_balance.toFixed(2)
|
|
119290
|
+
};
|
|
119291
|
+
} catch {
|
|
119292
|
+
return null;
|
|
119293
|
+
}
|
|
119294
|
+
}
|
|
119295
|
+
}];
|
|
119296
|
+
/**
|
|
119297
|
+
* Look up the balance for the given provider endpoint.
|
|
119298
|
+
* Returns null when the endpoint is not a recognized official vendor or
|
|
119299
|
+
* when the lookup fails — callers render nothing in that case.
|
|
119300
|
+
*/
|
|
119301
|
+
async function fetchProviderBalance(baseUrl, apiKey) {
|
|
119302
|
+
const fetcher = fetchers.find((f) => f.matches(baseUrl));
|
|
119303
|
+
if (!fetcher) return null;
|
|
119304
|
+
return fetcher.fetch(baseUrl, apiKey);
|
|
119305
|
+
}
|
|
119306
|
+
//#endregion
|
|
119236
119307
|
//#region ../../packages/node-sdk/src/auth.ts
|
|
119237
119308
|
var ScreamAuthFacade = class {
|
|
119238
119309
|
options;
|
|
@@ -120653,7 +120724,7 @@ function optionalBuildString(value) {
|
|
|
120653
120724
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
120654
120725
|
}
|
|
120655
120726
|
const SCREAM_BUILD_INFO = {
|
|
120656
|
-
version: optionalBuildString("0.11.
|
|
120727
|
+
version: optionalBuildString("0.11.8"),
|
|
120657
120728
|
channel: optionalBuildString(""),
|
|
120658
120729
|
commit: optionalBuildString(""),
|
|
120659
120730
|
buildTarget: optionalBuildString("darwin-arm64")
|
|
@@ -120918,7 +120989,9 @@ const NotificationsConfigSchema = z.object({
|
|
|
120918
120989
|
const TuiLikePreferencesSchema = z.object({
|
|
120919
120990
|
nickname: z.string().optional(),
|
|
120920
120991
|
tone: z.string().optional(),
|
|
120921
|
-
other: z.string().optional()
|
|
120992
|
+
other: z.string().optional(),
|
|
120993
|
+
/** Explicit prohibitions: things the user does NOT want done. */
|
|
120994
|
+
doNot: z.string().optional()
|
|
120922
120995
|
});
|
|
120923
120996
|
const TuiConfigFileSchema = z.object({
|
|
120924
120997
|
theme: TuiThemeSchema.optional(),
|
|
@@ -123307,7 +123380,7 @@ function mountProfileList(host) {
|
|
|
123307
123380
|
const { subagentModels: bindings, availableModels } = host.state.appState;
|
|
123308
123381
|
const options = getSubagentProfiles().map((profile) => {
|
|
123309
123382
|
const alias = bindings[profile.name];
|
|
123310
|
-
const bindingLabel = alias === void 0 ? t("subagent.follow_main") : modelDisplayName$1(alias, availableModels[alias]);
|
|
123383
|
+
const bindingLabel = alias === void 0 ? t("subagent.follow_main") : availableModels[alias] !== void 0 ? modelDisplayName$1(alias, availableModels[alias]) : t("subagent.stale_binding", { alias });
|
|
123311
123384
|
return {
|
|
123312
123385
|
value: profile.name,
|
|
123313
123386
|
label: `${profile.name} → ${bindingLabel}`,
|
|
@@ -123361,6 +123434,10 @@ async function applyBinding(host, profileName, value) {
|
|
|
123361
123434
|
const configPath = getTuiConfigPath();
|
|
123362
123435
|
try {
|
|
123363
123436
|
const current = await loadTuiConfig(configPath);
|
|
123437
|
+
if (value !== FOLLOW_MAIN && host.state.appState.availableModels[value] === void 0) {
|
|
123438
|
+
host.showError(t("subagent.invalid_alias", { alias: value }));
|
|
123439
|
+
return;
|
|
123440
|
+
}
|
|
123364
123441
|
const updated = { ...current.subagentModels };
|
|
123365
123442
|
if (value === FOLLOW_MAIN) delete updated[profileName];
|
|
123366
123443
|
else updated[profileName] = value;
|
|
@@ -123873,6 +123950,11 @@ function safeUsage(usage) {
|
|
|
123873
123950
|
const CONTEXT_BAR_WIDTH = 10;
|
|
123874
123951
|
const CONTEXT_BAR_FILLED = "▰";
|
|
123875
123952
|
const CONTEXT_BAR_EMPTY = "▱";
|
|
123953
|
+
function currencySymbol(currency) {
|
|
123954
|
+
if (currency === "CNY") return "¥";
|
|
123955
|
+
if (currency === "USD") return "$";
|
|
123956
|
+
return `${currency} `;
|
|
123957
|
+
}
|
|
123876
123958
|
/**
|
|
123877
123959
|
* Half-block progress bar for context usage: `▰▰▰▱▱▱▱▱▱▱` (10 cells).
|
|
123878
123960
|
* Filled cells are rounded from the clamped ratio, so 0% is all-empty and
|
|
@@ -124094,8 +124176,12 @@ var FooterComponent = class {
|
|
|
124094
124176
|
left.push(chalk.hex(colors.primary).bold(goalLabel));
|
|
124095
124177
|
}
|
|
124096
124178
|
const model = shortenModel(modelDisplayName(state));
|
|
124097
|
-
if (model)
|
|
124098
|
-
|
|
124179
|
+
if (model) {
|
|
124180
|
+
if (state.streamingPhase === "thinking") left.push(shimmerText(model, colors));
|
|
124181
|
+
else left.push(chalk.hex(colors.textDim)(model));
|
|
124182
|
+
const balance = state.providerBalance;
|
|
124183
|
+
if (balance !== null && balance !== void 0) left.push(chalk.hex(colors.textDim)(`${currencySymbol(balance.currency)}${balance.totalBalance}`));
|
|
124184
|
+
}
|
|
124099
124185
|
if (this.backgroundBashTaskCount > 0) left.push(chalk.hex(colors.primary)(`[${t("footer.tasks_running", { count: String(this.backgroundBashTaskCount) })}]`));
|
|
124100
124186
|
if (this.backgroundAgentCount > 0) left.push(chalk.hex(colors.primary)(`[${t("footer.agents_running", { count: String(this.backgroundAgentCount) })}]`));
|
|
124101
124187
|
const git = this.gitCache.getStatus();
|
|
@@ -124542,6 +124628,7 @@ function createMarkdownTheme(colors) {
|
|
|
124542
124628
|
quote: (text) => chalk.hex(colors.mdQuote)(text),
|
|
124543
124629
|
quoteBorder: (text) => chalk.hex(colors.mdQuote)(text),
|
|
124544
124630
|
hr: (text) => border(text),
|
|
124631
|
+
tableHeader: (text) => chalk.bold.hex(colors.accent)(text),
|
|
124545
124632
|
listBullet: (text) => chalk.hex(colors.roleAssistant)(text.replace(/^-/, "•")),
|
|
124546
124633
|
bold: (text) => chalk.bold(text),
|
|
124547
124634
|
italic: (text) => chalk.italic(text),
|
|
@@ -124933,6 +125020,84 @@ async function loadManagedUsageReport(host) {
|
|
|
124933
125020
|
} };
|
|
124934
125021
|
}
|
|
124935
125022
|
//#endregion
|
|
125023
|
+
//#region src/tui/api-balance.ts
|
|
125024
|
+
/**
|
|
125025
|
+
* TUI-side provider balance lookup.
|
|
125026
|
+
*
|
|
125027
|
+
* Reads the runtime config.toml (same file the engine consumes), resolves
|
|
125028
|
+
* the plaintext API key (direct value or the provider's ENV_VAR env
|
|
125029
|
+
* reference), and delegates the actual query to the engine's
|
|
125030
|
+
* fetchProviderBalance. Results are cached briefly so footer renders do
|
|
125031
|
+
* not hammer the vendor endpoint.
|
|
125032
|
+
*/
|
|
125033
|
+
const BALANCE_CACHE_MS = 6e4;
|
|
125034
|
+
const cache = /* @__PURE__ */ new Map();
|
|
125035
|
+
/** Monotonic id so an out-of-order lookup can never overwrite a newer one. */
|
|
125036
|
+
let latestRequestId = 0;
|
|
125037
|
+
function resolveApiKey(providerName) {
|
|
125038
|
+
const provider = readConfigFile(join(getDataDir(), "config.toml")).providers?.[providerName];
|
|
125039
|
+
if (!provider) return void 0;
|
|
125040
|
+
const direct = provider.apiKey?.trim();
|
|
125041
|
+
if (direct !== void 0 && direct.length > 0) return direct;
|
|
125042
|
+
const envKey = envKeyForProviderType(provider.type);
|
|
125043
|
+
const stored = envKey !== void 0 ? provider.env?.[envKey]?.trim() : void 0;
|
|
125044
|
+
return stored !== void 0 && stored.length > 0 ? stored : void 0;
|
|
125045
|
+
}
|
|
125046
|
+
function envKeyForProviderType(type) {
|
|
125047
|
+
switch (type) {
|
|
125048
|
+
case "anthropic": return "ANTHROPIC_API_KEY";
|
|
125049
|
+
case "openai":
|
|
125050
|
+
case "openai_responses": return "OPENAI_API_KEY";
|
|
125051
|
+
case "scream": return "SCREAM_API_KEY";
|
|
125052
|
+
case "google-genai": return "GOOGLE_API_KEY";
|
|
125053
|
+
case "vertexai": return "VERTEXAI_API_KEY";
|
|
125054
|
+
default: return;
|
|
125055
|
+
}
|
|
125056
|
+
}
|
|
125057
|
+
async function loadBalance(providerName) {
|
|
125058
|
+
try {
|
|
125059
|
+
const provider = readConfigFile(join(getDataDir(), "config.toml")).providers?.[providerName];
|
|
125060
|
+
if (!provider?.baseUrl) return null;
|
|
125061
|
+
const apiKey = resolveApiKey(providerName);
|
|
125062
|
+
if (apiKey === void 0) return null;
|
|
125063
|
+
return await fetchProviderBalance(provider.baseUrl, apiKey);
|
|
125064
|
+
} catch {
|
|
125065
|
+
return null;
|
|
125066
|
+
}
|
|
125067
|
+
}
|
|
125068
|
+
/**
|
|
125069
|
+
* Look up the balance for the provider that serves the given model
|
|
125070
|
+
* (model names follow the "provider/model" convention). Returns null when
|
|
125071
|
+
* the provider is unknown, unofficial, or the lookup failed — callers
|
|
125072
|
+
* render nothing in that case. Cached for BALANCE_CACHE_MS per provider.
|
|
125073
|
+
*/
|
|
125074
|
+
async function getProviderBalanceForModel(model) {
|
|
125075
|
+
const providerName = model.split("/")[0] ?? "";
|
|
125076
|
+
if (providerName.length === 0) return null;
|
|
125077
|
+
const cached = cache.get(providerName);
|
|
125078
|
+
if (cached !== void 0 && Date.now() - cached.at < BALANCE_CACHE_MS) return cached.balance;
|
|
125079
|
+
const balance = await loadBalance(providerName);
|
|
125080
|
+
cache.set(providerName, {
|
|
125081
|
+
balance,
|
|
125082
|
+
at: Date.now()
|
|
125083
|
+
});
|
|
125084
|
+
return balance;
|
|
125085
|
+
}
|
|
125086
|
+
/**
|
|
125087
|
+
* Fetch the balance for a model and push it into app state. Fire-and-forget:
|
|
125088
|
+
* failures resolve to null inside getProviderBalanceForModel, so callers
|
|
125089
|
+
* (startup sync and model switches) never await it. A request id guards
|
|
125090
|
+
* against out-of-order resolutions: when the user switches models quickly,
|
|
125091
|
+
* only the latest lookup's result is committed.
|
|
125092
|
+
*/
|
|
125093
|
+
function refreshProviderBalance(model, setAppState) {
|
|
125094
|
+
const requestId = ++latestRequestId;
|
|
125095
|
+
getProviderBalanceForModel(model).then((balance) => {
|
|
125096
|
+
if (requestId !== latestRequestId) return;
|
|
125097
|
+
setAppState({ providerBalance: balance });
|
|
125098
|
+
});
|
|
125099
|
+
}
|
|
125100
|
+
//#endregion
|
|
124936
125101
|
//#region src/tui/commands/config.ts
|
|
124937
125102
|
/**
|
|
124938
125103
|
* Storm Breaker guard for model switches. Returns the (currentTokens,
|
|
@@ -125359,8 +125524,10 @@ async function performModelSwitch(host, alias, thinkingLevel) {
|
|
|
125359
125524
|
}
|
|
125360
125525
|
host.setAppState({
|
|
125361
125526
|
model: effectiveAlias,
|
|
125362
|
-
thinkingLevel: effectiveThinking
|
|
125527
|
+
thinkingLevel: effectiveThinking,
|
|
125528
|
+
providerBalance: null
|
|
125363
125529
|
});
|
|
125530
|
+
refreshProviderBalance(effectiveAlias, (patch) => host.setAppState(patch));
|
|
125364
125531
|
let persisted = false;
|
|
125365
125532
|
try {
|
|
125366
125533
|
persisted = await persistModelSelection(host, alias, thinkingLevel);
|
|
@@ -126195,7 +126362,7 @@ async function guidedGoalSetup(host) {
|
|
|
126195
126362
|
host.showNotice(t("goal.storm_breaker"), t("goal.conflict_loop"));
|
|
126196
126363
|
return;
|
|
126197
126364
|
}
|
|
126198
|
-
const { TextInputDialogComponent } = await import("./text-input-dialog-
|
|
126365
|
+
const { TextInputDialogComponent } = await import("./text-input-dialog-DX3hKoBF.mjs");
|
|
126199
126366
|
const initialDesc = await promptText(host, TextInputDialogComponent, {
|
|
126200
126367
|
title: t("goal.setup_title_initial"),
|
|
126201
126368
|
subtitle: t("goal.setup_desc_hint"),
|
|
@@ -126216,7 +126383,7 @@ async function guidedGoalSetup(host) {
|
|
|
126216
126383
|
await showGoalConfigWizard(host, session, confirmed.trim() || objective, false);
|
|
126217
126384
|
}
|
|
126218
126385
|
async function showGoalConfigWizard(host, session, objective, replace) {
|
|
126219
|
-
const { TextInputDialogComponent } = await import("./text-input-dialog-
|
|
126386
|
+
const { TextInputDialogComponent } = await import("./text-input-dialog-DX3hKoBF.mjs");
|
|
126220
126387
|
const turnInput = await promptNumber(host, TextInputDialogComponent, {
|
|
126221
126388
|
title: t("goal.wizard_title", { objective }),
|
|
126222
126389
|
subtitle: t("goal.budget_turns_hint"),
|
|
@@ -132617,8 +132784,11 @@ function buildRoleAdditionalText(prefs) {
|
|
|
132617
132784
|
if (prefs.nickname !== void 0 && prefs.nickname.trim().length > 0) items.push(`- Nickname: address the user as "${prefs.nickname.trim()}".`);
|
|
132618
132785
|
if (prefs.tone !== void 0 && prefs.tone.trim().length > 0) items.push(`- Tone: respond in ${prefs.tone.trim()} tone.`);
|
|
132619
132786
|
if (prefs.other !== void 0 && prefs.other.trim().length > 0) items.push(`- Other: ${prefs.other.trim()}`);
|
|
132620
|
-
|
|
132621
|
-
|
|
132787
|
+
const doNot = prefs.doNot?.trim();
|
|
132788
|
+
if (items.length === 0 && (doNot === void 0 || doNot.length === 0)) return "";
|
|
132789
|
+
lines.push("", ...items);
|
|
132790
|
+
if (doNot !== void 0 && doNot.length > 0) lines.push("", "## Do NOT (explicit prohibitions — NEVER do these)", doNot);
|
|
132791
|
+
lines.push("", t("like.priority"));
|
|
132622
132792
|
return lines.join("\n");
|
|
132623
132793
|
}
|
|
132624
132794
|
async function getUserPrefsPath() {
|
|
@@ -132626,12 +132796,23 @@ async function getUserPrefsPath() {
|
|
|
132626
132796
|
}
|
|
132627
132797
|
async function persistLikePreferences(host, prefs) {
|
|
132628
132798
|
const configPath = getTuiConfigPath();
|
|
132629
|
-
await
|
|
132630
|
-
|
|
132799
|
+
const current = await loadTuiConfig(configPath);
|
|
132800
|
+
const updated = {
|
|
132801
|
+
...current,
|
|
132631
132802
|
like: prefs
|
|
132632
|
-
}
|
|
132633
|
-
|
|
132634
|
-
|
|
132803
|
+
};
|
|
132804
|
+
try {
|
|
132805
|
+
await saveTuiConfig(updated, configPath);
|
|
132806
|
+
await writeFile(await getUserPrefsPath(), buildRoleAdditionalText(prefs), "utf-8");
|
|
132807
|
+
} catch (error) {
|
|
132808
|
+
try {
|
|
132809
|
+
await saveTuiConfig(current, configPath);
|
|
132810
|
+
} catch {}
|
|
132811
|
+
try {
|
|
132812
|
+
await writeFile(await getUserPrefsPath(), buildRoleAdditionalText(current.like ?? {}), "utf-8");
|
|
132813
|
+
} catch {}
|
|
132814
|
+
throw error;
|
|
132815
|
+
}
|
|
132635
132816
|
host.setAppState({ like: prefs });
|
|
132636
132817
|
}
|
|
132637
132818
|
async function handleLikeCommand(host) {
|
|
@@ -132666,10 +132847,21 @@ async function handleLikeCommand(host) {
|
|
|
132666
132847
|
host.showStatus(t("like.cancelled"), host.state.theme.colors.textDim);
|
|
132667
132848
|
return;
|
|
132668
132849
|
}
|
|
132850
|
+
const doNot = await promptTextInput$1(host, t("like.do_not"), {
|
|
132851
|
+
subtitle: t("like.do_not_hint"),
|
|
132852
|
+
placeholder: t("like.do_not_example"),
|
|
132853
|
+
initialValue: current.doNot,
|
|
132854
|
+
allowEmpty: true
|
|
132855
|
+
});
|
|
132856
|
+
if (doNot === void 0) {
|
|
132857
|
+
host.showStatus(t("like.cancelled"), host.state.theme.colors.textDim);
|
|
132858
|
+
return;
|
|
132859
|
+
}
|
|
132669
132860
|
await persistLikePreferences(host, {
|
|
132670
132861
|
nickname: nickname.trim().length > 0 ? nickname.trim() : void 0,
|
|
132671
132862
|
tone: tone.trim().length > 0 ? tone.trim() : void 0,
|
|
132672
|
-
other: other.trim().length > 0 ? other.trim() : void 0
|
|
132863
|
+
other: other.trim().length > 0 ? other.trim() : void 0,
|
|
132864
|
+
doNot: doNot.trim().length > 0 ? doNot.trim() : void 0
|
|
132673
132865
|
});
|
|
132674
132866
|
host.showStatus(t("like.saved"), host.state.theme.colors.success);
|
|
132675
132867
|
}
|
|
@@ -142967,8 +143159,10 @@ var SessionManager$1 = class {
|
|
|
142967
143159
|
wallClockBaseAt: Date.now()
|
|
142968
143160
|
} : null,
|
|
142969
143161
|
goalActive: goal?.status === "active",
|
|
142970
|
-
goalContinuationCount: 0
|
|
143162
|
+
goalContinuationCount: 0,
|
|
143163
|
+
providerBalance: null
|
|
142971
143164
|
});
|
|
143165
|
+
refreshProviderBalance(status.model ?? "", (patch) => this.host.setAppState(patch));
|
|
142972
143166
|
}
|
|
142973
143167
|
async activateRuntime() {
|
|
142974
143168
|
const session = this.requireSession();
|
|
@@ -143815,6 +144009,8 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143815
144009
|
searchQuery = "";
|
|
143816
144010
|
isSearching = false;
|
|
143817
144011
|
searchInput = "";
|
|
144012
|
+
/** Memo ids ticked for batch delete (space toggles, a selects all). */
|
|
144013
|
+
selectedIds = /* @__PURE__ */ new Set();
|
|
143818
144014
|
memos;
|
|
143819
144015
|
total;
|
|
143820
144016
|
loading;
|
|
@@ -143843,6 +144039,7 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143843
144039
|
this.memos = result.memos;
|
|
143844
144040
|
this.total = result.total;
|
|
143845
144041
|
this.selectedIndex = 0;
|
|
144042
|
+
this.selectedIds.clear();
|
|
143846
144043
|
} catch {
|
|
143847
144044
|
this.memos = [];
|
|
143848
144045
|
this.total = 0;
|
|
@@ -143874,8 +144071,11 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143874
144071
|
}
|
|
143875
144072
|
if (this.mode === "confirmDelete") {
|
|
143876
144073
|
if (matchesKey(data, Key.enter)) {
|
|
143877
|
-
|
|
143878
|
-
|
|
144074
|
+
if (this.selectedIds.size > 0) this.deleteSelectedAndReload();
|
|
144075
|
+
else {
|
|
144076
|
+
const memo = this.memos[this.selectedIndex];
|
|
144077
|
+
if (memo) this.deleteAndReload(memo.id);
|
|
144078
|
+
}
|
|
143879
144079
|
return;
|
|
143880
144080
|
}
|
|
143881
144081
|
if (matchesKey(data, Key.escape)) {
|
|
@@ -143922,7 +144122,23 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143922
144122
|
return;
|
|
143923
144123
|
}
|
|
143924
144124
|
if (ch === "d" || ch === "D") {
|
|
143925
|
-
if (this.memos.length > 0) this.mode = "confirmDelete";
|
|
144125
|
+
if (this.selectedIds.size > 0 || this.memos.length > 0) this.mode = "confirmDelete";
|
|
144126
|
+
return;
|
|
144127
|
+
}
|
|
144128
|
+
if (ch === " ") {
|
|
144129
|
+
const memo = this.memos[this.selectedIndex];
|
|
144130
|
+
if (memo) {
|
|
144131
|
+
if (this.selectedIds.has(memo.id)) this.selectedIds.delete(memo.id);
|
|
144132
|
+
else this.selectedIds.add(memo.id);
|
|
144133
|
+
this.ui?.requestRender();
|
|
144134
|
+
}
|
|
144135
|
+
return;
|
|
144136
|
+
}
|
|
144137
|
+
if (ch === "a" || ch === "A") {
|
|
144138
|
+
if (this.memos.length === 0) return;
|
|
144139
|
+
if (this.memos.every((memo) => this.selectedIds.has(memo.id))) this.selectedIds.clear();
|
|
144140
|
+
else for (const memo of this.memos) this.selectedIds.add(memo.id);
|
|
144141
|
+
this.ui?.requestRender();
|
|
143926
144142
|
return;
|
|
143927
144143
|
}
|
|
143928
144144
|
if (ch === "/") {
|
|
@@ -143951,6 +144167,15 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143951
144167
|
if (this.selectedIndex >= this.memos.length) this.selectedIndex = Math.max(0, this.memos.length - 1);
|
|
143952
144168
|
this.ui?.requestRender();
|
|
143953
144169
|
}
|
|
144170
|
+
async deleteSelectedAndReload() {
|
|
144171
|
+
const ids = [...this.selectedIds];
|
|
144172
|
+
for (const id of ids) try {
|
|
144173
|
+
await this.store.delete(id);
|
|
144174
|
+
} catch {}
|
|
144175
|
+
await this.loadMemos();
|
|
144176
|
+
this.mode = "list";
|
|
144177
|
+
this.ui?.requestRender();
|
|
144178
|
+
}
|
|
143954
144179
|
render(width) {
|
|
143955
144180
|
const c = this.colors;
|
|
143956
144181
|
const lines = [];
|
|
@@ -143963,7 +144188,7 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143963
144188
|
return lines;
|
|
143964
144189
|
}
|
|
143965
144190
|
const headerLabel = t("memory.notebook_title");
|
|
143966
|
-
const headerHint = this.searchQuery.length > 0 ? t("memory.esc_clear_search") : t("memory.nav_hint");
|
|
144191
|
+
const headerHint = this.searchQuery.length > 0 ? t("memory.esc_clear_search") : this.selectedIds.size > 0 ? t("memory.batch_hint", { count: String(this.selectedIds.size) }) : t("memory.nav_hint");
|
|
143967
144192
|
const labelWidth = visibleWidth(headerLabel);
|
|
143968
144193
|
const shownHint = truncateToWidth(headerHint, Math.max(0, width - labelWidth), ELLIPSIS$1);
|
|
143969
144194
|
lines.push(chalk.hex(c.primary).bold(headerLabel) + chalk.hex(c.textMuted)(shownHint));
|
|
@@ -143984,10 +144209,15 @@ var MemoryPickerComponent = class extends Container {
|
|
|
143984
144209
|
}
|
|
143985
144210
|
if (this.mode === "detail" && this.detailMemo) return this.renderDetail(lines, width, c);
|
|
143986
144211
|
if (this.mode === "confirmDelete") {
|
|
143987
|
-
|
|
143988
|
-
|
|
143989
|
-
lines.push(
|
|
143990
|
-
|
|
144212
|
+
if (this.selectedIds.size > 0) {
|
|
144213
|
+
lines.push(truncateToWidth(chalk.hex(c.warning).bold(t("memory.batch_delete_confirm", { count: String(this.selectedIds.size) })), width, ELLIPSIS$1));
|
|
144214
|
+
lines.push(chalk.hex(c.warning)(t("memory.batch_delete_hint")));
|
|
144215
|
+
} else {
|
|
144216
|
+
const memo = this.memos[this.selectedIndex];
|
|
144217
|
+
if (memo) {
|
|
144218
|
+
lines.push(truncateToWidth(chalk.hex(c.warning).bold(` ${t("memory.deleting")}${memo.userNeed}`), width, ELLIPSIS$1));
|
|
144219
|
+
lines.push(chalk.hex(c.warning)(t("memory.delete_confirm_hint")));
|
|
144220
|
+
}
|
|
143991
144221
|
}
|
|
143992
144222
|
lines.push(chalk.hex(c.primary)("─".repeat(width)));
|
|
143993
144223
|
return lines;
|
|
@@ -144015,6 +144245,7 @@ var MemoryPickerComponent = class extends Container {
|
|
|
144015
144245
|
renderMemoCard(width, memo, isSelected) {
|
|
144016
144246
|
const c = this.colors;
|
|
144017
144247
|
const pointer = isSelected ? "❯" : " ";
|
|
144248
|
+
const check = this.selectedIds.has(memo.id) ? "☑" : "□";
|
|
144018
144249
|
const indent = " ";
|
|
144019
144250
|
const indentWidth = visibleWidth(indent);
|
|
144020
144251
|
const titleColor = isSelected ? c.primary : c.text;
|
|
@@ -144022,10 +144253,12 @@ var MemoryPickerComponent = class extends Container {
|
|
|
144022
144253
|
const trailingParts = [formatRelativeTime$1(memo.recordedAt), sourceLabel(memo.extractionSource)].filter((p) => p.length > 0);
|
|
144023
144254
|
const trailingText = trailingParts.length > 0 ? " " + trailingParts.join(" ") : "";
|
|
144024
144255
|
const trailingWidth = visibleWidth(trailingText);
|
|
144025
|
-
const headerPrefixWidth = visibleWidth(pointer) + 1;
|
|
144256
|
+
const headerPrefixWidth = visibleWidth(pointer) + 1 + visibleWidth(check) + 1;
|
|
144026
144257
|
const titleBudget = Math.max(8, width - headerPrefixWidth - trailingWidth);
|
|
144027
144258
|
const shownTitle = truncateToWidth(singleLine$1(memo.userNeed), titleBudget, ELLIPSIS$1);
|
|
144259
|
+
const checkColor = this.selectedIds.has(memo.id) ? c.primary : c.textDim;
|
|
144028
144260
|
let header = chalk.hex(isSelected ? c.primary : c.textDim)(pointer + " ");
|
|
144261
|
+
header += chalk.hex(checkColor)(check + " ");
|
|
144029
144262
|
header += titleStyle(shownTitle);
|
|
144030
144263
|
if (trailingText.length > 0) header += chalk.hex(c.textDim)(trailingText);
|
|
144031
144264
|
const card = [truncateToWidth(header, width, ELLIPSIS$1)];
|
|
@@ -144162,12 +144395,15 @@ var SessionPickerComponent = class extends Container {
|
|
|
144162
144395
|
onSelect;
|
|
144163
144396
|
onCancel;
|
|
144164
144397
|
onDelete;
|
|
144398
|
+
onDeleteMany;
|
|
144165
144399
|
onStatus;
|
|
144166
144400
|
maxVisibleSessions;
|
|
144167
144401
|
loading;
|
|
144168
144402
|
focused = false;
|
|
144169
144403
|
selectedIndex = 0;
|
|
144170
144404
|
confirmingDelete = false;
|
|
144405
|
+
/** Session ids ticked for batch delete (space toggles, a selects all). */
|
|
144406
|
+
selectedIds = /* @__PURE__ */ new Set();
|
|
144171
144407
|
constructor(opts) {
|
|
144172
144408
|
super();
|
|
144173
144409
|
this.sessions = opts.sessions;
|
|
@@ -144177,6 +144413,7 @@ var SessionPickerComponent = class extends Container {
|
|
|
144177
144413
|
this.onSelect = opts.onSelect;
|
|
144178
144414
|
this.onCancel = opts.onCancel;
|
|
144179
144415
|
this.onDelete = opts.onDelete;
|
|
144416
|
+
this.onDeleteMany = opts.onDeleteMany;
|
|
144180
144417
|
this.onStatus = opts.onStatus;
|
|
144181
144418
|
this.maxVisibleSessions = opts.maxVisibleSessions ?? 4;
|
|
144182
144419
|
}
|
|
@@ -144194,6 +144431,15 @@ var SessionPickerComponent = class extends Container {
|
|
|
144194
144431
|
if (!session) return;
|
|
144195
144432
|
if (this.confirmingDelete) {
|
|
144196
144433
|
this.confirmingDelete = false;
|
|
144434
|
+
if (this.selectedIds.size > 0) {
|
|
144435
|
+
if (this.onDeleteMany === void 0) {
|
|
144436
|
+
this.confirmingDelete = true;
|
|
144437
|
+
this.onStatus(t("session_picker.batch_delete_unavailable"));
|
|
144438
|
+
return;
|
|
144439
|
+
}
|
|
144440
|
+
this.onDeleteMany?.([...this.selectedIds]);
|
|
144441
|
+
return;
|
|
144442
|
+
}
|
|
144197
144443
|
if (session.metadata?.["source"] === "cc-connect") {
|
|
144198
144444
|
this.onStatus(t("session_picker.cc_restricted"));
|
|
144199
144445
|
return;
|
|
@@ -144209,11 +144455,13 @@ var SessionPickerComponent = class extends Container {
|
|
|
144209
144455
|
return;
|
|
144210
144456
|
}
|
|
144211
144457
|
if (matchesKey(data, Key.up)) {
|
|
144458
|
+
if (this.confirmingDelete) return;
|
|
144212
144459
|
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
|
144213
144460
|
this.confirmingDelete = false;
|
|
144214
144461
|
return;
|
|
144215
144462
|
}
|
|
144216
144463
|
if (matchesKey(data, Key.down)) {
|
|
144464
|
+
if (this.confirmingDelete) return;
|
|
144217
144465
|
this.selectedIndex = Math.min(this.sessions.length - 1, this.selectedIndex + 1);
|
|
144218
144466
|
this.confirmingDelete = false;
|
|
144219
144467
|
return;
|
|
@@ -144228,6 +144476,26 @@ var SessionPickerComponent = class extends Container {
|
|
|
144228
144476
|
}
|
|
144229
144477
|
if (session.id !== this.currentSessionId) this.confirmingDelete = true;
|
|
144230
144478
|
}
|
|
144479
|
+
if (k === " " && !this.confirmingDelete) {
|
|
144480
|
+
const session = this.sessions[this.selectedIndex];
|
|
144481
|
+
if (!session || session.id === this.currentSessionId) return;
|
|
144482
|
+
if (session.metadata?.["source"] === "cc-connect") {
|
|
144483
|
+
this.onStatus(t("session_picker.cc_restricted"));
|
|
144484
|
+
return;
|
|
144485
|
+
}
|
|
144486
|
+
if (this.selectedIds.has(session.id)) this.selectedIds.delete(session.id);
|
|
144487
|
+
else this.selectedIds.add(session.id);
|
|
144488
|
+
return;
|
|
144489
|
+
}
|
|
144490
|
+
if (k === "a" || k === "A") {
|
|
144491
|
+
if (this.confirmingDelete) return;
|
|
144492
|
+
if (this.sessions.length === 0) return;
|
|
144493
|
+
const selectable = this.sessions.filter((s) => s.id !== this.currentSessionId && s.metadata?.["source"] !== "cc-connect");
|
|
144494
|
+
if (selectable.length === 0) return;
|
|
144495
|
+
if (selectable.every((s) => this.selectedIds.has(s.id))) this.selectedIds.clear();
|
|
144496
|
+
else for (const s of selectable) this.selectedIds.add(s.id);
|
|
144497
|
+
return;
|
|
144498
|
+
}
|
|
144231
144499
|
}
|
|
144232
144500
|
render(width) {
|
|
144233
144501
|
const colors = this.colors;
|
|
@@ -144245,7 +144513,7 @@ var SessionPickerComponent = class extends Container {
|
|
|
144245
144513
|
return lines;
|
|
144246
144514
|
}
|
|
144247
144515
|
const headerLabel = t("session.picker_title");
|
|
144248
|
-
const headerHint = this.confirmingDelete ? t("session.delete_confirm") : t("session.picker_hint");
|
|
144516
|
+
const headerHint = this.confirmingDelete ? this.selectedIds.size > 0 ? t("session_picker.batch_delete_confirm", { count: String(this.selectedIds.size) }) : t("session.delete_confirm") : this.selectedIds.size > 0 ? t("session_picker.batch_hint", { count: String(this.selectedIds.size) }) : t("session.picker_hint");
|
|
144249
144517
|
const labelWidth = visibleWidth(headerLabel);
|
|
144250
144518
|
const shownHint = truncateToWidth(headerHint, Math.max(0, width - labelWidth), ELLIPSIS);
|
|
144251
144519
|
const hintColor = this.confirmingDelete ? colors.warning : colors.textMuted;
|
|
@@ -144271,6 +144539,7 @@ var SessionPickerComponent = class extends Container {
|
|
|
144271
144539
|
renderSessionCard(width, session, isSelected, isCurrent) {
|
|
144272
144540
|
const colors = this.colors;
|
|
144273
144541
|
const pointer = isSelected ? "❯" : " ";
|
|
144542
|
+
const check = this.selectedIds.has(session.id) ? "☑" : "□";
|
|
144274
144543
|
const indent = " ";
|
|
144275
144544
|
const indentWidth = visibleWidth(indent);
|
|
144276
144545
|
const titleColor = isSelected ? colors.primary : colors.text;
|
|
@@ -144284,14 +144553,16 @@ var SessionPickerComponent = class extends Container {
|
|
|
144284
144553
|
});
|
|
144285
144554
|
const trailingParts = [time, badge].filter((p) => p.length > 0);
|
|
144286
144555
|
const trailingWidth = visibleWidth(trailingParts.length > 0 ? " " + trailingParts.join(" ") : "");
|
|
144287
|
-
const headerPrefixWidth = visibleWidth(pointer) + 1;
|
|
144556
|
+
const headerPrefixWidth = visibleWidth(pointer) + 1 + visibleWidth(check) + 1;
|
|
144288
144557
|
const titleBudget = Math.max(8, width - headerPrefixWidth - trailingWidth);
|
|
144289
144558
|
const shownTitle = truncateToWidth(singleLine(titleSource), titleBudget, ELLIPSIS);
|
|
144559
|
+
const checkColor = this.selectedIds.has(session.id) ? colors.primary : colors.textDim;
|
|
144290
144560
|
let header = chalk.hex(isSelected ? colors.primary : colors.textDim)(pointer + " ");
|
|
144561
|
+
header += chalk.hex(checkColor)(check + " ");
|
|
144291
144562
|
header += titleStyle(shownTitle);
|
|
144292
144563
|
if (time.length > 0) header += " " + chalk.hex(colors.textDim)(time);
|
|
144293
144564
|
if (badge.length > 0) header += " " + chalk.hex(colors.success)(badge);
|
|
144294
|
-
const card = [header];
|
|
144565
|
+
const card = [truncateToWidth(header, width)];
|
|
144295
144566
|
const fullId = session.id;
|
|
144296
144567
|
const idWidth = visibleWidth(fullId);
|
|
144297
144568
|
const metaGap = " ";
|
|
@@ -145036,6 +145307,27 @@ var DialogManager = class {
|
|
|
145036
145307
|
}).catch((error) => {
|
|
145037
145308
|
this.host.showError(error instanceof Error ? error.message : String(error));
|
|
145038
145309
|
});
|
|
145310
|
+
},
|
|
145311
|
+
onDeleteMany: (sessionIds) => {
|
|
145312
|
+
const ccIds = new Set(this.host.getSessions().filter((s) => s.metadata?.["source"] === "cc-connect").map((s) => s.id));
|
|
145313
|
+
const deletable = sessionIds.filter((id) => !ccIds.has(id));
|
|
145314
|
+
if (deletable.length === 0) {
|
|
145315
|
+
this.host.showStatus(t("dialog.cc_managed"));
|
|
145316
|
+
return;
|
|
145317
|
+
}
|
|
145318
|
+
(async () => {
|
|
145319
|
+
for (const id of deletable) try {
|
|
145320
|
+
await this.host.deleteSession(id);
|
|
145321
|
+
} catch (error) {
|
|
145322
|
+
this.host.showError(error instanceof Error ? error.message : String(error));
|
|
145323
|
+
break;
|
|
145324
|
+
}
|
|
145325
|
+
await this.host.fetchSessions();
|
|
145326
|
+
if (this.host.getSessions().length === 0) this.hideSessionPicker();
|
|
145327
|
+
else if (this.host.state.activeDialog === "session-picker") this.mountSessionPicker(onCancel);
|
|
145328
|
+
})().catch((error) => {
|
|
145329
|
+
this.host.showError(error instanceof Error ? error.message : String(error));
|
|
145330
|
+
});
|
|
145039
145331
|
}
|
|
145040
145332
|
}));
|
|
145041
145333
|
}
|
|
@@ -145170,6 +145462,7 @@ function createInitialAppState(input) {
|
|
|
145170
145462
|
contextUsage: 0,
|
|
145171
145463
|
contextTokens: 0,
|
|
145172
145464
|
maxContextTokens: 0,
|
|
145465
|
+
providerBalance: null,
|
|
145173
145466
|
isCompacting: false,
|
|
145174
145467
|
lastCompactionFinishedAt: void 0,
|
|
145175
145468
|
autoCompactionCount: 0,
|
package/dist/main.mjs
CHANGED
|
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
|
|
|
6
6
|
import "./suppress-sqlite-warning-C2VB0doZ.mjs";
|
|
7
7
|
//#region src/main.ts
|
|
8
8
|
try {
|
|
9
|
-
(await import("./app-
|
|
9
|
+
(await import("./app-zSNn5qdo.mjs")).main();
|
|
10
10
|
} catch (error) {
|
|
11
11
|
process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
|
|
12
12
|
process.exit(1);
|
|
@@ -3,5 +3,5 @@ import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
|
|
|
3
3
|
import { dirname as __cjsShimDirname } from 'node:path';
|
|
4
4
|
const __filename = __cjsShimFileURLToPath(import.meta.url);
|
|
5
5
|
const __dirname = __cjsShimDirname(__filename);
|
|
6
|
-
import { t as TextInputDialogComponent } from "./text-input-dialog-
|
|
6
|
+
import { t as TextInputDialogComponent } from "./text-input-dialog-DYHGTG6m.mjs";
|
|
7
7
|
export { TextInputDialogComponent };
|
|
@@ -431,6 +431,9 @@ const dictionaries = {
|
|
|
431
431
|
"like.other": "其他偏好",
|
|
432
432
|
"like.other_hint": "例如:多说例子、先给结论再展开、避免术语等(留空表示不设置)",
|
|
433
433
|
"like.other_example": "例如:请用中文回答,避免缩写",
|
|
434
|
+
"like.do_not": "用户禁止",
|
|
435
|
+
"like.do_not_hint": "用户明确不让做的事。Agent 绝不能做这些。",
|
|
436
|
+
"like.do_not_example": "例如:未经询问绝不修改用户的配置文件",
|
|
434
437
|
"like.cancelled": "已取消 /like 设置",
|
|
435
438
|
"like.saved": "偏好已保存(下次新会话生效)",
|
|
436
439
|
"revoke.streaming": "无法在 streaming 中撤回 — 请先按 Esc 或 Ctrl-C 取消。",
|
|
@@ -470,9 +473,12 @@ const dictionaries = {
|
|
|
470
473
|
"session.loading": "正在加载会话...",
|
|
471
474
|
"session_picker.empty": "未找到会话。按 Escape 关闭。",
|
|
472
475
|
"session_picker.cc_restricted": "CC专属会话不支持切换或删除,请点击或复制下方文件路径进入手动管理",
|
|
476
|
+
"session_picker.batch_delete_confirm": "删除选中的 {count} 个会话?",
|
|
477
|
+
"session_picker.batch_delete_unavailable": "此处不支持批量删除。",
|
|
478
|
+
"session_picker.batch_hint": "[空格] 选择 · [a] 全选 · [d] 删除选中({count})",
|
|
473
479
|
"session.picker_title": "会话 ",
|
|
474
480
|
"session.delete_confirm": "⚠️ 按 Enter 确认删除,Esc 取消",
|
|
475
|
-
"session.picker_hint": "(↑↓ 导航,Enter
|
|
481
|
+
"session.picker_hint": "(↑↓ 导航,Enter 打开,空格 标记,a 全选,d 删除,Esc 取消)",
|
|
476
482
|
"model.nav_model": "↑↓ 模型",
|
|
477
483
|
"model.nav_thinking": "←→ 思考等级",
|
|
478
484
|
"model.nav_page": "PgUp/PgDn 翻页",
|
|
@@ -535,13 +541,16 @@ const dictionaries = {
|
|
|
535
541
|
"memory.search_label": "搜索: ",
|
|
536
542
|
"memory.notebook_title": "记忆备忘录 ",
|
|
537
543
|
"memory.esc_clear_search": "(Esc 清除搜索)",
|
|
538
|
-
"memory.nav_hint": "(↑↓ 导航,Enter
|
|
544
|
+
"memory.nav_hint": "(↑↓ 导航,Enter 查看,空格 标记,a 全选,i 注入,d 删除,/ 搜索,Esc 关闭)",
|
|
539
545
|
"memory.loading": "正在加载...",
|
|
540
546
|
"memory.no_match": "未找到匹配 \"{query}\" 的记忆。",
|
|
541
547
|
"memory.empty": "暂无记忆备忘录。",
|
|
542
548
|
"memory.auto_extract_hint": " 压缩对话或退出会话时,系统会自动提取并保存。",
|
|
543
549
|
"memory.deleting": "删除: ",
|
|
544
550
|
"memory.delete_confirm_hint": " 按 Enter 确认删除,Esc 取消",
|
|
551
|
+
"memory.batch_delete_confirm": "删除选中的 {count} 条记忆?",
|
|
552
|
+
"memory.batch_delete_hint": " 按 Enter 确认批量删除,Esc 取消",
|
|
553
|
+
"memory.batch_hint": "已选 {count} 条 · [空格] 选择 · [a] 全选 · [d] 删除选中",
|
|
545
554
|
"memory.showing_range": "{start}-{end} / {total} 条",
|
|
546
555
|
"memory.id_label": "ID: ",
|
|
547
556
|
"memory.source_label": "来源: ",
|
|
@@ -724,6 +733,8 @@ const dictionaries = {
|
|
|
724
733
|
"subagent.bind_title": "绑定 {profile}",
|
|
725
734
|
"subagent.model_hint": "↑↓ 选择模型 · Enter 确认 · Esc 返回",
|
|
726
735
|
"subagent.save_failed": "保存失败:{msg}",
|
|
736
|
+
"subagent.stale_binding": "{alias}(已失效)",
|
|
737
|
+
"subagent.invalid_alias": "模型别名 {alias} 不存在",
|
|
727
738
|
"kdoctree.no_title": "(无标题)",
|
|
728
739
|
"kdoctree.empty": "(空)",
|
|
729
740
|
"kdoctree.move": "移动",
|
|
@@ -1468,6 +1479,9 @@ const dictionaries = {
|
|
|
1468
1479
|
"like.other": "Other preferences",
|
|
1469
1480
|
"like.other_hint": "e.g. more examples, conclusion first, avoid jargon (leave empty to skip)",
|
|
1470
1481
|
"like.other_example": "e.g. Answer in English, avoid abbreviations",
|
|
1482
|
+
"like.do_not": "User Prohibitions",
|
|
1483
|
+
"like.do_not_hint": "Things the user explicitly does NOT want done. The agent must NEVER do these.",
|
|
1484
|
+
"like.do_not_example": "e.g. Never modify user config files without asking",
|
|
1471
1485
|
"like.cancelled": "/like setup cancelled",
|
|
1472
1486
|
"like.saved": "Preferences saved (takes effect in next session)",
|
|
1473
1487
|
"revoke.streaming": "Cannot revoke during streaming — press Esc or Ctrl-C to cancel first.",
|
|
@@ -1507,9 +1521,12 @@ const dictionaries = {
|
|
|
1507
1521
|
"session.loading": "Loading sessions...",
|
|
1508
1522
|
"session_picker.empty": "No sessions found. Press Escape to close.",
|
|
1509
1523
|
"session_picker.cc_restricted": "CC sessions cannot be switched or deleted. Use the file path below to manage manually",
|
|
1524
|
+
"session_picker.batch_delete_confirm": "Delete {count} selected sessions?",
|
|
1525
|
+
"session_picker.batch_delete_unavailable": "Batch delete is not available here.",
|
|
1526
|
+
"session_picker.batch_hint": "[space] select · [a] all · [d] delete selected ({count})",
|
|
1510
1527
|
"session.picker_title": "Sessions ",
|
|
1511
1528
|
"session.delete_confirm": "⚠️ Press Enter to confirm delete, Esc to cancel",
|
|
1512
|
-
"session.picker_hint": "(↑↓ Navigate, Enter
|
|
1529
|
+
"session.picker_hint": "(↑↓ Navigate, Enter Open, Space Mark, a All, d Delete, Esc Cancel)",
|
|
1513
1530
|
"model.nav_model": "↑↓ Model",
|
|
1514
1531
|
"model.nav_thinking": "←→ Thinking",
|
|
1515
1532
|
"model.nav_page": "PgUp/PgDn Page",
|
|
@@ -1572,13 +1589,16 @@ const dictionaries = {
|
|
|
1572
1589
|
"memory.search_label": "Search: ",
|
|
1573
1590
|
"memory.notebook_title": "Memory Notebook ",
|
|
1574
1591
|
"memory.esc_clear_search": "(Esc clear search)",
|
|
1575
|
-
"memory.nav_hint": "(↑↓ Navigate, Enter View, i Inject, d Delete, / Search, Esc Close)",
|
|
1592
|
+
"memory.nav_hint": "(↑↓ Navigate, Enter View, Space Mark, a All, i Inject, d Delete, / Search, Esc Close)",
|
|
1576
1593
|
"memory.loading": "Loading...",
|
|
1577
1594
|
"memory.no_match": "No memories matching \"{query}\".",
|
|
1578
1595
|
"memory.empty": "No memories yet.",
|
|
1579
1596
|
"memory.auto_extract_hint": " Memories are extracted automatically when compacting or exiting a session.",
|
|
1580
1597
|
"memory.deleting": "Delete: ",
|
|
1581
1598
|
"memory.delete_confirm_hint": " Press Enter to confirm delete, Esc to cancel",
|
|
1599
|
+
"memory.batch_delete_confirm": "Delete {count} selected memos?",
|
|
1600
|
+
"memory.batch_delete_hint": " Press Enter to confirm batch delete, Esc to cancel",
|
|
1601
|
+
"memory.batch_hint": "{count} selected · [space] select · [a] all · [d] delete selected",
|
|
1582
1602
|
"memory.showing_range": "{start}-{end} / {total} items",
|
|
1583
1603
|
"memory.id_label": "ID: ",
|
|
1584
1604
|
"memory.source_label": "Source: ",
|
|
@@ -1761,6 +1781,8 @@ const dictionaries = {
|
|
|
1761
1781
|
"subagent.bind_title": "Bind {profile}",
|
|
1762
1782
|
"subagent.model_hint": "↑↓ Select model · Enter confirm · Esc back",
|
|
1763
1783
|
"subagent.save_failed": "Save failed: {msg}",
|
|
1784
|
+
"subagent.stale_binding": "{alias} (stale)",
|
|
1785
|
+
"subagent.invalid_alias": "Model alias {alias} does not exist",
|
|
1764
1786
|
"kdoctree.no_title": "(untitled)",
|
|
1765
1787
|
"kdoctree.empty": "(empty)",
|
|
1766
1788
|
"kdoctree.move": "Move",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scream-code",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "A terminal-native AI agent for builders",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ScreamCli",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"smoke": "node dist/main.mjs --version"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@liutod-scream/pi-tui": "^0.80.
|
|
62
|
+
"@liutod-scream/pi-tui": "^0.80.32",
|
|
63
63
|
"@mariozechner/clipboard": "^0.3.2",
|
|
64
64
|
"chalk": "^5.4.1",
|
|
65
65
|
"cli-highlight": "^2.1.11",
|