@pensar/apex 0.0.99 → 0.0.100-canary.826dfe3c
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/bin/pensar.js +16 -0
- package/build/auth.js +1 -1
- package/build/index.js +464 -288
- package/package.json +1 -1
package/bin/pensar.js
CHANGED
|
@@ -66,6 +66,13 @@ if (command === "benchmark") {
|
|
|
66
66
|
|
|
67
67
|
// Import and run auth
|
|
68
68
|
await import(authPath);
|
|
69
|
+
} else if (command === "uninstall") {
|
|
70
|
+
// Run uninstall CLI
|
|
71
|
+
const uninstallPath = join(__dirname, "..", "build", "uninstall.js");
|
|
72
|
+
|
|
73
|
+
process.argv = [process.argv[0], uninstallPath, ...args.slice(1)];
|
|
74
|
+
|
|
75
|
+
await import(uninstallPath);
|
|
69
76
|
} else if (command === "upgrade" || command === "update") {
|
|
70
77
|
const currentVersion = getCurrentVersion();
|
|
71
78
|
console.log(`Current version: v${currentVersion}`);
|
|
@@ -89,6 +96,7 @@ if (command === "benchmark") {
|
|
|
89
96
|
console.log();
|
|
90
97
|
console.log("Usage:");
|
|
91
98
|
console.log(" pensar Launch the TUI (Terminal User Interface)");
|
|
99
|
+
console.log(" pensar uninstall Uninstall Pensar (keeps sessions, memories, skills)");
|
|
92
100
|
console.log(" pensar upgrade Update pensar to the latest version");
|
|
93
101
|
console.log(" pensar help Show this help message");
|
|
94
102
|
console.log(" pensar version Show version number");
|
|
@@ -181,6 +189,14 @@ if (command === "benchmark") {
|
|
|
181
189
|
console.log(" pensar auth logout Disconnect from Pensar Console");
|
|
182
190
|
console.log(" pensar auth status Show connection status");
|
|
183
191
|
console.log();
|
|
192
|
+
console.log("Uninstall Usage:");
|
|
193
|
+
console.log(
|
|
194
|
+
" pensar uninstall Fully uninstall Pensar"
|
|
195
|
+
);
|
|
196
|
+
console.log(
|
|
197
|
+
" pensar uninstall --force Skip confirmation prompt"
|
|
198
|
+
);
|
|
199
|
+
console.log();
|
|
184
200
|
console.log("Header Modes (for quicktest, pentest, swarm):");
|
|
185
201
|
console.log(" none No custom headers added to requests");
|
|
186
202
|
console.log(
|
package/build/auth.js
CHANGED
|
@@ -8,7 +8,7 @@ import fs from "fs/promises";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@pensar/apex",
|
|
11
|
-
version: "0.0.
|
|
11
|
+
version: "0.0.100-canary.826dfe3c",
|
|
12
12
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
13
13
|
module: "src/tui/index.tsx",
|
|
14
14
|
main: "build/index.js",
|
package/build/index.js
CHANGED
|
@@ -31880,12 +31880,6 @@ var init_openrouter = __esm(() => {
|
|
|
31880
31880
|
var PENSAR_MODELS;
|
|
31881
31881
|
var init_pensar = __esm(() => {
|
|
31882
31882
|
PENSAR_MODELS = [
|
|
31883
|
-
{
|
|
31884
|
-
id: "pensar:anthropic.claude-opus-4-6-v1",
|
|
31885
|
-
name: "Claude Opus 4.6 (Pensar)",
|
|
31886
|
-
provider: "pensar",
|
|
31887
|
-
contextLength: 200000
|
|
31888
|
-
},
|
|
31889
31883
|
{
|
|
31890
31884
|
id: "pensar:anthropic.claude-sonnet-4-5-20250929-v1:0",
|
|
31891
31885
|
name: "Claude Sonnet 4.5 (Pensar)",
|
|
@@ -31977,7 +31971,7 @@ var package_default2;
|
|
|
31977
31971
|
var init_package = __esm(() => {
|
|
31978
31972
|
package_default2 = {
|
|
31979
31973
|
name: "@pensar/apex",
|
|
31980
|
-
version: "0.0.
|
|
31974
|
+
version: "0.0.100-canary.826dfe3c",
|
|
31981
31975
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
31982
31976
|
module: "src/tui/index.tsx",
|
|
31983
31977
|
main: "build/index.js",
|
|
@@ -193797,6 +193791,19 @@ COMMON SEARCH PATTERNS:
|
|
|
193797
193791
|
execute: async ({ query }) => {
|
|
193798
193792
|
try {
|
|
193799
193793
|
const cfg = await config2.get();
|
|
193794
|
+
const apiUrl = getPensarApiUrl();
|
|
193795
|
+
const body = JSON.stringify({ query });
|
|
193796
|
+
if (cfg.pensarAPIKey && !cfg.accessToken) {
|
|
193797
|
+
const response2 = await fetch(`${apiUrl}/agents/web_search`, {
|
|
193798
|
+
method: "POST",
|
|
193799
|
+
headers: {
|
|
193800
|
+
"Content-Type": "application/json",
|
|
193801
|
+
"x-api-key": cfg.pensarAPIKey
|
|
193802
|
+
},
|
|
193803
|
+
body
|
|
193804
|
+
});
|
|
193805
|
+
return handleSearchResponse(response2);
|
|
193806
|
+
}
|
|
193800
193807
|
const tokenResult = await ensureValidToken({
|
|
193801
193808
|
accessToken: cfg.accessToken,
|
|
193802
193809
|
refreshToken: cfg.refreshToken,
|
|
@@ -193823,8 +193830,6 @@ COMMON SEARCH PATTERNS:
|
|
|
193823
193830
|
error: "Web search requires authentication. Please sign in again to your Pensar account."
|
|
193824
193831
|
};
|
|
193825
193832
|
}
|
|
193826
|
-
const apiUrl = getPensarApiUrl();
|
|
193827
|
-
const body = JSON.stringify({ query });
|
|
193828
193833
|
const { signature, timestamp, nonce } = signGatewayRequest(cfg.gatewaySigningKey, "web_search", body);
|
|
193829
193834
|
const response = await fetch(`${apiUrl}/agents/web_search`, {
|
|
193830
193835
|
method: "POST",
|
|
@@ -193838,40 +193843,7 @@ COMMON SEARCH PATTERNS:
|
|
|
193838
193843
|
},
|
|
193839
193844
|
body
|
|
193840
193845
|
});
|
|
193841
|
-
|
|
193842
|
-
if (response.status === 401) {
|
|
193843
|
-
return {
|
|
193844
|
-
success: false,
|
|
193845
|
-
results: [],
|
|
193846
|
-
error: "Authentication failed. Please sign in again to your Pensar account."
|
|
193847
|
-
};
|
|
193848
|
-
}
|
|
193849
|
-
if (response.status === 429) {
|
|
193850
|
-
return {
|
|
193851
|
-
success: false,
|
|
193852
|
-
results: [],
|
|
193853
|
-
error: "Rate limit exceeded. Please wait a moment before searching again."
|
|
193854
|
-
};
|
|
193855
|
-
}
|
|
193856
|
-
const errorText = await response.text().catch(() => "Unknown error");
|
|
193857
|
-
return {
|
|
193858
|
-
success: false,
|
|
193859
|
-
results: [],
|
|
193860
|
-
error: `Web search failed: ${response.status} ${response.statusText}. ${errorText}`
|
|
193861
|
-
};
|
|
193862
|
-
}
|
|
193863
|
-
const data = await response.json();
|
|
193864
|
-
if (data.error) {
|
|
193865
|
-
return {
|
|
193866
|
-
success: false,
|
|
193867
|
-
results: [],
|
|
193868
|
-
error: data.error
|
|
193869
|
-
};
|
|
193870
|
-
}
|
|
193871
|
-
return {
|
|
193872
|
-
success: true,
|
|
193873
|
-
results: data.results || []
|
|
193874
|
-
};
|
|
193846
|
+
return handleSearchResponse(response);
|
|
193875
193847
|
} catch (error40) {
|
|
193876
193848
|
const errorMsg = error40 instanceof Error ? error40.message : String(error40);
|
|
193877
193849
|
return {
|
|
@@ -193883,6 +193855,42 @@ COMMON SEARCH PATTERNS:
|
|
|
193883
193855
|
}
|
|
193884
193856
|
});
|
|
193885
193857
|
}
|
|
193858
|
+
async function handleSearchResponse(response) {
|
|
193859
|
+
if (!response.ok) {
|
|
193860
|
+
if (response.status === 401) {
|
|
193861
|
+
return {
|
|
193862
|
+
success: false,
|
|
193863
|
+
results: [],
|
|
193864
|
+
error: "Authentication failed. Please sign in again to your Pensar account."
|
|
193865
|
+
};
|
|
193866
|
+
}
|
|
193867
|
+
if (response.status === 429) {
|
|
193868
|
+
return {
|
|
193869
|
+
success: false,
|
|
193870
|
+
results: [],
|
|
193871
|
+
error: "Rate limit exceeded. Please wait a moment before searching again."
|
|
193872
|
+
};
|
|
193873
|
+
}
|
|
193874
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
193875
|
+
return {
|
|
193876
|
+
success: false,
|
|
193877
|
+
results: [],
|
|
193878
|
+
error: `Web search failed: ${response.status} ${response.statusText}. ${errorText}`
|
|
193879
|
+
};
|
|
193880
|
+
}
|
|
193881
|
+
const data = await response.json();
|
|
193882
|
+
if (data.error) {
|
|
193883
|
+
return {
|
|
193884
|
+
success: false,
|
|
193885
|
+
results: [],
|
|
193886
|
+
error: data.error
|
|
193887
|
+
};
|
|
193888
|
+
}
|
|
193889
|
+
return {
|
|
193890
|
+
success: true,
|
|
193891
|
+
results: data.results || []
|
|
193892
|
+
};
|
|
193893
|
+
}
|
|
193886
193894
|
var webSearchInputSchema2;
|
|
193887
193895
|
var init_webSearch = __esm(() => {
|
|
193888
193896
|
init_dist5();
|
|
@@ -194042,7 +194050,7 @@ function createAllTools(ctx4) {
|
|
|
194042
194050
|
get_page: getPage(ctx4)
|
|
194043
194051
|
};
|
|
194044
194052
|
}
|
|
194045
|
-
var ALL_TOOL_NAMES;
|
|
194053
|
+
var ALL_TOOL_NAMES, PLAN_MODE_TOOL_NAMES;
|
|
194046
194054
|
var init_tools = __esm(() => {
|
|
194047
194055
|
init_browserTools();
|
|
194048
194056
|
init_sandboxPlaywright();
|
|
@@ -194151,6 +194159,40 @@ var init_tools = __esm(() => {
|
|
|
194151
194159
|
"web_search",
|
|
194152
194160
|
"get_page"
|
|
194153
194161
|
];
|
|
194162
|
+
PLAN_MODE_TOOL_NAMES = [
|
|
194163
|
+
"browser_navigate",
|
|
194164
|
+
"browser_snapshot",
|
|
194165
|
+
"browser_screenshot",
|
|
194166
|
+
"browser_click",
|
|
194167
|
+
"browser_fill",
|
|
194168
|
+
"browser_evaluate",
|
|
194169
|
+
"browser_console",
|
|
194170
|
+
"browser_get_cookies",
|
|
194171
|
+
"execute_command",
|
|
194172
|
+
"http_request",
|
|
194173
|
+
"read_file",
|
|
194174
|
+
"list_files",
|
|
194175
|
+
"grep",
|
|
194176
|
+
"authenticate_session",
|
|
194177
|
+
"delegate_to_auth_subagent",
|
|
194178
|
+
"create_attack_surface_report",
|
|
194179
|
+
"complete_authentication",
|
|
194180
|
+
"run_attack_surface",
|
|
194181
|
+
"spawn_pentest_swarm",
|
|
194182
|
+
"spawn_coding_agent",
|
|
194183
|
+
"provide_comparison_results",
|
|
194184
|
+
"add_memory",
|
|
194185
|
+
"list_memories",
|
|
194186
|
+
"get_memory",
|
|
194187
|
+
"email_list_inboxes",
|
|
194188
|
+
"email_list_messages",
|
|
194189
|
+
"email_get_message",
|
|
194190
|
+
"email_search_messages",
|
|
194191
|
+
"email_get_attachments",
|
|
194192
|
+
"email_mark_read",
|
|
194193
|
+
"web_search",
|
|
194194
|
+
"get_page"
|
|
194195
|
+
];
|
|
194154
194196
|
});
|
|
194155
194197
|
|
|
194156
194198
|
// src/core/agents/offSecAgent/tools/response.ts
|
|
@@ -194892,7 +194934,11 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194892
194934
|
}
|
|
194893
194935
|
const hasEmail = (input.session.config?.emailIntegration?.inboxes?.length ?? 0) > 0;
|
|
194894
194936
|
const emailToolSet = new Set(EMAIL_TOOL_NAMES);
|
|
194895
|
-
|
|
194937
|
+
let activeTools = hasEmail ? input.activeTools : input.activeTools.filter((t3) => !emailToolSet.has(t3));
|
|
194938
|
+
if (input.mode === "plan") {
|
|
194939
|
+
const planSet = new Set(PLAN_MODE_TOOL_NAMES);
|
|
194940
|
+
activeTools = activeTools.filter((t3) => planSet.has(t3));
|
|
194941
|
+
}
|
|
194896
194942
|
const messagesDir = input.messagesDir ?? input.session.rootPath;
|
|
194897
194943
|
if (!existsSync21(messagesDir)) {
|
|
194898
194944
|
mkdirSync10(messagesDir, { recursive: true });
|
|
@@ -276318,6 +276364,37 @@ var providerOrder = [
|
|
|
276318
276364
|
"bedrock",
|
|
276319
276365
|
"local"
|
|
276320
276366
|
];
|
|
276367
|
+
function setsAreEqual(a, b2) {
|
|
276368
|
+
return a.size === b2.size && [...a].every((value) => b2.has(value));
|
|
276369
|
+
}
|
|
276370
|
+
function PickerRow({
|
|
276371
|
+
children,
|
|
276372
|
+
id,
|
|
276373
|
+
paddingLeft,
|
|
276374
|
+
paddingRight,
|
|
276375
|
+
backgroundColor,
|
|
276376
|
+
flexDirection = "row",
|
|
276377
|
+
gap = 0
|
|
276378
|
+
}) {
|
|
276379
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
276380
|
+
id,
|
|
276381
|
+
width: "100%",
|
|
276382
|
+
overflow: "hidden",
|
|
276383
|
+
flexDirection,
|
|
276384
|
+
paddingLeft,
|
|
276385
|
+
paddingRight,
|
|
276386
|
+
backgroundColor,
|
|
276387
|
+
gap,
|
|
276388
|
+
children
|
|
276389
|
+
}, undefined, false, undefined, this);
|
|
276390
|
+
}
|
|
276391
|
+
function getNavItemId(item) {
|
|
276392
|
+
if (item.type === "provider")
|
|
276393
|
+
return `provider-${item.provider}`;
|
|
276394
|
+
if (item.type === "model")
|
|
276395
|
+
return `model-${item.model.id}`;
|
|
276396
|
+
return `local-input-${item.field}`;
|
|
276397
|
+
}
|
|
276321
276398
|
function ModelPicker({
|
|
276322
276399
|
config: config3,
|
|
276323
276400
|
selectedModel,
|
|
@@ -276328,6 +276405,7 @@ function ModelPicker({
|
|
|
276328
276405
|
isModelUserSelected = false
|
|
276329
276406
|
}) {
|
|
276330
276407
|
const { colors: colors2 } = useTheme();
|
|
276408
|
+
const scrollBoxRef = import_react34.useRef(null);
|
|
276331
276409
|
const [availableModels, setAvailableModels] = import_react34.useState([]);
|
|
276332
276410
|
const [searchQuery, setSearchQuery] = import_react34.useState("");
|
|
276333
276411
|
const [expandedProviders, setExpandedProviders] = import_react34.useState(new Set(["anthropic"]));
|
|
@@ -276340,17 +276418,29 @@ function ModelPicker({
|
|
|
276340
276418
|
setLocalModelName(config3?.localModelName ?? "");
|
|
276341
276419
|
}, [config3?.localModelUrl, config3?.localModelName]);
|
|
276342
276420
|
import_react34.useEffect(() => {
|
|
276343
|
-
if (config3) {
|
|
276344
|
-
|
|
276345
|
-
|
|
276346
|
-
if (models.length > 0) {
|
|
276347
|
-
const currentModel = models.find((m2) => m2.id === selectedModel.id) || models[0];
|
|
276348
|
-
if (currentModel) {
|
|
276349
|
-
setExpandedProviders(new Set([currentModel.provider]));
|
|
276350
|
-
}
|
|
276351
|
-
}
|
|
276421
|
+
if (!config3) {
|
|
276422
|
+
setAvailableModels([]);
|
|
276423
|
+
return;
|
|
276352
276424
|
}
|
|
276353
|
-
|
|
276425
|
+
setAvailableModels(getAvailableModels(config3));
|
|
276426
|
+
}, [config3]);
|
|
276427
|
+
import_react34.useEffect(() => {
|
|
276428
|
+
const availableProviders = new Set(availableModels.map((model) => model.provider));
|
|
276429
|
+
setExpandedProviders((prev) => {
|
|
276430
|
+
if (availableProviders.size === 0) {
|
|
276431
|
+
return prev.size === 0 ? prev : new Set;
|
|
276432
|
+
}
|
|
276433
|
+
const preservedProviders = new Set([...prev].filter((provider) => availableProviders.has(provider)));
|
|
276434
|
+
if (preservedProviders.size > 0) {
|
|
276435
|
+
return setsAreEqual(prev, preservedProviders) ? prev : preservedProviders;
|
|
276436
|
+
}
|
|
276437
|
+
const fallbackProvider = availableProviders.has(selectedModel.provider) ? selectedModel.provider : availableModels[0]?.provider;
|
|
276438
|
+
if (!fallbackProvider) {
|
|
276439
|
+
return prev.size === 0 ? prev : new Set;
|
|
276440
|
+
}
|
|
276441
|
+
return prev.size === 1 && prev.has(fallbackProvider) ? prev : new Set([fallbackProvider]);
|
|
276442
|
+
});
|
|
276443
|
+
}, [availableModels, selectedModel.provider]);
|
|
276354
276444
|
const groupedModels = import_react34.useMemo(() => {
|
|
276355
276445
|
const groups = {};
|
|
276356
276446
|
const query = searchQuery.toLowerCase().trim();
|
|
@@ -276403,6 +276493,12 @@ function ModelPicker({
|
|
|
276403
276493
|
import_react34.useEffect(() => {
|
|
276404
276494
|
setFocusedIndex((prev) => Math.min(prev, Math.max(0, navigationItems.length - 1)));
|
|
276405
276495
|
}, [navigationItems.length]);
|
|
276496
|
+
import_react34.useEffect(() => {
|
|
276497
|
+
const item = navigationItems[focusedIndex];
|
|
276498
|
+
if (!item)
|
|
276499
|
+
return;
|
|
276500
|
+
scrollToChild(scrollBoxRef.current, getNavItemId(item));
|
|
276501
|
+
}, [focusedIndex, navigationItems]);
|
|
276406
276502
|
const commitLocalConfig = import_react34.useCallback((url2, modelName) => {
|
|
276407
276503
|
if (!onConfigUpdate)
|
|
276408
276504
|
return;
|
|
@@ -276510,169 +276606,206 @@ function ModelPicker({
|
|
|
276510
276606
|
useKeyboard((key) => {
|
|
276511
276607
|
handleKeyboard(key);
|
|
276512
276608
|
});
|
|
276609
|
+
const isProviderFocused = (provider) => navigationItems[focusedIndex]?.type === "provider" && navigationItems[focusedIndex].provider === provider;
|
|
276610
|
+
const isModelFocused = (modelId) => navigationItems[focusedIndex]?.type === "model" && navigationItems[focusedIndex].model.id === modelId;
|
|
276611
|
+
const isLocalFieldFocused = (field) => navigationItems[focusedIndex]?.type === "local-input" && navigationItems[focusedIndex].field === field;
|
|
276513
276612
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
276514
276613
|
flexDirection: "column",
|
|
276515
276614
|
gap: 0,
|
|
276615
|
+
width: "100%",
|
|
276616
|
+
flexGrow: 1,
|
|
276617
|
+
flexShrink: 1,
|
|
276618
|
+
overflow: "hidden",
|
|
276516
276619
|
children: [
|
|
276517
|
-
searchQuery ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
276518
|
-
|
|
276519
|
-
|
|
276520
|
-
|
|
276521
|
-
|
|
276522
|
-
|
|
276523
|
-
|
|
276524
|
-
|
|
276525
|
-
|
|
276526
|
-
children:
|
|
276620
|
+
searchQuery ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276621
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276622
|
+
fg: colors2.text,
|
|
276623
|
+
children: [
|
|
276624
|
+
"Search: ",
|
|
276625
|
+
searchQuery
|
|
276626
|
+
]
|
|
276627
|
+
}, undefined, true, undefined, this)
|
|
276628
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276629
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276630
|
+
fg: colors2.textMuted,
|
|
276631
|
+
children: "Type to search models..."
|
|
276632
|
+
}, undefined, false, undefined, this)
|
|
276527
276633
|
}, undefined, false, undefined, this),
|
|
276528
|
-
|
|
276529
|
-
|
|
276530
|
-
|
|
276531
|
-
|
|
276532
|
-
|
|
276533
|
-
|
|
276534
|
-
|
|
276535
|
-
|
|
276536
|
-
|
|
276537
|
-
|
|
276538
|
-
|
|
276539
|
-
|
|
276540
|
-
|
|
276634
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("scrollbox", {
|
|
276635
|
+
ref: scrollBoxRef,
|
|
276636
|
+
style: {
|
|
276637
|
+
rootOptions: {
|
|
276638
|
+
flexGrow: 1,
|
|
276639
|
+
flexShrink: 1,
|
|
276640
|
+
width: "100%",
|
|
276641
|
+
overflow: "hidden"
|
|
276642
|
+
},
|
|
276643
|
+
contentOptions: {
|
|
276644
|
+
flexDirection: "column"
|
|
276645
|
+
},
|
|
276646
|
+
scrollbarOptions: {
|
|
276647
|
+
visible: false
|
|
276648
|
+
}
|
|
276649
|
+
},
|
|
276650
|
+
stickyScroll: false,
|
|
276651
|
+
children: providerOrder.flatMap((provider) => {
|
|
276652
|
+
const isExpanded = expandedProviders.has(provider);
|
|
276653
|
+
const providerName = providerNames[provider] || provider;
|
|
276654
|
+
const isFocused = isProviderFocused(provider);
|
|
276655
|
+
if (provider === "local") {
|
|
276656
|
+
const localModels = groupedModels["local"];
|
|
276657
|
+
const modelCount = localModels?.length ?? 0;
|
|
276658
|
+
const elements2 = [];
|
|
276659
|
+
elements2.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276660
|
+
id: "provider-local",
|
|
276661
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276662
|
+
fg: isFocused ? colors2.primary : isExpanded ? colors2.text : colors2.textMuted,
|
|
276541
276663
|
children: [
|
|
276542
|
-
|
|
276664
|
+
isFocused ? "❯" : isExpanded ? "▾" : "▸",
|
|
276543
276665
|
" ",
|
|
276544
276666
|
providerName,
|
|
276545
276667
|
modelCount > 0 ? ` (${modelCount})` : ""
|
|
276546
276668
|
]
|
|
276547
|
-
}, undefined, true, undefined, this)
|
|
276548
|
-
|
|
276549
|
-
|
|
276550
|
-
|
|
276551
|
-
|
|
276552
|
-
|
|
276553
|
-
|
|
276554
|
-
|
|
276555
|
-
|
|
276556
|
-
|
|
276557
|
-
|
|
276558
|
-
|
|
276559
|
-
|
|
276560
|
-
|
|
276561
|
-
|
|
276562
|
-
|
|
276563
|
-
|
|
276564
|
-
|
|
276565
|
-
|
|
276566
|
-
|
|
276567
|
-
|
|
276568
|
-
|
|
276569
|
-
|
|
276570
|
-
|
|
276571
|
-
|
|
276572
|
-
|
|
276573
|
-
|
|
276574
|
-
|
|
276575
|
-
|
|
276576
|
-
|
|
276577
|
-
|
|
276578
|
-
|
|
276579
|
-
|
|
276580
|
-
|
|
276581
|
-
|
|
276582
|
-
|
|
276583
|
-
|
|
276584
|
-
|
|
276585
|
-
|
|
276586
|
-
|
|
276587
|
-
|
|
276588
|
-
|
|
276589
|
-
|
|
276590
|
-
|
|
276591
|
-
|
|
276592
|
-
|
|
276593
|
-
|
|
276594
|
-
|
|
276595
|
-
|
|
276596
|
-
|
|
276597
|
-
|
|
276598
|
-
|
|
276599
|
-
|
|
276600
|
-
|
|
276601
|
-
|
|
276602
|
-
|
|
276603
|
-
|
|
276604
|
-
|
|
276605
|
-
|
|
276606
|
-
|
|
276607
|
-
|
|
276608
|
-
|
|
276609
|
-
|
|
276610
|
-
|
|
276611
|
-
|
|
276612
|
-
|
|
276613
|
-
|
|
276614
|
-
|
|
276615
|
-
|
|
276616
|
-
|
|
276617
|
-
|
|
276618
|
-
|
|
276619
|
-
|
|
276669
|
+
}, undefined, true, undefined, this)
|
|
276670
|
+
}, "local", false, undefined, this));
|
|
276671
|
+
if (isExpanded) {
|
|
276672
|
+
const isUrlFocused = isLocalFieldFocused("url");
|
|
276673
|
+
const isUrlEditing = editingLocalField === "url";
|
|
276674
|
+
if (isUrlEditing) {
|
|
276675
|
+
elements2.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276676
|
+
id: "local-input-url",
|
|
276677
|
+
paddingLeft: 2,
|
|
276678
|
+
children: [
|
|
276679
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276680
|
+
fg: colors2.primary,
|
|
276681
|
+
children: " URL: "
|
|
276682
|
+
}, undefined, false, undefined, this),
|
|
276683
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
|
|
276684
|
+
focused: true,
|
|
276685
|
+
value: localUrl,
|
|
276686
|
+
backgroundColor: "transparent",
|
|
276687
|
+
cursorColor: colors2.textMuted,
|
|
276688
|
+
onInput: (v2) => setLocalUrl(typeof v2 === "string" ? v2 : ""),
|
|
276689
|
+
onPaste: (event) => {
|
|
276690
|
+
const cleaned = String(event.text).replace(/\r?\n/g, "");
|
|
276691
|
+
setLocalUrl((prev) => `${prev}${cleaned}`);
|
|
276692
|
+
},
|
|
276693
|
+
onSubmit: finishEditing
|
|
276694
|
+
}, undefined, false, undefined, this)
|
|
276695
|
+
]
|
|
276696
|
+
}, "local-url", true, undefined, this));
|
|
276697
|
+
} else {
|
|
276698
|
+
elements2.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276699
|
+
id: "local-input-url",
|
|
276700
|
+
paddingLeft: 2,
|
|
276701
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276702
|
+
fg: isUrlFocused ? colors2.primary : colors2.textMuted,
|
|
276703
|
+
children: ` URL: ${localUrl || "(press Enter to set)"}`
|
|
276704
|
+
}, undefined, false, undefined, this)
|
|
276705
|
+
}, "local-url", false, undefined, this));
|
|
276706
|
+
}
|
|
276707
|
+
const isModelFieldFocused = isLocalFieldFocused("model");
|
|
276708
|
+
const isModelEditing = editingLocalField === "model";
|
|
276709
|
+
if (isModelEditing) {
|
|
276710
|
+
elements2.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276711
|
+
id: "local-input-model",
|
|
276712
|
+
paddingLeft: 2,
|
|
276713
|
+
children: [
|
|
276714
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276715
|
+
fg: colors2.primary,
|
|
276716
|
+
children: " Model: "
|
|
276717
|
+
}, undefined, false, undefined, this),
|
|
276718
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
|
|
276719
|
+
focused: true,
|
|
276720
|
+
value: localModelName,
|
|
276721
|
+
backgroundColor: "transparent",
|
|
276722
|
+
cursorColor: colors2.textMuted,
|
|
276723
|
+
onInput: (v2) => setLocalModelName(typeof v2 === "string" ? v2 : ""),
|
|
276724
|
+
onPaste: (event) => {
|
|
276725
|
+
const cleaned = String(event.text).replace(/\r?\n/g, "");
|
|
276726
|
+
setLocalModelName((prev) => `${prev}${cleaned}`);
|
|
276727
|
+
},
|
|
276728
|
+
onSubmit: finishEditing
|
|
276729
|
+
}, undefined, false, undefined, this)
|
|
276730
|
+
]
|
|
276731
|
+
}, "local-model", true, undefined, this));
|
|
276732
|
+
} else {
|
|
276733
|
+
elements2.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276734
|
+
id: "local-input-model",
|
|
276735
|
+
paddingLeft: 2,
|
|
276736
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276737
|
+
fg: isModelFieldFocused ? colors2.primary : colors2.textMuted,
|
|
276738
|
+
children: ` Model: ${localModelName || "(press Enter to set)"}`
|
|
276739
|
+
}, undefined, false, undefined, this)
|
|
276740
|
+
}, "local-model", false, undefined, this));
|
|
276741
|
+
}
|
|
276742
|
+
if (localModels) {
|
|
276743
|
+
for (const m2 of localModels) {
|
|
276744
|
+
const isSelected = m2.id === selectedModel.id;
|
|
276745
|
+
const isMFocused = isModelFocused(m2.id);
|
|
276746
|
+
elements2.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276747
|
+
id: `model-${m2.id}`,
|
|
276748
|
+
paddingLeft: 2,
|
|
276749
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276750
|
+
fg: isMFocused ? colors2.primary : colors2.textMuted,
|
|
276620
276751
|
children: [
|
|
276621
276752
|
isSelected ? "●" : "○",
|
|
276622
276753
|
" ",
|
|
276623
276754
|
m2.name
|
|
276624
276755
|
]
|
|
276625
|
-
},
|
|
276626
|
-
})
|
|
276627
|
-
|
|
276628
|
-
}
|
|
276629
|
-
|
|
276630
|
-
|
|
276631
|
-
|
|
276632
|
-
|
|
276633
|
-
|
|
276634
|
-
|
|
276635
|
-
|
|
276636
|
-
|
|
276637
|
-
|
|
276638
|
-
|
|
276639
|
-
|
|
276640
|
-
fg: isProviderFocused ? colors2.primary : isExpanded ? colors2.text : colors2.textMuted,
|
|
276756
|
+
}, undefined, true, undefined, this)
|
|
276757
|
+
}, m2.id, false, undefined, this));
|
|
276758
|
+
}
|
|
276759
|
+
}
|
|
276760
|
+
}
|
|
276761
|
+
return elements2;
|
|
276762
|
+
}
|
|
276763
|
+
const models = groupedModels[provider];
|
|
276764
|
+
if (!models || models.length === 0)
|
|
276765
|
+
return [];
|
|
276766
|
+
const elements = [];
|
|
276767
|
+
elements.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276768
|
+
id: `provider-${provider}`,
|
|
276769
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276770
|
+
fg: isFocused ? colors2.primary : isExpanded ? colors2.text : colors2.textMuted,
|
|
276641
276771
|
children: [
|
|
276642
|
-
|
|
276772
|
+
isFocused ? "❯" : isExpanded ? "▾" : "▸",
|
|
276643
276773
|
" ",
|
|
276644
276774
|
providerName,
|
|
276645
|
-
" ",
|
|
276646
|
-
"(",
|
|
276775
|
+
" (",
|
|
276647
276776
|
models.length,
|
|
276648
276777
|
")"
|
|
276649
276778
|
]
|
|
276650
|
-
}, undefined, true, undefined, this)
|
|
276651
|
-
|
|
276652
|
-
|
|
276653
|
-
|
|
276654
|
-
|
|
276655
|
-
|
|
276656
|
-
|
|
276657
|
-
|
|
276658
|
-
|
|
276659
|
-
|
|
276660
|
-
|
|
276779
|
+
}, undefined, true, undefined, this)
|
|
276780
|
+
}, provider, false, undefined, this));
|
|
276781
|
+
if (isExpanded) {
|
|
276782
|
+
for (const m2 of models) {
|
|
276783
|
+
const isSelected = m2.id === selectedModel.id;
|
|
276784
|
+
const isMFocused = isModelFocused(m2.id);
|
|
276785
|
+
const isDefault = m2.id === "claude-haiku-4-5" || m2.id === "gpt-4o-mini";
|
|
276786
|
+
elements.push(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276787
|
+
id: `model-${m2.id}`,
|
|
276788
|
+
paddingLeft: 2,
|
|
276789
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276790
|
+
fg: isMFocused ? colors2.primary : colors2.textMuted,
|
|
276661
276791
|
children: [
|
|
276662
276792
|
isSelected ? "●" : "○",
|
|
276663
276793
|
" ",
|
|
276664
276794
|
m2.name,
|
|
276665
276795
|
isDefault && !isModelUserSelected && isSelected ? " [default]" : ""
|
|
276666
276796
|
]
|
|
276667
|
-
},
|
|
276668
|
-
})
|
|
276669
|
-
}
|
|
276670
|
-
|
|
276671
|
-
|
|
276672
|
-
|
|
276673
|
-
|
|
276674
|
-
|
|
276675
|
-
children:
|
|
276797
|
+
}, undefined, true, undefined, this)
|
|
276798
|
+
}, m2.id, false, undefined, this));
|
|
276799
|
+
}
|
|
276800
|
+
}
|
|
276801
|
+
return elements;
|
|
276802
|
+
})
|
|
276803
|
+
}, undefined, false, undefined, this),
|
|
276804
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PickerRow, {
|
|
276805
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
276806
|
+
fg: colors2.textMuted,
|
|
276807
|
+
children: editingLocalField ? "Type or paste | Enter/Esc to confirm" : "↑/↓ navigate | ←/→ collapse/expand | Type to search"
|
|
276808
|
+
}, undefined, false, undefined, this)
|
|
276676
276809
|
}, undefined, false, undefined, this)
|
|
276677
276810
|
]
|
|
276678
276811
|
}, undefined, true, undefined, this);
|
|
@@ -276847,7 +276980,8 @@ function ConfigView({ config: config3, onBack, onStart }) {
|
|
|
276847
276980
|
borderColor: focusedField === "model" ? colors2.primary : colors2.border,
|
|
276848
276981
|
paddingLeft: 1,
|
|
276849
276982
|
paddingRight: 1,
|
|
276850
|
-
|
|
276983
|
+
height: 8,
|
|
276984
|
+
overflow: "hidden",
|
|
276851
276985
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ModelPicker, {
|
|
276852
276986
|
config: config3,
|
|
276853
276987
|
selectedModel,
|
|
@@ -280254,6 +280388,13 @@ function HelpDialog() {
|
|
|
280254
280388
|
}, undefined, false, undefined, this);
|
|
280255
280389
|
}
|
|
280256
280390
|
// src/tui/components/commands/models-display.tsx
|
|
280391
|
+
function ClippedLine({ children }) {
|
|
280392
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
280393
|
+
width: "100%",
|
|
280394
|
+
overflow: "hidden",
|
|
280395
|
+
children
|
|
280396
|
+
}, undefined, false, undefined, this);
|
|
280397
|
+
}
|
|
280257
280398
|
function ModelsDisplay() {
|
|
280258
280399
|
const { colors: colors2 } = useTheme();
|
|
280259
280400
|
const route = useRoute();
|
|
@@ -280281,42 +280422,52 @@ function ModelsDisplay() {
|
|
|
280281
280422
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
280282
280423
|
flexDirection: "column",
|
|
280283
280424
|
width: "100%",
|
|
280425
|
+
height: "100%",
|
|
280284
280426
|
paddingLeft: 4,
|
|
280427
|
+
paddingRight: 4,
|
|
280285
280428
|
paddingTop: 2,
|
|
280429
|
+
overflow: "hidden",
|
|
280286
280430
|
children: [
|
|
280287
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
280288
|
-
children:
|
|
280289
|
-
|
|
280290
|
-
|
|
280291
|
-
|
|
280292
|
-
|
|
280293
|
-
|
|
280294
|
-
|
|
280295
|
-
|
|
280296
|
-
|
|
280297
|
-
|
|
280298
|
-
|
|
280299
|
-
|
|
280300
|
-
|
|
280301
|
-
|
|
280302
|
-
|
|
280303
|
-
|
|
280304
|
-
|
|
280305
|
-
|
|
280306
|
-
|
|
280307
|
-
|
|
280308
|
-
|
|
280309
|
-
|
|
280310
|
-
|
|
280311
|
-
|
|
280312
|
-
|
|
280313
|
-
|
|
280314
|
-
|
|
280315
|
-
|
|
280431
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ClippedLine, {
|
|
280432
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
280433
|
+
children: [
|
|
280434
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280435
|
+
fg: colors2.primary,
|
|
280436
|
+
children: "█ "
|
|
280437
|
+
}, undefined, false, undefined, this),
|
|
280438
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280439
|
+
fg: colors2.text,
|
|
280440
|
+
children: "Select AI Model"
|
|
280441
|
+
}, undefined, false, undefined, this),
|
|
280442
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280443
|
+
fg: colors2.textMuted,
|
|
280444
|
+
children: [
|
|
280445
|
+
" (",
|
|
280446
|
+
model.name,
|
|
280447
|
+
")"
|
|
280448
|
+
]
|
|
280449
|
+
}, undefined, true, undefined, this),
|
|
280450
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280451
|
+
fg: colors2.textMuted,
|
|
280452
|
+
children: [
|
|
280453
|
+
" ",
|
|
280454
|
+
"[",
|
|
280455
|
+
isModelUserSelected ? "user" : "default",
|
|
280456
|
+
"]"
|
|
280457
|
+
]
|
|
280458
|
+
}, undefined, true, undefined, this)
|
|
280459
|
+
]
|
|
280460
|
+
}, undefined, true, undefined, this)
|
|
280461
|
+
}, undefined, false, undefined, this),
|
|
280316
280462
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
280317
280463
|
flexDirection: "column",
|
|
280464
|
+
width: "100%",
|
|
280318
280465
|
paddingLeft: 2,
|
|
280466
|
+
paddingRight: 2,
|
|
280319
280467
|
marginTop: 1,
|
|
280468
|
+
flexGrow: 1,
|
|
280469
|
+
flexShrink: 1,
|
|
280470
|
+
overflow: "hidden",
|
|
280320
280471
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ModelPicker, {
|
|
280321
280472
|
config: config3.data,
|
|
280322
280473
|
selectedModel: model,
|
|
@@ -280331,66 +280482,72 @@ function ModelsDisplay() {
|
|
|
280331
280482
|
flexDirection: "column",
|
|
280332
280483
|
marginTop: 2,
|
|
280333
280484
|
children: [
|
|
280334
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
280335
|
-
children:
|
|
280336
|
-
|
|
280337
|
-
|
|
280338
|
-
|
|
280339
|
-
|
|
280340
|
-
|
|
280341
|
-
|
|
280342
|
-
|
|
280343
|
-
|
|
280344
|
-
|
|
280345
|
-
|
|
280346
|
-
|
|
280347
|
-
|
|
280348
|
-
|
|
280349
|
-
|
|
280350
|
-
|
|
280351
|
-
|
|
280352
|
-
|
|
280353
|
-
|
|
280354
|
-
|
|
280355
|
-
|
|
280356
|
-
|
|
280357
|
-
|
|
280358
|
-
|
|
280359
|
-
|
|
280360
|
-
|
|
280361
|
-
|
|
280362
|
-
|
|
280363
|
-
|
|
280364
|
-
|
|
280365
|
-
|
|
280366
|
-
|
|
280367
|
-
|
|
280368
|
-
|
|
280369
|
-
|
|
280370
|
-
|
|
280371
|
-
|
|
280372
|
-
|
|
280373
|
-
|
|
280374
|
-
|
|
280375
|
-
|
|
280376
|
-
|
|
280377
|
-
|
|
280378
|
-
|
|
280379
|
-
|
|
280380
|
-
|
|
280381
|
-
|
|
280382
|
-
|
|
280383
|
-
|
|
280384
|
-
|
|
280385
|
-
|
|
280386
|
-
|
|
280387
|
-
|
|
280388
|
-
|
|
280389
|
-
|
|
280390
|
-
|
|
280391
|
-
|
|
280392
|
-
|
|
280393
|
-
|
|
280485
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ClippedLine, {
|
|
280486
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
280487
|
+
children: [
|
|
280488
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280489
|
+
fg: colors2.primary,
|
|
280490
|
+
children: "█ "
|
|
280491
|
+
}, undefined, false, undefined, this),
|
|
280492
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280493
|
+
fg: colors2.textMuted,
|
|
280494
|
+
children: "Press "
|
|
280495
|
+
}, undefined, false, undefined, this),
|
|
280496
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280497
|
+
fg: colors2.text,
|
|
280498
|
+
children: "[Enter]"
|
|
280499
|
+
}, undefined, false, undefined, this),
|
|
280500
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280501
|
+
fg: colors2.textMuted,
|
|
280502
|
+
children: " to confirm"
|
|
280503
|
+
}, undefined, false, undefined, this)
|
|
280504
|
+
]
|
|
280505
|
+
}, undefined, true, undefined, this)
|
|
280506
|
+
}, undefined, false, undefined, this),
|
|
280507
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ClippedLine, {
|
|
280508
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
280509
|
+
children: [
|
|
280510
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280511
|
+
fg: colors2.primary,
|
|
280512
|
+
children: "█ "
|
|
280513
|
+
}, undefined, false, undefined, this),
|
|
280514
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280515
|
+
fg: colors2.textMuted,
|
|
280516
|
+
children: "Press "
|
|
280517
|
+
}, undefined, false, undefined, this),
|
|
280518
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280519
|
+
fg: colors2.text,
|
|
280520
|
+
children: "[ESC]"
|
|
280521
|
+
}, undefined, false, undefined, this),
|
|
280522
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280523
|
+
fg: colors2.textMuted,
|
|
280524
|
+
children: " to go back"
|
|
280525
|
+
}, undefined, false, undefined, this)
|
|
280526
|
+
]
|
|
280527
|
+
}, undefined, true, undefined, this)
|
|
280528
|
+
}, undefined, false, undefined, this),
|
|
280529
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ClippedLine, {
|
|
280530
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
280531
|
+
children: [
|
|
280532
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280533
|
+
fg: colors2.primary,
|
|
280534
|
+
children: "█ "
|
|
280535
|
+
}, undefined, false, undefined, this),
|
|
280536
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280537
|
+
fg: colors2.textMuted,
|
|
280538
|
+
children: "Press "
|
|
280539
|
+
}, undefined, false, undefined, this),
|
|
280540
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280541
|
+
fg: colors2.text,
|
|
280542
|
+
children: "[Ctrl+P]"
|
|
280543
|
+
}, undefined, false, undefined, this),
|
|
280544
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
280545
|
+
fg: colors2.textMuted,
|
|
280546
|
+
children: " to connect provider"
|
|
280547
|
+
}, undefined, false, undefined, this)
|
|
280548
|
+
]
|
|
280549
|
+
}, undefined, true, undefined, this)
|
|
280550
|
+
}, undefined, false, undefined, this)
|
|
280394
280551
|
]
|
|
280395
280552
|
}, undefined, true, undefined, this)
|
|
280396
280553
|
]
|
|
@@ -286458,8 +286615,10 @@ function resolveKeyboardShortcut(key, status, inputValue, hasPendingApprovals, d
|
|
|
286458
286615
|
return { type: "toggle-verbose" };
|
|
286459
286616
|
if (key.ctrl && key.name === "l")
|
|
286460
286617
|
return { type: "toggle-expanded-logs" };
|
|
286461
|
-
if (key.name === "tab" && key.shift)
|
|
286618
|
+
if (key.name === "tab" && key.shift && key.meta)
|
|
286462
286619
|
return { type: "toggle-approval" };
|
|
286620
|
+
if (key.name === "tab" && key.shift)
|
|
286621
|
+
return { type: "toggle-mode" };
|
|
286463
286622
|
if (status === "waiting" && hasPendingApprovals && (key.name === "y" || key.raw === "Y")) {
|
|
286464
286623
|
return { type: "approve" };
|
|
286465
286624
|
}
|
|
@@ -286474,7 +286633,9 @@ function resolveAbortAction(commandCancelled, cancelCommand) {
|
|
|
286474
286633
|
}
|
|
286475
286634
|
return { type: "kill-agent" };
|
|
286476
286635
|
}
|
|
286477
|
-
function buildOperatorSystemPrompt(target, operatorState) {
|
|
286636
|
+
function buildOperatorSystemPrompt(target, operatorState, agentMode) {
|
|
286637
|
+
const modeNote = agentMode === "plan" ? `
|
|
286638
|
+
Agent mode: PLAN — read-only tools only, no mutations allowed` : "";
|
|
286478
286639
|
return `${BASE_SYSTEM_PROMPT}
|
|
286479
286640
|
|
|
286480
286641
|
# Operator Mode
|
|
@@ -286483,7 +286644,7 @@ You are operating in interactive operator mode. The human operator will guide yo
|
|
|
286483
286644
|
|
|
286484
286645
|
Target: ${target || "unknown"}
|
|
286485
286646
|
Stage: ${operatorState.currentStage}
|
|
286486
|
-
Command approval: ${operatorState.requireApproval ? "enabled — the operator will approve each tool call" : "disabled — tool calls execute automatically"}`;
|
|
286647
|
+
Command approval: ${operatorState.requireApproval ? "enabled — the operator will approve each tool call" : "disabled — tool calls execute automatically"}${modeNote}`;
|
|
286487
286648
|
}
|
|
286488
286649
|
function resolveInputFocused(status, dialogStackLength, externalDialogOpen) {
|
|
286489
286650
|
return status !== "running" && dialogStackLength === 0 && !externalDialogOpen;
|
|
@@ -286653,6 +286814,7 @@ function OperatorDashboard({
|
|
|
286653
286814
|
const [lastApprovedAction, setLastApprovedAction] = import_react79.useState(null);
|
|
286654
286815
|
const [verboseMode, setVerboseMode] = import_react79.useState(false);
|
|
286655
286816
|
const [expandedLogs, setExpandedLogs] = import_react79.useState(false);
|
|
286817
|
+
const [agentMode, setAgentMode] = import_react79.useState("default");
|
|
286656
286818
|
const tokenUsageRef = import_react79.useRef(tokenUsage);
|
|
286657
286819
|
import_react79.useEffect(() => {
|
|
286658
286820
|
tokenUsageRef.current = tokenUsage;
|
|
@@ -287095,7 +287257,10 @@ function OperatorDashboard({
|
|
|
287095
287257
|
messages: nextMessages,
|
|
287096
287258
|
stopWhen: [stepCountIs(1e4)],
|
|
287097
287259
|
target: initialConfig?.target,
|
|
287098
|
-
activeTools: [
|
|
287260
|
+
activeTools: [
|
|
287261
|
+
...agentMode === "plan" ? PLAN_MODE_TOOL_NAMES : ALL_TOOL_NAMES
|
|
287262
|
+
],
|
|
287263
|
+
mode: agentMode,
|
|
287099
287264
|
abortSignal: controller.signal,
|
|
287100
287265
|
authConfig: buildAuthConfig(config3.data),
|
|
287101
287266
|
approvalGate: approvalGateRef.current,
|
|
@@ -287111,7 +287276,7 @@ function OperatorDashboard({
|
|
|
287111
287276
|
if (session) {
|
|
287112
287277
|
agentResult = await runOffensiveSecurityAgent({
|
|
287113
287278
|
...commonInput,
|
|
287114
|
-
system: buildOperatorSystemPrompt(initialConfig?.target, operatorState),
|
|
287279
|
+
system: buildOperatorSystemPrompt(initialConfig?.target, operatorState, agentMode),
|
|
287115
287280
|
session
|
|
287116
287281
|
});
|
|
287117
287282
|
} else {
|
|
@@ -287127,7 +287292,7 @@ function OperatorDashboard({
|
|
|
287127
287292
|
};
|
|
287128
287293
|
agentResult = await runOffensiveSecurityAgent({
|
|
287129
287294
|
...commonInput,
|
|
287130
|
-
system: buildOperatorSystemPrompt(initialConfig?.target, operatorState),
|
|
287295
|
+
system: buildOperatorSystemPrompt(initialConfig?.target, operatorState, agentMode),
|
|
287131
287296
|
sessionConfig,
|
|
287132
287297
|
onNameGenerated: (name26) => {
|
|
287133
287298
|
pendingNameRef.current = name26;
|
|
@@ -287192,6 +287357,7 @@ function OperatorDashboard({
|
|
|
287192
287357
|
model.id,
|
|
287193
287358
|
config3.data,
|
|
287194
287359
|
operatorState,
|
|
287360
|
+
agentMode,
|
|
287195
287361
|
addTokenUsage,
|
|
287196
287362
|
appendText,
|
|
287197
287363
|
addStreamingToolCall,
|
|
@@ -287382,6 +287548,9 @@ function OperatorDashboard({
|
|
|
287382
287548
|
return { ...prev, requireApproval: newVal };
|
|
287383
287549
|
});
|
|
287384
287550
|
}, []);
|
|
287551
|
+
const toggleMode = import_react79.useCallback(() => {
|
|
287552
|
+
setAgentMode((prev) => prev === "default" ? "plan" : "default");
|
|
287553
|
+
}, []);
|
|
287385
287554
|
useKeyboard((key) => {
|
|
287386
287555
|
if (status === "running" && queuedMessages.length > 0 && !inputValue.trim()) {
|
|
287387
287556
|
if (key.name === "up") {
|
|
@@ -287453,6 +287622,9 @@ function OperatorDashboard({
|
|
|
287453
287622
|
case "toggle-approval":
|
|
287454
287623
|
toggleApproval();
|
|
287455
287624
|
return;
|
|
287625
|
+
case "toggle-mode":
|
|
287626
|
+
toggleMode();
|
|
287627
|
+
return;
|
|
287456
287628
|
case "approve":
|
|
287457
287629
|
handleApprove();
|
|
287458
287630
|
return;
|
|
@@ -287548,6 +287720,10 @@ function OperatorDashboard({
|
|
|
287548
287720
|
flexDirection: "row",
|
|
287549
287721
|
gap: 2,
|
|
287550
287722
|
children: [
|
|
287723
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
287724
|
+
fg: agentMode === "plan" ? colors2.warning : colors2.primary,
|
|
287725
|
+
children: agentMode === "plan" ? "PLAN" : "DEFAULT"
|
|
287726
|
+
}, undefined, false, undefined, this),
|
|
287551
287727
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
287552
287728
|
fg: operatorState.requireApproval ? colors2.warning : colors2.primary,
|
|
287553
287729
|
children: operatorState.requireApproval ? "APPROVAL ON" : "APPROVAL OFF"
|
|
@@ -287591,7 +287767,7 @@ function OperatorDashboard({
|
|
|
287591
287767
|
focused: status === "running" ? selectedQueueIndex < 0 : resolveInputFocused(status, stack.length, externalDialogOpen),
|
|
287592
287768
|
status: status === "waiting" ? "running" : status,
|
|
287593
287769
|
mode: "operator",
|
|
287594
|
-
operatorMode: operatorState.mode,
|
|
287770
|
+
operatorMode: agentMode === "plan" ? "plan" : operatorState.mode,
|
|
287595
287771
|
verboseMode,
|
|
287596
287772
|
expandedLogs,
|
|
287597
287773
|
pendingApproval: currentPending,
|