@rdmind/rdmind 0.1.8-alpha.9 → 0.1.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.
- package/cli.js +2147 -1814
- package/locales/en.js +90 -191
- package/locales/zh.js +102 -213
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -132660,7 +132660,7 @@ var init_loggingContentGenerator = __esm({
|
|
|
132660
132660
|
this._logApiResponse(
|
|
132661
132661
|
response.responseId ?? requestId,
|
|
132662
132662
|
durationMs,
|
|
132663
|
-
|
|
132663
|
+
req.model,
|
|
132664
132664
|
userPromptId,
|
|
132665
132665
|
response.usageMetadata,
|
|
132666
132666
|
JSON.stringify(response)
|
|
@@ -141204,10 +141204,18 @@ var init_pipeline = __esm({
|
|
|
141204
141204
|
userPromptId,
|
|
141205
141205
|
false,
|
|
141206
141206
|
async (openaiRequest) => {
|
|
141207
|
+
const extraBody = this.contentGeneratorConfig.model?.toLowerCase().includes("glm-4.7") ? {
|
|
141208
|
+
thinking: {
|
|
141209
|
+
type: "enabled",
|
|
141210
|
+
clear_thinking: false
|
|
141211
|
+
// Enable preserved/interleaved thinking
|
|
141212
|
+
}
|
|
141213
|
+
} : void 0;
|
|
141207
141214
|
const openaiResponse = await this.client.chat.completions.create(
|
|
141208
141215
|
openaiRequest,
|
|
141209
141216
|
{
|
|
141210
|
-
signal: request4.config?.abortSignal
|
|
141217
|
+
signal: request4.config?.abortSignal,
|
|
141218
|
+
...extraBody ? { extra_body: extraBody } : {}
|
|
141211
141219
|
}
|
|
141212
141220
|
);
|
|
141213
141221
|
const geminiResponse = this.converter.convertOpenAIResponseToGemini(openaiResponse);
|
|
@@ -141221,10 +141229,18 @@ var init_pipeline = __esm({
|
|
|
141221
141229
|
userPromptId,
|
|
141222
141230
|
true,
|
|
141223
141231
|
async (openaiRequest, context2) => {
|
|
141232
|
+
const extraBody = this.contentGeneratorConfig.model?.toLowerCase().includes("glm-4.7") ? {
|
|
141233
|
+
thinking: {
|
|
141234
|
+
type: "enabled",
|
|
141235
|
+
clear_thinking: false
|
|
141236
|
+
// Enable preserved/interleaved thinking
|
|
141237
|
+
}
|
|
141238
|
+
} : void 0;
|
|
141224
141239
|
const stream2 = await this.client.chat.completions.create(
|
|
141225
141240
|
openaiRequest,
|
|
141226
141241
|
{
|
|
141227
|
-
signal: request4.config?.abortSignal
|
|
141242
|
+
signal: request4.config?.abortSignal,
|
|
141243
|
+
...extraBody ? { extra_body: extraBody } : {}
|
|
141228
141244
|
}
|
|
141229
141245
|
);
|
|
141230
141246
|
return this.processStreamWithLogging(stream2, context2, request4);
|
|
@@ -156072,7 +156088,7 @@ __export(geminiContentGenerator_exports2, {
|
|
|
156072
156088
|
createGeminiContentGenerator: () => createGeminiContentGenerator
|
|
156073
156089
|
});
|
|
156074
156090
|
function createGeminiContentGenerator(config2, gcConfig) {
|
|
156075
|
-
const version2 = "0.1.8
|
|
156091
|
+
const version2 = "0.1.8";
|
|
156076
156092
|
const userAgent2 = config2.userAgent || `QwenCode/${version2} (${process.platform}; ${process.arch})`;
|
|
156077
156093
|
const baseHeaders = {
|
|
156078
156094
|
"User-Agent": userAgent2
|
|
@@ -156143,7 +156159,7 @@ function createContentGeneratorConfig(config2, authType, generationConfig) {
|
|
|
156143
156159
|
}
|
|
156144
156160
|
return {
|
|
156145
156161
|
...newContentGeneratorConfig,
|
|
156146
|
-
model: newContentGeneratorConfig?.model || "
|
|
156162
|
+
model: newContentGeneratorConfig?.model || "gemini-3-flash-preview(low)"
|
|
156147
156163
|
};
|
|
156148
156164
|
}
|
|
156149
156165
|
if (authType === "anthropic" /* USE_ANTHROPIC */) {
|
|
@@ -225563,8 +225579,8 @@ var init_xhsSSOAuth = __esm({
|
|
|
225563
225579
|
DEFAULT_TIMEOUT_MS = 1e4;
|
|
225564
225580
|
DEFAULT_API_TIMEOUT_MS = 5e3;
|
|
225565
225581
|
COMPANY_DEFAULT_CONFIG = {
|
|
225566
|
-
baseUrl: "https://runway.devops.
|
|
225567
|
-
model: "
|
|
225582
|
+
baseUrl: "https://runway.devops.rednote.life/openai/google/v1",
|
|
225583
|
+
model: "gemini-3-flash-preview(low)"
|
|
225568
225584
|
};
|
|
225569
225585
|
ssoAuthEvents = new EventEmitter6();
|
|
225570
225586
|
__name(getRequestSSOId, "getRequestSSOId");
|
|
@@ -233717,8 +233733,8 @@ var init_git_commit = __esm({
|
|
|
233717
233733
|
"packages/core/src/generated/git-commit.ts"() {
|
|
233718
233734
|
"use strict";
|
|
233719
233735
|
init_esbuild_shims();
|
|
233720
|
-
GIT_COMMIT_INFO = "
|
|
233721
|
-
CLI_VERSION = "0.1.8
|
|
233736
|
+
GIT_COMMIT_INFO = "8f0613d7";
|
|
233737
|
+
CLI_VERSION = "0.1.8";
|
|
233722
233738
|
}
|
|
233723
233739
|
});
|
|
233724
233740
|
|
|
@@ -304859,6 +304875,7 @@ var init_en3 = __esm({
|
|
|
304859
304875
|
"(Use Enter to select{{tabText}})": "(Use Enter to select{{tabText}})",
|
|
304860
304876
|
", Tab to change focus": ", Tab to change focus",
|
|
304861
304877
|
"To see changes, RDMind must be restarted. Press r to exit and apply changes now.": "To see changes, RDMind must be restarted. Press r to exit and apply changes now.",
|
|
304878
|
+
'The command "/{{command}}" is not supported in non-interactive mode.': 'The command "/{{command}}" is not supported in non-interactive mode.',
|
|
304862
304879
|
// ============================================================================
|
|
304863
304880
|
// Settings Labels
|
|
304864
304881
|
// ============================================================================
|
|
@@ -305090,6 +305107,10 @@ var init_en3 = __esm({
|
|
|
305090
305107
|
"Already generating summary, wait for previous request to complete": "Already generating summary, wait for previous request to complete",
|
|
305091
305108
|
"No conversation found to summarize.": "No conversation found to summarize.",
|
|
305092
305109
|
"Failed to generate project context summary: {{error}}": "Failed to generate project context summary: {{error}}",
|
|
305110
|
+
"Saved project summary to {{filePathForDisplay}}.": "Saved project summary to {{filePathForDisplay}}.",
|
|
305111
|
+
"Saving project summary...": "Saving project summary...",
|
|
305112
|
+
"Generating project summary...": "Generating project summary...",
|
|
305113
|
+
"Failed to generate summary - no text content received from LLM response": "Failed to generate summary - no text content received from LLM response",
|
|
305093
305114
|
// ============================================================================
|
|
305094
305115
|
// Commands - Model
|
|
305095
305116
|
// ============================================================================
|
|
@@ -305100,8 +305121,8 @@ var init_en3 = __esm({
|
|
|
305100
305121
|
// ============================================================================
|
|
305101
305122
|
// Commands - Clear
|
|
305102
305123
|
// ============================================================================
|
|
305103
|
-
"
|
|
305104
|
-
"
|
|
305124
|
+
"Starting a new session, resetting chat, and clearing terminal.": "Starting a new session, resetting chat, and clearing terminal.",
|
|
305125
|
+
"Starting a new session and clearing.": "Starting a new session and clearing.",
|
|
305105
305126
|
// ============================================================================
|
|
305106
305127
|
// Commands - Compress
|
|
305107
305128
|
// ============================================================================
|
|
@@ -305365,183 +305386,142 @@ var init_en3 = __esm({
|
|
|
305365
305386
|
// ============================================================================
|
|
305366
305387
|
"Waiting for user confirmation...": "Waiting for user confirmation...",
|
|
305367
305388
|
"(esc to cancel, {{time}})": "(esc to cancel, {{time}})",
|
|
305368
|
-
|
|
305369
|
-
|
|
305370
|
-
|
|
305371
|
-
|
|
305372
|
-
|
|
305373
|
-
|
|
305374
|
-
|
|
305375
|
-
|
|
305376
|
-
|
|
305377
|
-
|
|
305378
|
-
|
|
305379
|
-
|
|
305380
|
-
|
|
305381
|
-
|
|
305382
|
-
|
|
305383
|
-
|
|
305384
|
-
|
|
305385
|
-
|
|
305386
|
-
|
|
305387
|
-
|
|
305388
|
-
|
|
305389
|
-
|
|
305390
|
-
|
|
305391
|
-
|
|
305392
|
-
|
|
305393
|
-
|
|
305394
|
-
|
|
305395
|
-
|
|
305396
|
-
|
|
305397
|
-
|
|
305398
|
-
|
|
305399
|
-
|
|
305400
|
-
|
|
305401
|
-
|
|
305402
|
-
|
|
305403
|
-
|
|
305404
|
-
|
|
305405
|
-
|
|
305406
|
-
|
|
305407
|
-
|
|
305408
|
-
|
|
305409
|
-
|
|
305410
|
-
|
|
305411
|
-
|
|
305412
|
-
|
|
305413
|
-
|
|
305414
|
-
|
|
305415
|
-
|
|
305416
|
-
|
|
305417
|
-
|
|
305418
|
-
|
|
305419
|
-
|
|
305420
|
-
|
|
305421
|
-
|
|
305422
|
-
|
|
305423
|
-
|
|
305424
|
-
|
|
305425
|
-
|
|
305426
|
-
|
|
305427
|
-
|
|
305428
|
-
|
|
305429
|
-
|
|
305430
|
-
|
|
305431
|
-
|
|
305432
|
-
|
|
305433
|
-
|
|
305434
|
-
|
|
305435
|
-
|
|
305436
|
-
|
|
305437
|
-
|
|
305438
|
-
|
|
305439
|
-
|
|
305440
|
-
|
|
305441
|
-
|
|
305442
|
-
|
|
305443
|
-
|
|
305444
|
-
|
|
305445
|
-
|
|
305446
|
-
|
|
305447
|
-
|
|
305448
|
-
|
|
305449
|
-
|
|
305450
|
-
|
|
305451
|
-
|
|
305452
|
-
|
|
305453
|
-
|
|
305454
|
-
|
|
305455
|
-
|
|
305456
|
-
|
|
305457
|
-
|
|
305458
|
-
|
|
305459
|
-
|
|
305460
|
-
|
|
305461
|
-
|
|
305462
|
-
|
|
305463
|
-
|
|
305464
|
-
|
|
305465
|
-
|
|
305466
|
-
|
|
305467
|
-
|
|
305468
|
-
|
|
305469
|
-
|
|
305470
|
-
|
|
305471
|
-
|
|
305472
|
-
|
|
305473
|
-
|
|
305474
|
-
|
|
305475
|
-
|
|
305476
|
-
|
|
305477
|
-
|
|
305478
|
-
|
|
305479
|
-
|
|
305480
|
-
|
|
305481
|
-
|
|
305482
|
-
|
|
305483
|
-
|
|
305484
|
-
|
|
305485
|
-
|
|
305486
|
-
|
|
305487
|
-
|
|
305488
|
-
|
|
305489
|
-
|
|
305490
|
-
|
|
305491
|
-
|
|
305492
|
-
|
|
305493
|
-
|
|
305494
|
-
|
|
305495
|
-
|
|
305496
|
-
|
|
305497
|
-
|
|
305498
|
-
|
|
305499
|
-
|
|
305500
|
-
|
|
305501
|
-
|
|
305502
|
-
|
|
305503
|
-
|
|
305504
|
-
"Praying for no bugs...": "Praying for no bugs...",
|
|
305505
|
-
"Resolving dependencies...": "Resolving dependencies...",
|
|
305506
|
-
"Waiting for product manager to change requirements...": "Waiting for product manager to change requirements...",
|
|
305507
|
-
"Postponing project deadline...": "Postponing project deadline...",
|
|
305508
|
-
'Preparing another "almost done"...': 'Preparing another "almost done"...',
|
|
305509
|
-
"Taking a break...": "Taking a break...",
|
|
305510
|
-
"Making goji berry tea...": "Making goji berry tea...",
|
|
305511
|
-
"Ordering takeout...": "Ordering takeout...",
|
|
305512
|
-
"Pretending to be busy...": "Pretending to be busy...",
|
|
305513
|
-
"Recharging faith...": "Recharging faith...",
|
|
305514
|
-
"Downloading more RAM...": "Downloading more RAM...",
|
|
305515
|
-
"Feeding the server...": "Feeding the server...",
|
|
305516
|
-
"Waking up sleeping code...": "Waking up sleeping code...",
|
|
305517
|
-
"Feeding data to AI...": "Feeding data to AI...",
|
|
305518
|
-
"Opening imagination...": "Opening imagination...",
|
|
305519
|
-
"Boiling water for tea...": "Boiling water for tea...",
|
|
305520
|
-
"Waiting for the elevator...": "Waiting for the elevator...",
|
|
305521
|
-
"Taking a number in queue...": "Taking a number in queue...",
|
|
305522
|
-
"Waiting for traffic light...": "Waiting for traffic light...",
|
|
305523
|
-
"Charging...": "Charging...",
|
|
305524
|
-
"Buffering life...": "Buffering life...",
|
|
305525
|
-
"Contemplating the meaning of life...": "Contemplating the meaning of life...",
|
|
305526
|
-
"What to eat today? Thinking...": "What to eat today? Thinking...",
|
|
305527
|
-
"Pretending to work...": "Pretending to work...",
|
|
305528
|
-
"Let me think, just a moment...": "Let me think, just a moment...",
|
|
305529
|
-
"Brewing inspiration...": "Brewing inspiration...",
|
|
305530
|
-
"Take a deep breath, almost done...": "Take a deep breath, almost done...",
|
|
305531
|
-
"Don't worry, good things take time...": "Don't worry, good things take time...",
|
|
305532
|
-
"Stay calm, exciting things coming...": "Stay calm, exciting things coming...",
|
|
305533
|
-
"Greeting the server...": "Greeting the server...",
|
|
305534
|
-
"Organizing thoughts...": "Organizing thoughts...",
|
|
305535
|
-
"Preparing my words...": "Preparing my words...",
|
|
305536
|
-
"Looking up information...": "Looking up information...",
|
|
305537
|
-
"Sorting out my thoughts...": "Sorting out my thoughts...",
|
|
305538
|
-
"Analyzing the problem...": "Analyzing the problem...",
|
|
305539
|
-
"Looking for the best solution...": "Looking for the best solution...",
|
|
305540
|
-
"Loading...": "Loading...",
|
|
305541
|
-
"Processing, please wait...": "Processing, please wait...",
|
|
305542
|
-
"Almost there...": "Almost there...",
|
|
305543
|
-
"Working hard...": "Working hard...",
|
|
305544
|
-
"Almost... almost...": "Almost... almost...",
|
|
305389
|
+
// ============================================================================
|
|
305390
|
+
// Loading Phrases
|
|
305391
|
+
// ============================================================================
|
|
305392
|
+
WITTY_LOADING_PHRASES: [
|
|
305393
|
+
"I'm Feeling Lucky",
|
|
305394
|
+
"Shipping awesomeness... ",
|
|
305395
|
+
"Painting the serifs back on...",
|
|
305396
|
+
"Navigating the slime mold...",
|
|
305397
|
+
"Consulting the digital spirits...",
|
|
305398
|
+
"Reticulating splines...",
|
|
305399
|
+
"Warming up the AI hamsters...",
|
|
305400
|
+
"Asking the magic conch shell...",
|
|
305401
|
+
"Generating witty retort...",
|
|
305402
|
+
"Polishing the algorithms...",
|
|
305403
|
+
"Don't rush perfection (or my code)...",
|
|
305404
|
+
"Brewing fresh bytes...",
|
|
305405
|
+
"Counting electrons...",
|
|
305406
|
+
"Engaging cognitive processors...",
|
|
305407
|
+
"Checking for syntax errors in the universe...",
|
|
305408
|
+
"One moment, optimizing humor...",
|
|
305409
|
+
"Shuffling punchlines...",
|
|
305410
|
+
"Untangling neural nets...",
|
|
305411
|
+
"Compiling brilliance...",
|
|
305412
|
+
"Loading wit.exe...",
|
|
305413
|
+
"Summoning the cloud of wisdom...",
|
|
305414
|
+
"Preparing a witty response...",
|
|
305415
|
+
"Just a sec, I'm debugging reality...",
|
|
305416
|
+
"Confuzzling the options...",
|
|
305417
|
+
"Tuning the cosmic frequencies...",
|
|
305418
|
+
"Crafting a response worthy of your patience...",
|
|
305419
|
+
"Compiling the 1s and 0s...",
|
|
305420
|
+
"Resolving dependencies... and existential crises...",
|
|
305421
|
+
"Defragmenting memories... both RAM and personal...",
|
|
305422
|
+
"Rebooting the humor module...",
|
|
305423
|
+
"Caching the essentials (mostly cat memes)...",
|
|
305424
|
+
"Optimizing for ludicrous speed",
|
|
305425
|
+
"Swapping bits... don't tell the bytes...",
|
|
305426
|
+
"Garbage collecting... be right back...",
|
|
305427
|
+
"Assembling the interwebs...",
|
|
305428
|
+
"Converting coffee into code...",
|
|
305429
|
+
"Updating the syntax for reality...",
|
|
305430
|
+
"Rewiring the synapses...",
|
|
305431
|
+
"Looking for a misplaced semicolon...",
|
|
305432
|
+
"Greasin' the cogs of the machine...",
|
|
305433
|
+
"Pre-heating the servers...",
|
|
305434
|
+
"Calibrating the flux capacitor...",
|
|
305435
|
+
"Engaging the improbability drive...",
|
|
305436
|
+
"Channeling the Force...",
|
|
305437
|
+
"Aligning the stars for optimal response...",
|
|
305438
|
+
"So say we all...",
|
|
305439
|
+
"Loading the next great idea...",
|
|
305440
|
+
"Just a moment, I'm in the zone...",
|
|
305441
|
+
"Preparing to dazzle you with brilliance...",
|
|
305442
|
+
"Just a tick, I'm polishing my wit...",
|
|
305443
|
+
"Hold tight, I'm crafting a masterpiece...",
|
|
305444
|
+
"Just a jiffy, I'm debugging the universe...",
|
|
305445
|
+
"Just a moment, I'm aligning the pixels...",
|
|
305446
|
+
"Just a sec, I'm optimizing the humor...",
|
|
305447
|
+
"Just a moment, I'm tuning the algorithms...",
|
|
305448
|
+
"Warp speed engaged...",
|
|
305449
|
+
"Mining for more Dilithium crystals...",
|
|
305450
|
+
"Don't panic...",
|
|
305451
|
+
"Following the white rabbit...",
|
|
305452
|
+
"The truth is in here... somewhere...",
|
|
305453
|
+
"Blowing on the cartridge...",
|
|
305454
|
+
"Loading... Do a barrel roll!",
|
|
305455
|
+
"Waiting for the respawn...",
|
|
305456
|
+
"Finishing the Kessel Run in less than 12 parsecs...",
|
|
305457
|
+
"The cake is not a lie, it's just still loading...",
|
|
305458
|
+
"Fiddling with the character creation screen...",
|
|
305459
|
+
"Just a moment, I'm finding the right meme...",
|
|
305460
|
+
"Pressing 'A' to continue...",
|
|
305461
|
+
"Herding digital cats...",
|
|
305462
|
+
"Polishing the pixels...",
|
|
305463
|
+
"Finding a suitable loading screen pun...",
|
|
305464
|
+
"Distracting you with this witty phrase...",
|
|
305465
|
+
"Almost there... probably...",
|
|
305466
|
+
"Our hamsters are working as fast as they can...",
|
|
305467
|
+
"Giving Cloudy a pat on the head...",
|
|
305468
|
+
"Petting the cat...",
|
|
305469
|
+
"Rickrolling my boss...",
|
|
305470
|
+
"Never gonna give you up, never gonna let you down...",
|
|
305471
|
+
"Slapping the bass...",
|
|
305472
|
+
"Tasting the snozberries...",
|
|
305473
|
+
"I'm going the distance, I'm going for speed...",
|
|
305474
|
+
"Is this the real life? Is this just fantasy?...",
|
|
305475
|
+
"I've got a good feeling about this...",
|
|
305476
|
+
"Poking the bear...",
|
|
305477
|
+
"Doing research on the latest memes...",
|
|
305478
|
+
"Figuring out how to make this more witty...",
|
|
305479
|
+
"Hmmm... let me think...",
|
|
305480
|
+
"What do you call a fish with no eyes? A fsh...",
|
|
305481
|
+
"Why did the computer go to therapy? It had too many bytes...",
|
|
305482
|
+
"Why don't programmers like nature? It has too many bugs...",
|
|
305483
|
+
"Why do programmers prefer dark mode? Because light attracts bugs...",
|
|
305484
|
+
"Why did the developer go broke? Because they used up all their cache...",
|
|
305485
|
+
"What can you do with a broken pencil? Nothing, it's pointless...",
|
|
305486
|
+
"Applying percussive maintenance...",
|
|
305487
|
+
"Searching for the correct USB orientation...",
|
|
305488
|
+
"Ensuring the magic smoke stays inside the wires...",
|
|
305489
|
+
"Rewriting in Rust for no particular reason...",
|
|
305490
|
+
"Trying to exit Vim...",
|
|
305491
|
+
"Spinning up the hamster wheel...",
|
|
305492
|
+
"That's not a bug, it's an undocumented feature...",
|
|
305493
|
+
"Engage.",
|
|
305494
|
+
"I'll be back... with an answer.",
|
|
305495
|
+
"My other process is a TARDIS...",
|
|
305496
|
+
"Communing with the machine spirit...",
|
|
305497
|
+
"Letting the thoughts marinate...",
|
|
305498
|
+
"Just remembered where I put my keys...",
|
|
305499
|
+
"Pondering the orb...",
|
|
305500
|
+
"I've seen things you people wouldn't believe... like a user who reads loading messages.",
|
|
305501
|
+
"Initiating thoughtful gaze...",
|
|
305502
|
+
"What's a computer's favorite snack? Microchips.",
|
|
305503
|
+
"Why do Java developers wear glasses? Because they don't C#.",
|
|
305504
|
+
"Charging the laser... pew pew!",
|
|
305505
|
+
"Dividing by zero... just kidding!",
|
|
305506
|
+
"Looking for an adult superviso... I mean, processing.",
|
|
305507
|
+
"Making it go beep boop.",
|
|
305508
|
+
"Buffering... because even AIs need a moment.",
|
|
305509
|
+
"Entangling quantum particles for a faster response...",
|
|
305510
|
+
"Polishing the chrome... on the algorithms.",
|
|
305511
|
+
"Are you not entertained? (Working on it!)",
|
|
305512
|
+
"Summoning the code gremlins... to help, of course.",
|
|
305513
|
+
"Just waiting for the dial-up tone to finish...",
|
|
305514
|
+
"Recalibrating the humor-o-meter.",
|
|
305515
|
+
"My other loading screen is even funnier.",
|
|
305516
|
+
"Pretty sure there's a cat walking on the keyboard somewhere...",
|
|
305517
|
+
"Enhancing... Enhancing... Still loading.",
|
|
305518
|
+
"It's not a bug, it's a feature... of this loading screen.",
|
|
305519
|
+
"Have you tried turning it off and on again? (The loading screen, not me.)",
|
|
305520
|
+
"Constructing additional pylons..."
|
|
305521
|
+
],
|
|
305522
|
+
// ============================================================================
|
|
305523
|
+
// OpenSpec Commands
|
|
305524
|
+
// ============================================================================
|
|
305545
305525
|
"Initialize OpenSpec in a project with RDMind integration": "Initialize OpenSpec in a project with RDMind integration",
|
|
305546
305526
|
"Initialize OpenSpec in the current directory": "Initialize OpenSpec in the current directory",
|
|
305547
305527
|
"Scaffold a new OpenSpec change and validate strictly.": "Scaffold a new OpenSpec change and validate strictly.",
|
|
@@ -305647,7 +305627,7 @@ var init_zh = __esm({
|
|
|
305647
305627
|
"(empty prompt)": "(\u7A7A\u63D0\u793A\u8BCD)",
|
|
305648
305628
|
"No sessions found. Start a new session with {{cmd}}.": "\u672A\u53D1\u73B0\u4F1A\u8BDD\u3002\u8BF7\u4F7F\u7528 {{cmd}} \u5F00\u59CB\u65B0\u4F1A\u8BDD\u3002",
|
|
305649
305629
|
"No saved session found with ID {{sessionId}}. Run `rdmind --resume` without an ID to choose from existing sessions.": "\u672A\u53D1\u73B0 ID \u4E3A {{sessionId}} \u7684\u5DF2\u4FDD\u5B58\u4F1A\u8BDD\u3002\u8BF7\u8FD0\u884C\u4E0D\u5E26 ID \u7684 `rdmind --resume` \u4EE5\u4ECE\u73B0\u6709\u4F1A\u8BDD\u4E2D\u9009\u62E9\u3002",
|
|
305650
|
-
"Clear conversation history and free up context": "\u6E05\u9664\u5BF9\u8BDD\u5386\u53F2",
|
|
305630
|
+
"Clear conversation history and free up context": "\u6E05\u9664\u5BF9\u8BDD\u5386\u53F2\u5E76\u91CA\u653E\u4E0A\u4E0B\u6587",
|
|
305651
305631
|
"Compresses the context by replacing it with a summary.": "\u901A\u8FC7\u7528\u6458\u8981\u66FF\u6362\u6765\u538B\u7F29\u4E0A\u4E0B\u6587",
|
|
305652
305632
|
"open full RDMind documentation in your browser": "\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u5B8C\u6574\u7684 RDMind \u6587\u6863",
|
|
305653
305633
|
"Configuration not available.": "\u914D\u7F6E\u4E0D\u53EF\u7528",
|
|
@@ -305767,6 +305747,7 @@ var init_zh = __esm({
|
|
|
305767
305747
|
"(Use Enter to select{{tabText}})": "\uFF08\u4F7F\u7528 Enter \u9009\u62E9{{tabText}}\uFF09",
|
|
305768
305748
|
", Tab to change focus": "\uFF0CTab \u5207\u6362\u7126\u70B9",
|
|
305769
305749
|
"To see changes, RDMind must be restarted. Press r to exit and apply changes now.": "\u8981\u67E5\u770B\u66F4\u6539\uFF0C\u5FC5\u987B\u91CD\u542F RDMind\u3002\u6309 r \u9000\u51FA\u5E76\u7ACB\u5373\u5E94\u7528\u66F4\u6539\u3002",
|
|
305750
|
+
'The command "/{{command}}" is not supported in non-interactive mode.': '\u4E0D\u652F\u6301\u5728\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u4F7F\u7528\u547D\u4EE4 "/{{command}}"\u3002',
|
|
305770
305751
|
// ============================================================================
|
|
305771
305752
|
// Settings Labels
|
|
305772
305753
|
// ============================================================================
|
|
@@ -305998,6 +305979,10 @@ var init_zh = __esm({
|
|
|
305998
305979
|
"Already generating summary, wait for previous request to complete": "\u6B63\u5728\u751F\u6210\u6458\u8981\uFF0C\u8BF7\u7B49\u5F85\u4E0A\u4E00\u4E2A\u8BF7\u6C42\u5B8C\u6210",
|
|
305999
305980
|
"No conversation found to summarize.": "\u672A\u627E\u5230\u8981\u603B\u7ED3\u7684\u5BF9\u8BDD",
|
|
306000
305981
|
"Failed to generate project context summary: {{error}}": "\u751F\u6210\u9879\u76EE\u4E0A\u4E0B\u6587\u6458\u8981\u5931\u8D25\uFF1A{{error}}",
|
|
305982
|
+
"Saved project summary to {{filePathForDisplay}}.": "\u9879\u76EE\u6458\u8981\u5DF2\u4FDD\u5B58\u5230 {{filePathForDisplay}}",
|
|
305983
|
+
"Saving project summary...": "\u6B63\u5728\u4FDD\u5B58\u9879\u76EE\u6458\u8981...",
|
|
305984
|
+
"Generating project summary...": "\u6B63\u5728\u751F\u6210\u9879\u76EE\u6458\u8981...",
|
|
305985
|
+
"Failed to generate summary - no text content received from LLM response": "\u751F\u6210\u6458\u8981\u5931\u8D25 - \u672A\u4ECE LLM \u54CD\u5E94\u4E2D\u63A5\u6536\u5230\u6587\u672C\u5185\u5BB9",
|
|
306001
305986
|
// ============================================================================
|
|
306002
305987
|
// Commands - Model
|
|
306003
305988
|
// ============================================================================
|
|
@@ -306008,8 +305993,8 @@ var init_zh = __esm({
|
|
|
306008
305993
|
// ============================================================================
|
|
306009
305994
|
// Commands - Clear
|
|
306010
305995
|
// ============================================================================
|
|
306011
|
-
"
|
|
306012
|
-
"
|
|
305996
|
+
"Starting a new session, resetting chat, and clearing terminal.": "\u6B63\u5728\u5F00\u59CB\u65B0\u4F1A\u8BDD\uFF0C\u91CD\u7F6E\u804A\u5929\u5E76\u6E05\u5C4F\u3002",
|
|
305997
|
+
"Starting a new session and clearing.": "\u6B63\u5728\u5F00\u59CB\u65B0\u4F1A\u8BDD\u5E76\u6E05\u5C4F\u3002",
|
|
306013
305998
|
// ============================================================================
|
|
306014
305999
|
// Commands - Compress
|
|
306015
306000
|
// ============================================================================
|
|
@@ -306273,183 +306258,90 @@ var init_zh = __esm({
|
|
|
306273
306258
|
// ============================================================================
|
|
306274
306259
|
"Waiting for user confirmation...": "\u7B49\u5F85\u7528\u6237\u786E\u8BA4...",
|
|
306275
306260
|
"(esc to cancel, {{time}})": "\uFF08\u6309 esc \u53D6\u6D88\uFF0C{{time}}\uFF09",
|
|
306276
|
-
|
|
306277
|
-
|
|
306278
|
-
|
|
306279
|
-
|
|
306280
|
-
|
|
306281
|
-
|
|
306282
|
-
|
|
306283
|
-
|
|
306284
|
-
|
|
306285
|
-
|
|
306286
|
-
|
|
306287
|
-
|
|
306288
|
-
|
|
306289
|
-
|
|
306290
|
-
|
|
306291
|
-
|
|
306292
|
-
|
|
306293
|
-
|
|
306294
|
-
|
|
306295
|
-
|
|
306296
|
-
|
|
306297
|
-
|
|
306298
|
-
|
|
306299
|
-
|
|
306300
|
-
|
|
306301
|
-
|
|
306302
|
-
|
|
306303
|
-
|
|
306304
|
-
|
|
306305
|
-
|
|
306306
|
-
|
|
306307
|
-
|
|
306308
|
-
|
|
306309
|
-
|
|
306310
|
-
|
|
306311
|
-
|
|
306312
|
-
|
|
306313
|
-
|
|
306314
|
-
|
|
306315
|
-
|
|
306316
|
-
|
|
306317
|
-
|
|
306318
|
-
|
|
306319
|
-
|
|
306320
|
-
|
|
306321
|
-
|
|
306322
|
-
|
|
306323
|
-
|
|
306324
|
-
|
|
306325
|
-
|
|
306326
|
-
|
|
306327
|
-
|
|
306328
|
-
|
|
306329
|
-
|
|
306330
|
-
|
|
306331
|
-
|
|
306332
|
-
|
|
306333
|
-
|
|
306334
|
-
|
|
306335
|
-
|
|
306336
|
-
|
|
306337
|
-
|
|
306338
|
-
|
|
306339
|
-
|
|
306340
|
-
|
|
306341
|
-
|
|
306342
|
-
|
|
306343
|
-
|
|
306344
|
-
|
|
306345
|
-
|
|
306346
|
-
|
|
306347
|
-
|
|
306348
|
-
|
|
306349
|
-
|
|
306350
|
-
|
|
306351
|
-
|
|
306352
|
-
|
|
306353
|
-
|
|
306354
|
-
|
|
306355
|
-
|
|
306356
|
-
|
|
306357
|
-
|
|
306358
|
-
|
|
306359
|
-
|
|
306360
|
-
"Doing research on the latest memes...": "\u6B63\u5728\u7814\u7A76\u6700\u65B0\u7684\u8868\u60C5\u5305...",
|
|
306361
|
-
"Figuring out how to make this more witty...": "\u6B63\u5728\u60F3\u529E\u6CD5\u8BA9\u8FD9\u66F4\u6709\u8DA3...",
|
|
306362
|
-
"Hmmm... let me think...": "\u55EF...\u8BA9\u6211\u60F3\u60F3...",
|
|
306363
|
-
"What do you call a fish with no eyes? A fsh...": "\u6CA1\u6709\u773C\u775B\u7684\u9C7C\u53EB\u4EC0\u4E48\uFF1F\u4E00\u6761\u9C7C...",
|
|
306364
|
-
"Why did the computer go to therapy? It had too many bytes...": "\u4E3A\u4EC0\u4E48\u7535\u8111\u53BB\u770B\u5FC3\u7406\u533B\u751F\uFF1F\u56E0\u4E3A\u5B83\u6709\u592A\u591A\u5B57\u8282...",
|
|
306365
|
-
"Why don't programmers like nature? It has too many bugs...": "\u4E3A\u4EC0\u4E48\u7A0B\u5E8F\u5458\u4E0D\u559C\u6B22\u5927\u81EA\u7136\uFF1F\u56E0\u4E3A\u866B\u5B50\u592A\u591A\u4E86...",
|
|
306366
|
-
"Why do programmers prefer dark mode? Because light attracts bugs...": "\u4E3A\u4EC0\u4E48\u7A0B\u5E8F\u5458\u559C\u6B22\u6697\u8272\u6A21\u5F0F\uFF1F\u56E0\u4E3A\u5149\u4F1A\u5438\u5F15\u866B\u5B50...",
|
|
306367
|
-
"Why did the developer go broke? Because they used up all their cache...": "\u4E3A\u4EC0\u4E48\u5F00\u53D1\u8005\u7834\u4EA7\u4E86\uFF1F\u56E0\u4E3A\u4ED6\u4EEC\u7528\u5B8C\u4E86\u6240\u6709\u7F13\u5B58...",
|
|
306368
|
-
"What can you do with a broken pencil? Nothing, it's pointless...": "\u4F60\u80FD\u7528\u65AD\u4E86\u7684\u94C5\u7B14\u505A\u4EC0\u4E48\uFF1F\u4EC0\u4E48\u90FD\u4E0D\u80FD\uFF0C\u56E0\u4E3A\u5B83\u6CA1\u6709\u7B14\u5C16...",
|
|
306369
|
-
"Applying percussive maintenance...": "\u6B63\u5728\u5E94\u7528\u6572\u51FB\u7EF4\u62A4...",
|
|
306370
|
-
"Searching for the correct USB orientation...": "\u6B63\u5728\u5BFB\u627E\u6B63\u786E\u7684 USB \u65B9\u5411...",
|
|
306371
|
-
"Ensuring the magic smoke stays inside the wires...": "\u786E\u4FDD\u9B54\u6CD5\u70DF\u96FE\u7559\u5728\u7535\u7EBF\u5185...",
|
|
306372
|
-
"Rewriting in Rust for no particular reason...": "\u6B63\u5728\u7528 Rust \u91CD\u5199\uFF0C\u6CA1\u6709\u7279\u522B\u7684\u539F\u56E0...",
|
|
306373
|
-
"Trying to exit Vim...": "\u6B63\u5728\u5C1D\u8BD5\u9000\u51FA Vim...",
|
|
306374
|
-
"Spinning up the hamster wheel...": "\u6B63\u5728\u542F\u52A8\u4ED3\u9F20\u8F6E...",
|
|
306375
|
-
"That's not a bug, it's an undocumented feature...": "\u8FD9\u4E0D\u662F\u4E00\u4E2A\u9519\u8BEF\uFF0C\u8FD9\u662F\u4E00\u4E2A\u672A\u8BB0\u5F55\u7684\u529F\u80FD...",
|
|
306376
|
-
"Engage.": "\u542F\u52A8\u3002",
|
|
306377
|
-
"I'll be back... with an answer.": "\u6211\u4F1A\u56DE\u6765\u7684...\u5E26\u7740\u7B54\u6848\u3002",
|
|
306378
|
-
"My other process is a TARDIS...": "\u6211\u7684\u53E6\u4E00\u4E2A\u8FDB\u7A0B\u662F TARDIS...",
|
|
306379
|
-
"Communing with the machine spirit...": "\u6B63\u5728\u4E0E\u673A\u5668\u7CBE\u795E\u4EA4\u6D41...",
|
|
306380
|
-
"Letting the thoughts marinate...": "\u8BA9\u60F3\u6CD5\u6162\u6162\u915D\u917F...",
|
|
306381
|
-
"Just remembered where I put my keys...": "\u521A\u521A\u60F3\u8D77\u6211\u628A\u94A5\u5319\u653E\u5728\u54EA\u91CC\u4E86...",
|
|
306382
|
-
"Pondering the orb...": "\u6B63\u5728\u601D\u8003\u7403\u4F53...",
|
|
306383
|
-
"I've seen things you people wouldn't believe... like a user who reads loading messages.": "\u6211\u89C1\u8FC7\u4F60\u4EEC\u4E0D\u4F1A\u76F8\u4FE1\u7684\u4E8B\u60C5...\u6BD4\u5982\u4E00\u4E2A\u9605\u8BFB\u52A0\u8F7D\u6D88\u606F\u7684\u7528\u6237\u3002",
|
|
306384
|
-
"Initiating thoughtful gaze...": "\u6B63\u5728\u542F\u52A8\u6DF1\u601D\u51DD\u89C6...",
|
|
306385
|
-
"What's a computer's favorite snack? Microchips.": "\u7535\u8111\u6700\u559C\u6B22\u7684\u96F6\u98DF\u662F\u4EC0\u4E48\uFF1F\u5FAE\u82AF\u7247\u3002",
|
|
306386
|
-
"Why do Java developers wear glasses? Because they don't C#.": "\u4E3A\u4EC0\u4E48 Java \u5F00\u53D1\u8005\u6234\u773C\u955C\uFF1F\u56E0\u4E3A\u4ED6\u4EEC\u4E0D\u4F1A C#\u3002",
|
|
306387
|
-
"Charging the laser... pew pew!": "\u6B63\u5728\u7ED9\u6FC0\u5149\u5145\u7535...\u7830\u7830\uFF01",
|
|
306388
|
-
"Dividing by zero... just kidding!": "\u9664\u4EE5\u96F6...\u53EA\u662F\u5F00\u73A9\u7B11\uFF01",
|
|
306389
|
-
"Looking for an adult superviso... I mean, processing.": "\u6B63\u5728\u5BFB\u627E\u6210\u4EBA\u76D1\u7763...\u6211\u662F\u8BF4\uFF0C\u5904\u7406\u4E2D\u3002",
|
|
306390
|
-
"Making it go beep boop.": "\u8BA9\u5B83\u53D1\u51FA\u54D4\u54D4\u58F0\u3002",
|
|
306391
|
-
"Buffering... because even AIs need a moment.": "\u6B63\u5728\u7F13\u51B2...\u56E0\u4E3A\u5373\u4F7F\u662F AI \u4E5F\u9700\u8981\u7247\u523B\u3002",
|
|
306392
|
-
"Entangling quantum particles for a faster response...": "\u6B63\u5728\u7EA0\u7F20\u91CF\u5B50\u7C92\u5B50\u4EE5\u83B7\u5F97\u66F4\u5FEB\u7684\u56DE\u590D...",
|
|
306393
|
-
"Polishing the chrome... on the algorithms.": "\u6B63\u5728\u6253\u78E8\u94EC...\u5728\u7B97\u6CD5\u4E0A\u3002",
|
|
306394
|
-
"Are you not entertained? (Working on it!)": "\u4F60\u4E0D\u89C9\u5F97\u6709\u8DA3\u5417\uFF1F\uFF08\u6B63\u5728\u52AA\u529B\uFF01\uFF09",
|
|
306395
|
-
"Summoning the code gremlins... to help, of course.": "\u6B63\u5728\u53EC\u5524\u4EE3\u7801\u5C0F\u7CBE\u7075...\u5F53\u7136\u662F\u6765\u5E2E\u5FD9\u7684\u3002",
|
|
306396
|
-
"Just waiting for the dial-up tone to finish...": "\u53EA\u662F\u7B49\u5F85\u62E8\u53F7\u97F3\u7ED3\u675F...",
|
|
306397
|
-
"Recalibrating the humor-o-meter.": "\u6B63\u5728\u91CD\u65B0\u6821\u51C6\u5E7D\u9ED8\u8BA1\u3002",
|
|
306398
|
-
"My other loading screen is even funnier.": "\u6211\u7684\u53E6\u4E00\u4E2A\u52A0\u8F7D\u5C4F\u5E55\u66F4\u6709\u8DA3\u3002",
|
|
306399
|
-
"Pretty sure there's a cat walking on the keyboard somewhere...": "\u5F88\u786E\u5B9A\u6709\u53EA\u732B\u5728\u67D0\u4E2A\u5730\u65B9\u952E\u76D8\u4E0A\u8D70...",
|
|
306400
|
-
"Enhancing... Enhancing... Still loading.": "\u6B63\u5728\u589E\u5F3A...\u6B63\u5728\u589E\u5F3A...\u4ECD\u5728\u52A0\u8F7D\u3002",
|
|
306401
|
-
"It's not a bug, it's a feature... of this loading screen.": "\u8FD9\u4E0D\u662F\u4E00\u4E2A\u9519\u8BEF\uFF0C\u8FD9\u662F\u4E00\u4E2A\u529F\u80FD...\u8FD9\u4E2A\u52A0\u8F7D\u5C4F\u5E55\u7684\u529F\u80FD\u3002",
|
|
306402
|
-
"Have you tried turning it off and on again? (The loading screen, not me.)": "\u4F60\u8BD5\u8FC7\u628A\u5B83\u5173\u6389\u518D\u6253\u5F00\u5417\uFF1F\uFF08\u52A0\u8F7D\u5C4F\u5E55\uFF0C\u4E0D\u662F\u6211\u3002\uFF09",
|
|
306403
|
-
"Constructing additional pylons...": "\u6B63\u5728\u5EFA\u9020\u989D\u5916\u7684\u80FD\u91CF\u5854...",
|
|
306404
|
-
"Summoning the soul of programmers...": "\u6B63\u5728\u53EC\u5524\u7A0B\u5E8F\u5458\u7684\u7075\u9B42...",
|
|
306405
|
-
"Fixing that bug that's not a bug, it's a feature...": "\u6B63\u5728\u4FEE\u590D\u90A3\u4E2A\u4E0D\u7B97 bug \u7684 feature...",
|
|
306406
|
-
"Removing pinyin comments from code...": "\u6B63\u5728\u6E05\u9664\u4EE3\u7801\u91CC\u7684\u62FC\u97F3\u6CE8\u91CA...",
|
|
306407
|
-
"Debating whether array index starts from 0 or 1...": "\u6B63\u5728\u4E89\u8BBA\u6570\u7EC4\u4E0B\u6807\u4ECE 0 \u8FD8\u662F\u4ECE 1...",
|
|
306408
|
-
"Thinking about refactoring...": "\u6B63\u5728\u601D\u8003\u8981\u4E0D\u8981\u91CD\u6784...",
|
|
306409
|
-
"Cleaning up stack overflow...": "\u6B63\u5728\u6E05\u7406\u5806\u6808\u6EA2\u51FA...",
|
|
306410
|
-
"Naming variables properly...": "\u6B63\u5728\u7ED9\u53D8\u91CF\u8D77\u4E2A\u597D\u540D\u5B57...",
|
|
306411
|
-
"Commenting code written 3 months ago...": "\u6B63\u5728\u6CE8\u91CA\u4E09\u4E2A\u6708\u524D\u5199\u7684\u4EE3\u7801...",
|
|
306412
|
-
"Praying for no bugs...": "\u6B63\u5728\u7948\u7977\u4E0D\u8981\u6709 bug...",
|
|
306413
|
-
"Resolving dependencies...": "\u6B63\u5728\u89E3\u51B3\u4F9D\u8D56\u5173\u7CFB...",
|
|
306414
|
-
"Waiting for product manager to change requirements...": "\u6B63\u5728\u7B49\u5F85\u4EA7\u54C1\u7ECF\u7406\u6539\u9700\u6C42...",
|
|
306415
|
-
"Postponing project deadline...": "\u6B63\u5728\u5EF6\u671F\u9879\u76EE\u622A\u6B62\u65E5\u671F...",
|
|
306416
|
-
'Preparing another "almost done"...': '\u6B63\u5728\u51C6\u5907\u53C8\u4E00\u6B21"\u5FEB\u597D\u4E86"...',
|
|
306417
|
-
"Taking a break...": "\u6B63\u5728\u6478\u9C7C...",
|
|
306418
|
-
"Making goji berry tea...": "\u6B63\u5728\u6CE1\u67B8\u675E...",
|
|
306419
|
-
"Ordering takeout...": "\u6B63\u5728\u70B9\u5916\u5356...",
|
|
306420
|
-
"Pretending to be busy...": "\u6B63\u5728\u5047\u88C5\u5F88\u5FD9...",
|
|
306421
|
-
"Recharging faith...": "\u6B63\u5728\u5145\u503C\u4FE1\u4EF0...",
|
|
306422
|
-
"Downloading more RAM...": "\u6B63\u5728\u4E0B\u8F7D\u66F4\u591A\u5185\u5B58...",
|
|
306423
|
-
"Feeding the server...": "\u6B63\u5728\u6295\u5582\u670D\u52A1\u5668...",
|
|
306424
|
-
"Waking up sleeping code...": "\u6B63\u5728\u5524\u9192\u6C89\u7761\u7684\u4EE3\u7801...",
|
|
306425
|
-
"Feeding data to AI...": "\u6B63\u5728\u7ED9 AI \u5582\u6570\u636E...",
|
|
306426
|
-
"Opening imagination...": "\u6B63\u5728\u6253\u5F00\u8111\u6D1E...",
|
|
306427
|
-
"Boiling water for tea...": "\u6B63\u5728\u70E7\u5F00\u6C34\u6CE1\u8336...",
|
|
306428
|
-
"Waiting for the elevator...": "\u6B63\u5728\u7B49\u7535\u68AF...",
|
|
306429
|
-
"Taking a number in queue...": "\u6B63\u5728\u6392\u961F\u53D6\u53F7...",
|
|
306430
|
-
"Waiting for traffic light...": "\u6B63\u5728\u7B49\u7EA2\u7EFF\u706F...",
|
|
306431
|
-
"Charging...": "\u6B63\u5728\u5145\u7535\u4E2D...",
|
|
306432
|
-
"Buffering life...": "\u6B63\u5728\u7F13\u51B2\u4EBA\u751F...",
|
|
306433
|
-
"Contemplating the meaning of life...": "\u6B63\u5728\u601D\u8003\u4EBA\u751F\u7684\u610F\u4E49...",
|
|
306434
|
-
"What to eat today? Thinking...": "\u4ECA\u5929\u5403\u4EC0\u4E48\uFF1F\u6B63\u5728\u601D\u8003\u4E2D...",
|
|
306435
|
-
"Pretending to work...": "\u6B63\u5728\u5047\u88C5\u5728\u5DE5\u4F5C...",
|
|
306436
|
-
"Let me think, just a moment...": "\u8BA9\u6211\u60F3\u60F3\uFF0C\u7A0D\u7B49\u4E00\u4E0B...",
|
|
306437
|
-
"Brewing inspiration...": "\u6B63\u5728\u915D\u917F\u7075\u611F...",
|
|
306438
|
-
"Take a deep breath, almost done...": "\u6DF1\u547C\u5438\uFF0C\u9A6C\u4E0A\u5C31\u597D...",
|
|
306439
|
-
"Don't worry, good things take time...": "\u4E0D\u8981\u7740\u6025\uFF0C\u597D\u996D\u4E0D\u6015\u665A...",
|
|
306440
|
-
"Stay calm, exciting things coming...": "\u7A0D\u5B89\u52FF\u8E81\uFF0C\u7CBE\u5F69\u5373\u5C06\u5448\u73B0...",
|
|
306441
|
-
"Greeting the server...": "\u6B63\u5728\u5411\u670D\u52A1\u5668\u95EE\u597D...",
|
|
306442
|
-
"Organizing thoughts...": "\u6B63\u5728\u6574\u7406\u601D\u7EEA...",
|
|
306443
|
-
"Preparing my words...": "\u6B63\u5728\u7EC4\u7EC7\u8BED\u8A00...",
|
|
306444
|
-
"Looking up information...": "\u6B63\u5728\u67E5\u9605\u8D44\u6599...",
|
|
306445
|
-
"Sorting out my thoughts...": "\u8BA9\u6211\u7406\u4E00\u7406\u601D\u8DEF...",
|
|
306446
|
-
"Analyzing the problem...": "\u6B63\u5728\u5206\u6790\u95EE\u9898...",
|
|
306447
|
-
"Looking for the best solution...": "\u6B63\u5728\u5BFB\u627E\u6700\u4F73\u65B9\u6848...",
|
|
306448
|
-
"Loading...": "\u6B63\u5728\u52A0\u8F7D...",
|
|
306449
|
-
"Processing, please wait...": "\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u5019...",
|
|
306450
|
-
"Almost there...": "\u9A6C\u4E0A\u5C31\u597D...",
|
|
306451
|
-
"Working hard...": "\u6B63\u5728\u52AA\u529B\u5DE5\u4F5C\u4E2D...",
|
|
306452
|
-
"Almost... almost...": "\u5FEB\u4E86\uFF0C\u5FEB\u4E86...",
|
|
306261
|
+
WITTY_LOADING_PHRASES: [
|
|
306262
|
+
// --- 编程/技术相关 ---
|
|
306263
|
+
"\u6B63\u5728\u53EC\u5524\u7A0B\u5E8F\u5458\u7684\u7075\u9B42...",
|
|
306264
|
+
"\u6B63\u5728\u4FEE\u590D\u90A3\u4E2A\u4E0D\u7B97 bug \u7684 feature...",
|
|
306265
|
+
"\u6B63\u5728\u6E05\u9664\u4EE3\u7801\u91CC\u7684\u62FC\u97F3\u6CE8\u91CA...",
|
|
306266
|
+
"\u6B63\u5728\u4E89\u8BBA\u6570\u7EC4\u4E0B\u6807\u4ECE 0 \u8FD8\u662F\u4ECE 1...",
|
|
306267
|
+
"\u6B63\u5728\u601D\u8003\u8981\u4E0D\u8981\u91CD\u6784...",
|
|
306268
|
+
"\u6B63\u5728\u5BFB\u627E\u6D88\u5931\u7684\u5206\u53F7...",
|
|
306269
|
+
"\u6B63\u5728\u6E05\u7406\u5806\u6808\u6EA2\u51FA...",
|
|
306270
|
+
"\u6B63\u5728\u7ED9\u53D8\u91CF\u8D77\u4E2A\u597D\u540D\u5B57...",
|
|
306271
|
+
"\u6B63\u5728\u6CE8\u91CA\u4E09\u4E2A\u6708\u524D\u5199\u7684\u4EE3\u7801...",
|
|
306272
|
+
"\u6B63\u5728\u7948\u7977\u4E0D\u8981\u6709 bug...",
|
|
306273
|
+
"\u6B63\u5728\u5C1D\u8BD5\u9000\u51FA Vim...",
|
|
306274
|
+
"\u6B63\u5728\u5BFB\u627E\u6B63\u786E\u7684 USB \u65B9\u5411...",
|
|
306275
|
+
"\u8FD9\u4E0D\u662F\u4E00\u4E2A\u9519\u8BEF\uFF0C\u8FD9\u662F\u4E00\u4E2A\u672A\u8BB0\u5F55\u7684\u529F\u80FD...",
|
|
306276
|
+
"\u6B63\u5728\u6253\u78E8\u7B97\u6CD5...",
|
|
306277
|
+
"\u6B63\u5728\u7F16\u8BD1\u667A\u6167...",
|
|
306278
|
+
"\u6B63\u5728\u89E3\u5F00\u795E\u7ECF\u7F51\u7EDC...",
|
|
306279
|
+
"\u6B63\u5728\u5783\u573E\u56DE\u6536...\u9A6C\u4E0A\u56DE\u6765...",
|
|
306280
|
+
"\u6B63\u5728\u89E3\u51B3\u4F9D\u8D56\u5173\u7CFB...",
|
|
306281
|
+
"\u6B63\u5728\u5C06\u5496\u5561\u8F6C\u6362\u4E3A\u4EE3\u7801...",
|
|
306282
|
+
// --- 工作/职场相关 ---
|
|
306283
|
+
"\u6B63\u5728\u7B49\u5F85\u4EA7\u54C1\u7ECF\u7406\u6539\u9700\u6C42...",
|
|
306284
|
+
"\u6B63\u5728\u5EF6\u671F\u9879\u76EE\u622A\u6B62\u65E5\u671F...",
|
|
306285
|
+
'\u6B63\u5728\u51C6\u5907\u53C8\u4E00\u6B21"\u5FEB\u597D\u4E86"...',
|
|
306286
|
+
"\u6B63\u5728\u6478\u9C7C...",
|
|
306287
|
+
"\u6B63\u5728\u6CE1\u67B8\u675E...",
|
|
306288
|
+
"\u6B63\u5728\u70B9\u5916\u5356...",
|
|
306289
|
+
"\u6B63\u5728\u5047\u88C5\u5F88\u5FD9...",
|
|
306290
|
+
// --- 合作愉快系列 ---
|
|
306291
|
+
"\u6B63\u5728\u8BE2\u95EE\u4EA7\u54C1\u7ECF\u7406\uFF1A\u8FD9\u9700\u6C42\u662F\u771F\u7684\u5417\uFF1F",
|
|
306292
|
+
"\u6B63\u5728\u7ED9\u4EA7\u54C1\u7ECF\u7406\u753B\u997C\uFF0C\u8BF7\u7A0D\u7B49...",
|
|
306293
|
+
// --- 温暖治愈系列 ---
|
|
306294
|
+
"\u6BCF\u4E00\u884C\u4EE3\u7801\uFF0C\u90FD\u5728\u52AA\u529B\u8BA9\u4E16\u754C\u53D8\u5F97\u66F4\u597D\u4E00\u70B9\u70B9...",
|
|
306295
|
+
"\u6BCF\u4E00\u4E2A\u4F1F\u5927\u7684\u60F3\u6CD5\uFF0C\u90FD\u503C\u5F97\u8FD9\u4EFD\u8010\u5FC3\u7684\u7B49\u5F85...",
|
|
306296
|
+
"\u522B\u6025\uFF0C\u7F8E\u597D\u7684\u4E8B\u7269\u603B\u662F\u9700\u8981\u4E00\u70B9\u65F6\u95F4\u53BB\u915D\u917F...",
|
|
306297
|
+
"\u613F\u4F60\u7684\u4EE3\u7801\u6C38\u65E0 Bug\uFF0C\u613F\u4F60\u7684\u68A6\u60F3\u7EC8\u5C06\u6210\u771F...",
|
|
306298
|
+
"\u54EA\u6015\u53EA\u6709 0.1% \u7684\u8FDB\u5EA6\uFF0C\u4E5F\u662F\u5728\u5411\u76EE\u6807\u9760\u8FD1...",
|
|
306299
|
+
"\u52A0\u8F7D\u7684\u662F\u5B57\u8282\uFF0C\u627F\u8F7D\u7684\u662F\u5BF9\u6280\u672F\u7684\u70ED\u7231...",
|
|
306300
|
+
// --- 互联网文化/梗 ---
|
|
306301
|
+
"\u6B63\u5728\u5145\u503C\u4FE1\u4EF0...",
|
|
306302
|
+
"\u6B63\u5728\u4E0B\u8F7D\u66F4\u591A\u5185\u5B58...",
|
|
306303
|
+
"\u6B63\u5728\u6295\u5582\u670D\u52A1\u5668...",
|
|
306304
|
+
"\u6B63\u5728\u5524\u9192\u6C89\u7761\u7684\u4EE3\u7801...",
|
|
306305
|
+
"\u6B63\u5728\u7ED9 AI \u5582\u6570\u636E...",
|
|
306306
|
+
"\u6B63\u5728\u6253\u5F00\u8111\u6D1E...",
|
|
306307
|
+
// --- 日常生活 ---
|
|
306308
|
+
"\u6B63\u5728\u70E7\u5F00\u6C34\u6CE1\u8336...",
|
|
306309
|
+
"\u6B63\u5728\u7B49\u7535\u68AF...",
|
|
306310
|
+
"\u6B63\u5728\u6392\u961F\u53D6\u53F7...",
|
|
306311
|
+
"\u6B63\u5728\u7B49\u7EA2\u7EFF\u706F...",
|
|
306312
|
+
"\u6B63\u5728\u5145\u7535\u4E2D...",
|
|
306313
|
+
"\u6B63\u5728\u7F13\u51B2\u4EBA\u751F...",
|
|
306314
|
+
// --- 轻松幽默 ---
|
|
306315
|
+
"\u6B63\u5728\u601D\u8003\u4EBA\u751F\u7684\u610F\u4E49...",
|
|
306316
|
+
"\u4ECA\u5929\u5403\u4EC0\u4E48\uFF1F\u6B63\u5728\u601D\u8003\u4E2D...",
|
|
306317
|
+
"\u6B63\u5728\u5047\u88C5\u5728\u5DE5\u4F5C...",
|
|
306318
|
+
"\u8BA9\u6211\u60F3\u60F3\uFF0C\u7A0D\u7B49\u4E00\u4E0B...",
|
|
306319
|
+
"\u6B63\u5728\u915D\u917F\u7075\u611F...",
|
|
306320
|
+
"\u6DF1\u547C\u5438\uFF0C\u9A6C\u4E0A\u5C31\u597D...",
|
|
306321
|
+
"\u4E0D\u8981\u7740\u6025\uFF0C\u597D\u996D\u4E0D\u6015\u665A...",
|
|
306322
|
+
"\u7A0D\u5B89\u52FF\u8E81\uFF0C\u7CBE\u5F69\u5373\u5C06\u5448\u73B0...",
|
|
306323
|
+
"\u55EF...\u8BA9\u6211\u60F3\u60F3...",
|
|
306324
|
+
// --- 技术向但接地气 ---
|
|
306325
|
+
"\u6B63\u5728\u5411\u670D\u52A1\u5668\u95EE\u597D...",
|
|
306326
|
+
"\u6B63\u5728\u6574\u7406\u601D\u7EEA...",
|
|
306327
|
+
"\u6B63\u5728\u7EC4\u7EC7\u8BED\u8A00...",
|
|
306328
|
+
"\u6B63\u5728\u67E5\u9605\u8D44\u6599...",
|
|
306329
|
+
"\u8BA9\u6211\u7406\u4E00\u7406\u601D\u8DEF...",
|
|
306330
|
+
"\u6B63\u5728\u5206\u6790\u95EE\u9898...",
|
|
306331
|
+
"\u6B63\u5728\u5BFB\u627E\u6700\u4F73\u65B9\u6848...",
|
|
306332
|
+
"\u6B63\u5728\u542F\u52A8\u8BA4\u77E5\u5904\u7406\u5668...",
|
|
306333
|
+
"\u6B63\u5728\u5236\u4F5C\u503C\u5F97\u60A8\u8010\u5FC3\u7B49\u5F85\u7684\u56DE\u590D...",
|
|
306334
|
+
// --- 保持通用性 ---
|
|
306335
|
+
"\u6B63\u5728\u52A0\u8F7D...",
|
|
306336
|
+
"\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u5019...",
|
|
306337
|
+
"\u9A6C\u4E0A\u5C31\u597D...",
|
|
306338
|
+
"\u6B63\u5728\u52AA\u529B\u5DE5\u4F5C\u4E2D...",
|
|
306339
|
+
"\u5FEB\u4E86\uFF0C\u5FEB\u4E86...",
|
|
306340
|
+
"\u5FEB\u5230\u4E86...\u53EF\u80FD..."
|
|
306341
|
+
],
|
|
306342
|
+
// ============================================================================
|
|
306343
|
+
// OpenSpec Commands
|
|
306344
|
+
// ============================================================================
|
|
306453
306345
|
"Initialize OpenSpec in a project with RDMind integration": "\u5728\u9879\u76EE\u4E2D\u521D\u59CB\u5316 OpenSpec\uFF08\u96C6\u6210 RDMind\uFF09",
|
|
306454
306346
|
"Initialize OpenSpec in the current directory": "\u5728\u5F53\u524D\u76EE\u5F55\u521D\u59CB\u5316 OpenSpec",
|
|
306455
306347
|
"Scaffold a new OpenSpec change and validate strictly.": "\u642D\u5EFA\u65B0\u7684 OpenSpec \u53D8\u66F4\u5E76\u4E25\u683C\u9A8C\u8BC1\u3002",
|
|
@@ -332090,7 +331982,7 @@ var loadYoga = (() => {
|
|
|
332090
331982
|
pa.unshift(a2);
|
|
332091
331983
|
}
|
|
332092
331984
|
__name(sa, "sa");
|
|
332093
|
-
var F4 = 0,
|
|
331985
|
+
var F4 = 0, ta2 = null, G2 = null;
|
|
332094
331986
|
function x3(a2) {
|
|
332095
331987
|
if (h3.onAbort) h3.onAbort(a2);
|
|
332096
331988
|
a2 = "Aborted(" + a2 + ")";
|
|
@@ -333233,7 +333125,7 @@ var loadYoga = (() => {
|
|
|
333233
333125
|
qa.unshift(h3.asm.F);
|
|
333234
333126
|
F4--;
|
|
333235
333127
|
h3.monitorRunDependencies && h3.monitorRunDependencies(F4);
|
|
333236
|
-
0 == F4 && (null !==
|
|
333128
|
+
0 == F4 && (null !== ta2 && (clearInterval(ta2), ta2 = null), G2 && (e4 = G2, G2 = null, e4()));
|
|
333237
333129
|
}
|
|
333238
333130
|
__name(a2, "a");
|
|
333239
333131
|
function b2(e4) {
|
|
@@ -344157,7 +344049,7 @@ __name(getPackageJson, "getPackageJson");
|
|
|
344157
344049
|
// packages/cli/src/utils/version.ts
|
|
344158
344050
|
async function getCliVersion() {
|
|
344159
344051
|
const pkgJson = await getPackageJson();
|
|
344160
|
-
return "0.1.8
|
|
344052
|
+
return "0.1.8";
|
|
344161
344053
|
}
|
|
344162
344054
|
__name(getCliVersion, "getCliVersion");
|
|
344163
344055
|
|
|
@@ -348122,6 +348014,26 @@ import * as path83 from "node:path";
|
|
|
348122
348014
|
import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
348123
348015
|
import { homedir as homedir18 } from "node:os";
|
|
348124
348016
|
|
|
348017
|
+
// packages/cli/src/i18n/languages.ts
|
|
348018
|
+
init_esbuild_shims();
|
|
348019
|
+
var SUPPORTED_LANGUAGES = [
|
|
348020
|
+
{
|
|
348021
|
+
code: "en",
|
|
348022
|
+
id: "en-US",
|
|
348023
|
+
fullName: "English"
|
|
348024
|
+
},
|
|
348025
|
+
{
|
|
348026
|
+
code: "zh",
|
|
348027
|
+
id: "zh-CN",
|
|
348028
|
+
fullName: "Chinese"
|
|
348029
|
+
}
|
|
348030
|
+
];
|
|
348031
|
+
function getLanguageNameFromLocale(locale) {
|
|
348032
|
+
const lang = SUPPORTED_LANGUAGES.find((l3) => l3.code === locale);
|
|
348033
|
+
return lang?.fullName || "English";
|
|
348034
|
+
}
|
|
348035
|
+
__name(getLanguageNameFromLocale, "getLanguageNameFromLocale");
|
|
348036
|
+
|
|
348125
348037
|
// import("./locales/**/*.js") in packages/cli/src/i18n/index.ts
|
|
348126
348038
|
var globImport_locales_js = __glob({
|
|
348127
348039
|
"./locales/en.js": () => Promise.resolve().then(() => (init_en3(), en_exports)),
|
|
@@ -348249,9 +348161,20 @@ function getCurrentLanguage() {
|
|
|
348249
348161
|
__name(getCurrentLanguage, "getCurrentLanguage");
|
|
348250
348162
|
function t4(key, params) {
|
|
348251
348163
|
const translation = translations[key] ?? key;
|
|
348164
|
+
if (Array.isArray(translation)) {
|
|
348165
|
+
return key;
|
|
348166
|
+
}
|
|
348252
348167
|
return interpolate(translation, params);
|
|
348253
348168
|
}
|
|
348254
348169
|
__name(t4, "t");
|
|
348170
|
+
function ta(key) {
|
|
348171
|
+
const translation = translations[key];
|
|
348172
|
+
if (Array.isArray(translation)) {
|
|
348173
|
+
return translation;
|
|
348174
|
+
}
|
|
348175
|
+
return [];
|
|
348176
|
+
}
|
|
348177
|
+
__name(ta, "ta");
|
|
348255
348178
|
async function initializeI18n(lang) {
|
|
348256
348179
|
await setLanguageAsync(lang ?? "auto");
|
|
348257
348180
|
}
|
|
@@ -351625,10 +351548,346 @@ function validateTheme(settings) {
|
|
|
351625
351548
|
}
|
|
351626
351549
|
__name(validateTheme, "validateTheme");
|
|
351627
351550
|
|
|
351551
|
+
// packages/cli/src/ui/commands/languageCommand.ts
|
|
351552
|
+
init_esbuild_shims();
|
|
351553
|
+
|
|
351554
|
+
// packages/cli/src/ui/commands/types.ts
|
|
351555
|
+
init_esbuild_shims();
|
|
351556
|
+
|
|
351557
|
+
// packages/cli/src/ui/commands/languageCommand.ts
|
|
351558
|
+
init_settings();
|
|
351559
|
+
init_core5();
|
|
351560
|
+
import * as fs80 from "node:fs";
|
|
351561
|
+
import * as path86 from "node:path";
|
|
351562
|
+
var LLM_OUTPUT_LANGUAGE_RULE_FILENAME = "output-language.md";
|
|
351563
|
+
var LLM_OUTPUT_LANGUAGE_MARKER_PREFIX = "qwen-code:llm-output-language:";
|
|
351564
|
+
function parseUiLanguageArg(input) {
|
|
351565
|
+
const lowered = input.trim().toLowerCase();
|
|
351566
|
+
if (!lowered) return null;
|
|
351567
|
+
for (const lang of SUPPORTED_LANGUAGES) {
|
|
351568
|
+
if (lowered === lang.code || lowered === lang.id.toLowerCase() || lowered === lang.fullName.toLowerCase()) {
|
|
351569
|
+
return lang.code;
|
|
351570
|
+
}
|
|
351571
|
+
}
|
|
351572
|
+
return null;
|
|
351573
|
+
}
|
|
351574
|
+
__name(parseUiLanguageArg, "parseUiLanguageArg");
|
|
351575
|
+
function formatUiLanguageDisplay(lang) {
|
|
351576
|
+
const option2 = SUPPORTED_LANGUAGES.find((o3) => o3.code === lang);
|
|
351577
|
+
return option2 ? `${option2.fullName}\uFF08${option2.id}\uFF09` : lang;
|
|
351578
|
+
}
|
|
351579
|
+
__name(formatUiLanguageDisplay, "formatUiLanguageDisplay");
|
|
351580
|
+
function sanitizeLanguageForMarker(language) {
|
|
351581
|
+
return language.replace(/[\r\n]/g, " ").replace(/--!?>/g, "").replace(/--/g, "");
|
|
351582
|
+
}
|
|
351583
|
+
__name(sanitizeLanguageForMarker, "sanitizeLanguageForMarker");
|
|
351584
|
+
function generateLlmOutputLanguageRule(language) {
|
|
351585
|
+
const markerLanguage = sanitizeLanguageForMarker(language);
|
|
351586
|
+
return `# Output language preference: ${language}
|
|
351587
|
+
<!-- ${LLM_OUTPUT_LANGUAGE_MARKER_PREFIX} ${markerLanguage} -->
|
|
351588
|
+
|
|
351589
|
+
## Goal
|
|
351590
|
+
Prefer responding in **${language}** for normal assistant messages and explanations.
|
|
351591
|
+
|
|
351592
|
+
## Keep technical artifacts unchanged
|
|
351593
|
+
Do **not** translate or rewrite:
|
|
351594
|
+
- Code blocks, CLI commands, file paths, stack traces, logs, JSON keys, identifiers
|
|
351595
|
+
- Exact quoted text from the user (keep quotes verbatim)
|
|
351596
|
+
|
|
351597
|
+
## When a conflict exists
|
|
351598
|
+
If higher-priority instructions (system/developer) require a different behavior, follow them.
|
|
351599
|
+
|
|
351600
|
+
## Tool / system outputs
|
|
351601
|
+
Raw tool/system outputs may contain fixed-format English. Preserve them verbatim, and if needed, add a short **${language}** explanation below.
|
|
351602
|
+
`;
|
|
351603
|
+
}
|
|
351604
|
+
__name(generateLlmOutputLanguageRule, "generateLlmOutputLanguageRule");
|
|
351605
|
+
function getLlmOutputLanguageRulePath() {
|
|
351606
|
+
return path86.join(
|
|
351607
|
+
Storage.getGlobalQwenDir(),
|
|
351608
|
+
LLM_OUTPUT_LANGUAGE_RULE_FILENAME
|
|
351609
|
+
);
|
|
351610
|
+
}
|
|
351611
|
+
__name(getLlmOutputLanguageRulePath, "getLlmOutputLanguageRulePath");
|
|
351612
|
+
function normalizeLanguageName(language) {
|
|
351613
|
+
const lowered = language.toLowerCase();
|
|
351614
|
+
const fullName = getLanguageNameFromLocale(lowered);
|
|
351615
|
+
if (fullName !== "English" || lowered === "en") {
|
|
351616
|
+
return fullName;
|
|
351617
|
+
}
|
|
351618
|
+
return language;
|
|
351619
|
+
}
|
|
351620
|
+
__name(normalizeLanguageName, "normalizeLanguageName");
|
|
351621
|
+
function extractLlmOutputLanguageFromRuleFileContent(content) {
|
|
351622
|
+
const markerMatch = content.match(
|
|
351623
|
+
new RegExp(
|
|
351624
|
+
String.raw`<!--\s*${LLM_OUTPUT_LANGUAGE_MARKER_PREFIX}\s*(.*?)\s*-->`,
|
|
351625
|
+
"i"
|
|
351626
|
+
)
|
|
351627
|
+
);
|
|
351628
|
+
if (markerMatch?.[1]) {
|
|
351629
|
+
const lang = markerMatch[1].trim();
|
|
351630
|
+
if (lang) return lang;
|
|
351631
|
+
}
|
|
351632
|
+
const headingMatch = content.match(
|
|
351633
|
+
/^#.*?CRITICAL:\s*(.*?)\s+Output Language Rule\b/im
|
|
351634
|
+
);
|
|
351635
|
+
if (headingMatch?.[1]) {
|
|
351636
|
+
const lang = headingMatch[1].trim();
|
|
351637
|
+
if (lang) return lang;
|
|
351638
|
+
}
|
|
351639
|
+
return null;
|
|
351640
|
+
}
|
|
351641
|
+
__name(extractLlmOutputLanguageFromRuleFileContent, "extractLlmOutputLanguageFromRuleFileContent");
|
|
351642
|
+
function initializeLlmOutputLanguage() {
|
|
351643
|
+
const filePath = getLlmOutputLanguageRulePath();
|
|
351644
|
+
if (fs80.existsSync(filePath)) {
|
|
351645
|
+
return;
|
|
351646
|
+
}
|
|
351647
|
+
const detectedLocale = detectSystemLanguage();
|
|
351648
|
+
const languageName = getLanguageNameFromLocale(detectedLocale);
|
|
351649
|
+
const content = generateLlmOutputLanguageRule(languageName);
|
|
351650
|
+
const dir = path86.dirname(filePath);
|
|
351651
|
+
fs80.mkdirSync(dir, { recursive: true });
|
|
351652
|
+
fs80.writeFileSync(filePath, content, "utf-8");
|
|
351653
|
+
}
|
|
351654
|
+
__name(initializeLlmOutputLanguage, "initializeLlmOutputLanguage");
|
|
351655
|
+
function getCurrentLlmOutputLanguage() {
|
|
351656
|
+
const filePath = getLlmOutputLanguageRulePath();
|
|
351657
|
+
if (fs80.existsSync(filePath)) {
|
|
351658
|
+
try {
|
|
351659
|
+
const content = fs80.readFileSync(filePath, "utf-8");
|
|
351660
|
+
return extractLlmOutputLanguageFromRuleFileContent(content);
|
|
351661
|
+
} catch {
|
|
351662
|
+
}
|
|
351663
|
+
}
|
|
351664
|
+
return null;
|
|
351665
|
+
}
|
|
351666
|
+
__name(getCurrentLlmOutputLanguage, "getCurrentLlmOutputLanguage");
|
|
351667
|
+
async function setUiLanguage(context2, lang) {
|
|
351668
|
+
const { services } = context2;
|
|
351669
|
+
const { settings } = services;
|
|
351670
|
+
if (!services.config) {
|
|
351671
|
+
return {
|
|
351672
|
+
type: "message",
|
|
351673
|
+
messageType: "error",
|
|
351674
|
+
content: t4("Configuration not available.")
|
|
351675
|
+
};
|
|
351676
|
+
}
|
|
351677
|
+
await setLanguageAsync(lang);
|
|
351678
|
+
if (settings && typeof settings.setValue === "function") {
|
|
351679
|
+
try {
|
|
351680
|
+
settings.setValue("User" /* User */, "general.language", lang);
|
|
351681
|
+
} catch (error2) {
|
|
351682
|
+
console.warn("Failed to save language setting:", error2);
|
|
351683
|
+
}
|
|
351684
|
+
}
|
|
351685
|
+
context2.ui.reloadCommands();
|
|
351686
|
+
return {
|
|
351687
|
+
type: "message",
|
|
351688
|
+
messageType: "info",
|
|
351689
|
+
content: t4("UI language changed to {{lang}}", {
|
|
351690
|
+
lang: formatUiLanguageDisplay(lang)
|
|
351691
|
+
})
|
|
351692
|
+
};
|
|
351693
|
+
}
|
|
351694
|
+
__name(setUiLanguage, "setUiLanguage");
|
|
351695
|
+
function generateLlmOutputLanguageRuleFile(language) {
|
|
351696
|
+
try {
|
|
351697
|
+
const filePath = getLlmOutputLanguageRulePath();
|
|
351698
|
+
const normalizedLanguage = normalizeLanguageName(language);
|
|
351699
|
+
const content = generateLlmOutputLanguageRule(normalizedLanguage);
|
|
351700
|
+
const dir = path86.dirname(filePath);
|
|
351701
|
+
fs80.mkdirSync(dir, { recursive: true });
|
|
351702
|
+
fs80.writeFileSync(filePath, content, "utf-8");
|
|
351703
|
+
return Promise.resolve({
|
|
351704
|
+
type: "message",
|
|
351705
|
+
messageType: "info",
|
|
351706
|
+
content: [
|
|
351707
|
+
t4("LLM output language rule file generated at {{path}}", {
|
|
351708
|
+
path: filePath
|
|
351709
|
+
}),
|
|
351710
|
+
"",
|
|
351711
|
+
t4("Please restart the application for the changes to take effect.")
|
|
351712
|
+
].join("\n")
|
|
351713
|
+
});
|
|
351714
|
+
} catch (error2) {
|
|
351715
|
+
return Promise.resolve({
|
|
351716
|
+
type: "message",
|
|
351717
|
+
messageType: "error",
|
|
351718
|
+
content: t4(
|
|
351719
|
+
"Failed to generate LLM output language rule file: {{error}}",
|
|
351720
|
+
{
|
|
351721
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
351722
|
+
}
|
|
351723
|
+
)
|
|
351724
|
+
});
|
|
351725
|
+
}
|
|
351726
|
+
}
|
|
351727
|
+
__name(generateLlmOutputLanguageRuleFile, "generateLlmOutputLanguageRuleFile");
|
|
351728
|
+
var languageCommand = {
|
|
351729
|
+
name: "language",
|
|
351730
|
+
get description() {
|
|
351731
|
+
return t4("View or change the language setting");
|
|
351732
|
+
},
|
|
351733
|
+
kind: "built-in" /* BUILT_IN */,
|
|
351734
|
+
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
351735
|
+
const { services } = context2;
|
|
351736
|
+
if (!services.config) {
|
|
351737
|
+
return {
|
|
351738
|
+
type: "message",
|
|
351739
|
+
messageType: "error",
|
|
351740
|
+
content: t4("Configuration not available.")
|
|
351741
|
+
};
|
|
351742
|
+
}
|
|
351743
|
+
const trimmedArgs = args.trim();
|
|
351744
|
+
const parts = trimmedArgs.split(/\s+/);
|
|
351745
|
+
const firstArg = parts[0].toLowerCase();
|
|
351746
|
+
const subArgs = parts.slice(1).join(" ");
|
|
351747
|
+
if (firstArg === "ui" || firstArg === "output") {
|
|
351748
|
+
const subCommand = languageCommand.subCommands?.find(
|
|
351749
|
+
(s5) => s5.name === firstArg
|
|
351750
|
+
);
|
|
351751
|
+
if (subCommand?.action) {
|
|
351752
|
+
return subCommand.action(
|
|
351753
|
+
context2,
|
|
351754
|
+
subArgs
|
|
351755
|
+
);
|
|
351756
|
+
}
|
|
351757
|
+
}
|
|
351758
|
+
if (!trimmedArgs) {
|
|
351759
|
+
const currentUiLang = getCurrentLanguage();
|
|
351760
|
+
const currentLlmLang = getCurrentLlmOutputLanguage();
|
|
351761
|
+
const message = [
|
|
351762
|
+
t4("Current UI language: {{lang}}", {
|
|
351763
|
+
lang: formatUiLanguageDisplay(currentUiLang)
|
|
351764
|
+
}),
|
|
351765
|
+
currentLlmLang ? t4("Current LLM output language: {{lang}}", { lang: currentLlmLang }) : t4("LLM output language not set"),
|
|
351766
|
+
"",
|
|
351767
|
+
t4("Available subcommands:"),
|
|
351768
|
+
` /language ui [${SUPPORTED_LANGUAGES.map((o3) => o3.id).join("|")}] - ${t4("Set UI language")}`,
|
|
351769
|
+
` /language output <language> - ${t4("Set LLM output language")}`
|
|
351770
|
+
].join("\n");
|
|
351771
|
+
return {
|
|
351772
|
+
type: "message",
|
|
351773
|
+
messageType: "info",
|
|
351774
|
+
content: message
|
|
351775
|
+
};
|
|
351776
|
+
}
|
|
351777
|
+
const targetLang = parseUiLanguageArg(trimmedArgs);
|
|
351778
|
+
if (targetLang) {
|
|
351779
|
+
return setUiLanguage(context2, targetLang);
|
|
351780
|
+
}
|
|
351781
|
+
return {
|
|
351782
|
+
type: "message",
|
|
351783
|
+
messageType: "error",
|
|
351784
|
+
content: [
|
|
351785
|
+
t4("Invalid command. Available subcommands:"),
|
|
351786
|
+
` - /language ui [${SUPPORTED_LANGUAGES.map((o3) => o3.id).join("|")}] - ${t4("Set UI language")}`,
|
|
351787
|
+
" - /language output <language> - " + t4("Set LLM output language")
|
|
351788
|
+
].join("\n")
|
|
351789
|
+
};
|
|
351790
|
+
}, "action"),
|
|
351791
|
+
subCommands: [
|
|
351792
|
+
{
|
|
351793
|
+
name: "ui",
|
|
351794
|
+
get description() {
|
|
351795
|
+
return t4("Set UI language");
|
|
351796
|
+
},
|
|
351797
|
+
kind: "built-in" /* BUILT_IN */,
|
|
351798
|
+
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
351799
|
+
const trimmedArgs = args.trim();
|
|
351800
|
+
if (!trimmedArgs) {
|
|
351801
|
+
return {
|
|
351802
|
+
type: "message",
|
|
351803
|
+
messageType: "info",
|
|
351804
|
+
content: [
|
|
351805
|
+
t4("Set UI language"),
|
|
351806
|
+
"",
|
|
351807
|
+
t4("Usage: /language ui [{{options}}]", {
|
|
351808
|
+
options: SUPPORTED_LANGUAGES.map((o3) => o3.id).join("|")
|
|
351809
|
+
}),
|
|
351810
|
+
"",
|
|
351811
|
+
t4("Available options:"),
|
|
351812
|
+
...SUPPORTED_LANGUAGES.map(
|
|
351813
|
+
(o3) => ` - ${o3.id}: ${t4(o3.fullName)}`
|
|
351814
|
+
),
|
|
351815
|
+
"",
|
|
351816
|
+
t4(
|
|
351817
|
+
"To request additional UI language packs, please open an issue on GitHub."
|
|
351818
|
+
)
|
|
351819
|
+
].join("\n")
|
|
351820
|
+
};
|
|
351821
|
+
}
|
|
351822
|
+
const targetLang = parseUiLanguageArg(trimmedArgs);
|
|
351823
|
+
if (!targetLang) {
|
|
351824
|
+
return {
|
|
351825
|
+
type: "message",
|
|
351826
|
+
messageType: "error",
|
|
351827
|
+
content: t4("Invalid language. Available: {{options}}", {
|
|
351828
|
+
options: SUPPORTED_LANGUAGES.map((o3) => o3.id).join(",")
|
|
351829
|
+
})
|
|
351830
|
+
};
|
|
351831
|
+
}
|
|
351832
|
+
return setUiLanguage(context2, targetLang);
|
|
351833
|
+
}, "action"),
|
|
351834
|
+
subCommands: SUPPORTED_LANGUAGES.map(createUiLanguageSubCommand)
|
|
351835
|
+
},
|
|
351836
|
+
{
|
|
351837
|
+
name: "output",
|
|
351838
|
+
get description() {
|
|
351839
|
+
return t4("Set LLM output language");
|
|
351840
|
+
},
|
|
351841
|
+
kind: "built-in" /* BUILT_IN */,
|
|
351842
|
+
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
351843
|
+
const trimmedArgs = args.trim();
|
|
351844
|
+
if (!trimmedArgs) {
|
|
351845
|
+
return {
|
|
351846
|
+
type: "message",
|
|
351847
|
+
messageType: "info",
|
|
351848
|
+
content: [
|
|
351849
|
+
t4("Set LLM output language"),
|
|
351850
|
+
"",
|
|
351851
|
+
t4("Usage: /language output <language>"),
|
|
351852
|
+
` ${t4("Example: /language output \u4E2D\u6587")}`,
|
|
351853
|
+
` ${t4("Example: /language output English")}`,
|
|
351854
|
+
` ${t4("Example: /language output \u65E5\u672C\u8A9E")}`
|
|
351855
|
+
].join("\n")
|
|
351856
|
+
};
|
|
351857
|
+
}
|
|
351858
|
+
return generateLlmOutputLanguageRuleFile(trimmedArgs);
|
|
351859
|
+
}, "action")
|
|
351860
|
+
}
|
|
351861
|
+
]
|
|
351862
|
+
};
|
|
351863
|
+
function createUiLanguageSubCommand(option2) {
|
|
351864
|
+
return {
|
|
351865
|
+
name: option2.id,
|
|
351866
|
+
get description() {
|
|
351867
|
+
return t4("Set UI language to {{name}}", { name: option2.fullName });
|
|
351868
|
+
},
|
|
351869
|
+
kind: "built-in" /* BUILT_IN */,
|
|
351870
|
+
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
351871
|
+
if (args.trim().length > 0) {
|
|
351872
|
+
return {
|
|
351873
|
+
type: "message",
|
|
351874
|
+
messageType: "error",
|
|
351875
|
+
content: t4(
|
|
351876
|
+
"Language subcommands do not accept additional arguments."
|
|
351877
|
+
)
|
|
351878
|
+
};
|
|
351879
|
+
}
|
|
351880
|
+
return setUiLanguage(context2, option2.code);
|
|
351881
|
+
}, "action")
|
|
351882
|
+
};
|
|
351883
|
+
}
|
|
351884
|
+
__name(createUiLanguageSubCommand, "createUiLanguageSubCommand");
|
|
351885
|
+
|
|
351628
351886
|
// packages/cli/src/core/initializer.ts
|
|
351629
351887
|
async function initializeApp(config2, settings) {
|
|
351630
351888
|
const languageSetting = process.env["RDMind_LANG"] || settings.merged.general?.language || "auto";
|
|
351631
351889
|
await initializeI18n(languageSetting);
|
|
351890
|
+
initializeLlmOutputLanguage();
|
|
351632
351891
|
const authType = settings.merged.security?.auth?.selectedType;
|
|
351633
351892
|
const authError = await performInitialAuth(config2, authType);
|
|
351634
351893
|
if (authError) {
|
|
@@ -351761,6 +352020,108 @@ import { randomUUID as randomUUID7 } from "node:crypto";
|
|
|
351761
352020
|
init_esbuild_shims();
|
|
351762
352021
|
init_core5();
|
|
351763
352022
|
|
|
352023
|
+
// packages/cli/src/ui/utils/computeStats.ts
|
|
352024
|
+
init_esbuild_shims();
|
|
352025
|
+
function calculateErrorRate(metrics2) {
|
|
352026
|
+
if (metrics2.api.totalRequests === 0) {
|
|
352027
|
+
return 0;
|
|
352028
|
+
}
|
|
352029
|
+
return metrics2.api.totalErrors / metrics2.api.totalRequests * 100;
|
|
352030
|
+
}
|
|
352031
|
+
__name(calculateErrorRate, "calculateErrorRate");
|
|
352032
|
+
function calculateAverageLatency(metrics2) {
|
|
352033
|
+
if (metrics2.api.totalRequests === 0) {
|
|
352034
|
+
return 0;
|
|
352035
|
+
}
|
|
352036
|
+
return metrics2.api.totalLatencyMs / metrics2.api.totalRequests;
|
|
352037
|
+
}
|
|
352038
|
+
__name(calculateAverageLatency, "calculateAverageLatency");
|
|
352039
|
+
function calculateCacheHitRate(metrics2) {
|
|
352040
|
+
if (metrics2.tokens.prompt === 0) {
|
|
352041
|
+
return 0;
|
|
352042
|
+
}
|
|
352043
|
+
return metrics2.tokens.cached / metrics2.tokens.prompt * 100;
|
|
352044
|
+
}
|
|
352045
|
+
__name(calculateCacheHitRate, "calculateCacheHitRate");
|
|
352046
|
+
var computeSessionStats = /* @__PURE__ */ __name((metrics2) => {
|
|
352047
|
+
const { models, tools, files } = metrics2;
|
|
352048
|
+
const totalApiTime = Object.values(models).reduce(
|
|
352049
|
+
(acc, model) => acc + model.api.totalLatencyMs,
|
|
352050
|
+
0
|
|
352051
|
+
);
|
|
352052
|
+
const totalToolTime = tools.totalDurationMs;
|
|
352053
|
+
const agentActiveTime = totalApiTime + totalToolTime;
|
|
352054
|
+
const apiTimePercent = agentActiveTime > 0 ? totalApiTime / agentActiveTime * 100 : 0;
|
|
352055
|
+
const toolTimePercent = agentActiveTime > 0 ? totalToolTime / agentActiveTime * 100 : 0;
|
|
352056
|
+
const totalCachedTokens = Object.values(models).reduce(
|
|
352057
|
+
(acc, model) => acc + model.tokens.cached,
|
|
352058
|
+
0
|
|
352059
|
+
);
|
|
352060
|
+
const totalPromptTokens = Object.values(models).reduce(
|
|
352061
|
+
(acc, model) => acc + model.tokens.prompt,
|
|
352062
|
+
0
|
|
352063
|
+
);
|
|
352064
|
+
const cacheEfficiency = totalPromptTokens > 0 ? totalCachedTokens / totalPromptTokens * 100 : 0;
|
|
352065
|
+
const totalDecisions = tools.totalDecisions.accept + tools.totalDecisions.reject + tools.totalDecisions.modify;
|
|
352066
|
+
const successRate = tools.totalCalls > 0 ? tools.totalSuccess / tools.totalCalls * 100 : 0;
|
|
352067
|
+
const agreementRate = totalDecisions > 0 ? tools.totalDecisions.accept / totalDecisions * 100 : 0;
|
|
352068
|
+
return {
|
|
352069
|
+
totalApiTime,
|
|
352070
|
+
totalToolTime,
|
|
352071
|
+
agentActiveTime,
|
|
352072
|
+
apiTimePercent,
|
|
352073
|
+
toolTimePercent,
|
|
352074
|
+
cacheEfficiency,
|
|
352075
|
+
totalDecisions,
|
|
352076
|
+
successRate,
|
|
352077
|
+
agreementRate,
|
|
352078
|
+
totalCachedTokens,
|
|
352079
|
+
totalPromptTokens,
|
|
352080
|
+
totalLinesAdded: files.totalLinesAdded,
|
|
352081
|
+
totalLinesRemoved: files.totalLinesRemoved
|
|
352082
|
+
};
|
|
352083
|
+
}, "computeSessionStats");
|
|
352084
|
+
|
|
352085
|
+
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
352086
|
+
init_esbuild_shims();
|
|
352087
|
+
|
|
352088
|
+
// packages/cli/src/utils/commands.ts
|
|
352089
|
+
init_esbuild_shims();
|
|
352090
|
+
var parseSlashCommand = /* @__PURE__ */ __name((query, commands) => {
|
|
352091
|
+
const trimmed2 = query.trim();
|
|
352092
|
+
const parts = trimmed2.substring(1).trim().split(/\s+/);
|
|
352093
|
+
const commandPath = parts.filter((p2) => p2);
|
|
352094
|
+
let currentCommands = commands;
|
|
352095
|
+
let commandToExecute;
|
|
352096
|
+
let pathIndex = 0;
|
|
352097
|
+
const canonicalPath = [];
|
|
352098
|
+
for (const part of commandPath) {
|
|
352099
|
+
let foundCommand = currentCommands.find((cmd) => cmd.name === part);
|
|
352100
|
+
if (!foundCommand) {
|
|
352101
|
+
foundCommand = currentCommands.find(
|
|
352102
|
+
(cmd) => cmd.altNames?.includes(part)
|
|
352103
|
+
);
|
|
352104
|
+
}
|
|
352105
|
+
if (foundCommand) {
|
|
352106
|
+
commandToExecute = foundCommand;
|
|
352107
|
+
canonicalPath.push(foundCommand.name);
|
|
352108
|
+
pathIndex++;
|
|
352109
|
+
if (foundCommand.subCommands) {
|
|
352110
|
+
currentCommands = foundCommand.subCommands;
|
|
352111
|
+
} else {
|
|
352112
|
+
break;
|
|
352113
|
+
}
|
|
352114
|
+
} else {
|
|
352115
|
+
break;
|
|
352116
|
+
}
|
|
352117
|
+
}
|
|
352118
|
+
const args = parts.slice(pathIndex).join(" ");
|
|
352119
|
+
return { commandToExecute, args, canonicalPath };
|
|
352120
|
+
}, "parseSlashCommand");
|
|
352121
|
+
|
|
352122
|
+
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
352123
|
+
init_core5();
|
|
352124
|
+
|
|
351764
352125
|
// packages/cli/src/services/CommandService.ts
|
|
351765
352126
|
init_esbuild_shims();
|
|
351766
352127
|
var CommandService = class _CommandService {
|
|
@@ -351844,9 +352205,6 @@ init_esbuild_shims();
|
|
|
351844
352205
|
// packages/cli/src/ui/commands/aboutCommand.ts
|
|
351845
352206
|
init_esbuild_shims();
|
|
351846
352207
|
|
|
351847
|
-
// packages/cli/src/ui/commands/types.ts
|
|
351848
|
-
init_esbuild_shims();
|
|
351849
|
-
|
|
351850
352208
|
// packages/cli/src/ui/types.ts
|
|
351851
352209
|
init_esbuild_shims();
|
|
351852
352210
|
var import_react26 = __toESM(require_react(), 1);
|
|
@@ -351930,7 +352288,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
|
|
|
351930
352288
|
|
|
351931
352289
|
// packages/cli/src/generated/git-commit.ts
|
|
351932
352290
|
init_esbuild_shims();
|
|
351933
|
-
var GIT_COMMIT_INFO2 = "
|
|
352291
|
+
var GIT_COMMIT_INFO2 = "8f0613d7";
|
|
351934
352292
|
|
|
351935
352293
|
// packages/cli/src/utils/systemInfo.ts
|
|
351936
352294
|
async function getNpmVersion() {
|
|
@@ -352345,7 +352703,8 @@ var compressCommand = {
|
|
|
352345
352703
|
kind: "built-in" /* BUILT_IN */,
|
|
352346
352704
|
action: /* @__PURE__ */ __name(async (context2) => {
|
|
352347
352705
|
const { ui: ui2 } = context2;
|
|
352348
|
-
|
|
352706
|
+
const executionMode = context2.executionMode ?? "interactive";
|
|
352707
|
+
if (executionMode === "interactive" && ui2.pendingItem) {
|
|
352349
352708
|
ui2.addItem(
|
|
352350
352709
|
{
|
|
352351
352710
|
type: "error" /* ERROR */,
|
|
@@ -352364,11 +352723,72 @@ var compressCommand = {
|
|
|
352364
352723
|
compressionStatus: null
|
|
352365
352724
|
}
|
|
352366
352725
|
};
|
|
352367
|
-
|
|
352368
|
-
|
|
352726
|
+
const config2 = context2.services.config;
|
|
352727
|
+
const geminiClient = config2?.getGeminiClient();
|
|
352728
|
+
if (!config2 || !geminiClient) {
|
|
352729
|
+
return {
|
|
352730
|
+
type: "message",
|
|
352731
|
+
messageType: "error",
|
|
352732
|
+
content: t4("Config not loaded.")
|
|
352733
|
+
};
|
|
352734
|
+
}
|
|
352735
|
+
const doCompress = /* @__PURE__ */ __name(async () => {
|
|
352369
352736
|
const promptId = `compress-${Date.now()}`;
|
|
352370
|
-
|
|
352371
|
-
|
|
352737
|
+
return await geminiClient.tryCompressChat(promptId, true);
|
|
352738
|
+
}, "doCompress");
|
|
352739
|
+
if (executionMode === "acp") {
|
|
352740
|
+
const messages = /* @__PURE__ */ __name(async function* () {
|
|
352741
|
+
try {
|
|
352742
|
+
yield {
|
|
352743
|
+
messageType: "info",
|
|
352744
|
+
content: "Compressing context..."
|
|
352745
|
+
};
|
|
352746
|
+
const compressed = await doCompress();
|
|
352747
|
+
if (!compressed) {
|
|
352748
|
+
yield {
|
|
352749
|
+
messageType: "error",
|
|
352750
|
+
content: t4("Failed to compress chat history.")
|
|
352751
|
+
};
|
|
352752
|
+
return;
|
|
352753
|
+
}
|
|
352754
|
+
yield {
|
|
352755
|
+
messageType: "info",
|
|
352756
|
+
content: `Context compressed (${compressed.originalTokenCount} -> ${compressed.newTokenCount}).`
|
|
352757
|
+
};
|
|
352758
|
+
} catch (e4) {
|
|
352759
|
+
yield {
|
|
352760
|
+
messageType: "error",
|
|
352761
|
+
content: t4("Failed to compress chat history: {{error}}", {
|
|
352762
|
+
error: e4 instanceof Error ? e4.message : String(e4)
|
|
352763
|
+
})
|
|
352764
|
+
};
|
|
352765
|
+
}
|
|
352766
|
+
}, "messages");
|
|
352767
|
+
return { type: "stream_messages", messages: messages() };
|
|
352768
|
+
}
|
|
352769
|
+
try {
|
|
352770
|
+
if (executionMode === "interactive") {
|
|
352771
|
+
ui2.setPendingItem(pendingMessage);
|
|
352772
|
+
}
|
|
352773
|
+
const compressed = await doCompress();
|
|
352774
|
+
if (!compressed) {
|
|
352775
|
+
if (executionMode === "interactive") {
|
|
352776
|
+
ui2.addItem(
|
|
352777
|
+
{
|
|
352778
|
+
type: "error" /* ERROR */,
|
|
352779
|
+
text: t4("Failed to compress chat history.")
|
|
352780
|
+
},
|
|
352781
|
+
Date.now()
|
|
352782
|
+
);
|
|
352783
|
+
return;
|
|
352784
|
+
}
|
|
352785
|
+
return {
|
|
352786
|
+
type: "message",
|
|
352787
|
+
messageType: "error",
|
|
352788
|
+
content: t4("Failed to compress chat history.")
|
|
352789
|
+
};
|
|
352790
|
+
}
|
|
352791
|
+
if (executionMode === "interactive") {
|
|
352372
352792
|
ui2.addItem(
|
|
352373
352793
|
{
|
|
352374
352794
|
type: "compression" /* COMPRESSION */,
|
|
@@ -352381,27 +352801,37 @@ var compressCommand = {
|
|
|
352381
352801
|
},
|
|
352382
352802
|
Date.now()
|
|
352383
352803
|
);
|
|
352384
|
-
|
|
352804
|
+
return;
|
|
352805
|
+
}
|
|
352806
|
+
return {
|
|
352807
|
+
type: "message",
|
|
352808
|
+
messageType: "info",
|
|
352809
|
+
content: `Context compressed (${compressed.originalTokenCount} -> ${compressed.newTokenCount}).`
|
|
352810
|
+
};
|
|
352811
|
+
} catch (e4) {
|
|
352812
|
+
if (executionMode === "interactive") {
|
|
352385
352813
|
ui2.addItem(
|
|
352386
352814
|
{
|
|
352387
352815
|
type: "error" /* ERROR */,
|
|
352388
|
-
text: t4("Failed to compress chat history
|
|
352816
|
+
text: t4("Failed to compress chat history: {{error}}", {
|
|
352817
|
+
error: e4 instanceof Error ? e4.message : String(e4)
|
|
352818
|
+
})
|
|
352389
352819
|
},
|
|
352390
352820
|
Date.now()
|
|
352391
352821
|
);
|
|
352822
|
+
return;
|
|
352392
352823
|
}
|
|
352393
|
-
|
|
352394
|
-
|
|
352395
|
-
|
|
352396
|
-
|
|
352397
|
-
|
|
352398
|
-
|
|
352399
|
-
|
|
352400
|
-
},
|
|
352401
|
-
Date.now()
|
|
352402
|
-
);
|
|
352824
|
+
return {
|
|
352825
|
+
type: "message",
|
|
352826
|
+
messageType: "error",
|
|
352827
|
+
content: t4("Failed to compress chat history: {{error}}", {
|
|
352828
|
+
error: e4 instanceof Error ? e4.message : String(e4)
|
|
352829
|
+
})
|
|
352830
|
+
};
|
|
352403
352831
|
} finally {
|
|
352404
|
-
|
|
352832
|
+
if (executionMode === "interactive") {
|
|
352833
|
+
ui2.setPendingItem(null);
|
|
352834
|
+
}
|
|
352405
352835
|
}
|
|
352406
352836
|
}, "action")
|
|
352407
352837
|
};
|
|
@@ -352455,11 +352885,11 @@ var copyCommand = {
|
|
|
352455
352885
|
|
|
352456
352886
|
// packages/cli/src/ui/commands/createCommand.ts
|
|
352457
352887
|
init_esbuild_shims();
|
|
352458
|
-
import * as
|
|
352459
|
-
import * as
|
|
352888
|
+
import * as fs81 from "fs";
|
|
352889
|
+
import * as path87 from "path";
|
|
352460
352890
|
import { fileURLToPath as fileURLToPath14 } from "url";
|
|
352461
352891
|
var __filename6 = fileURLToPath14(import.meta.url);
|
|
352462
|
-
var __dirname9 =
|
|
352892
|
+
var __dirname9 = path87.dirname(__filename6);
|
|
352463
352893
|
function validateProjectName(name3) {
|
|
352464
352894
|
return /^[a-z][a-z0-9-]*[a-z0-9]$|^[a-z]$/.test(name3);
|
|
352465
352895
|
}
|
|
@@ -352473,20 +352903,20 @@ function getIdlExamplePath() {
|
|
|
352473
352903
|
// 1. npm 发布:
|
|
352474
352904
|
// __dirname 就是 node_modules/@rdmind/rdmind/
|
|
352475
352905
|
// 模板在 node_modules/@rdmind/rdmind/templates/
|
|
352476
|
-
|
|
352906
|
+
path87.join(__dirname9, "templates", "idl-template/wiki/example"),
|
|
352477
352907
|
// 2. 开发环境:相对于工作区根目录的idl-template
|
|
352478
|
-
|
|
352908
|
+
path87.join(
|
|
352479
352909
|
__dirname9,
|
|
352480
352910
|
"..",
|
|
352481
352911
|
"packages/cli/templates/idl-template/wiki/example"
|
|
352482
352912
|
)
|
|
352483
352913
|
];
|
|
352484
352914
|
for (const templatePath of possiblePaths) {
|
|
352485
|
-
if (
|
|
352915
|
+
if (fs81.existsSync(templatePath)) {
|
|
352486
352916
|
return templatePath;
|
|
352487
352917
|
}
|
|
352488
352918
|
}
|
|
352489
|
-
return
|
|
352919
|
+
return path87.join(process.cwd(), "idl-template");
|
|
352490
352920
|
}
|
|
352491
352921
|
__name(getIdlExamplePath, "getIdlExamplePath");
|
|
352492
352922
|
function getTemplatePath() {
|
|
@@ -352494,16 +352924,16 @@ function getTemplatePath() {
|
|
|
352494
352924
|
// 1. npm 安装
|
|
352495
352925
|
// __dirname 就是 node_modules/@rdmind/rdmind/
|
|
352496
352926
|
// 模板在 node_modules/@rdmind/rdmind/template/
|
|
352497
|
-
|
|
352927
|
+
path87.join(__dirname9, "template"),
|
|
352498
352928
|
// 2. 开发环境:
|
|
352499
|
-
|
|
352929
|
+
path87.join(__dirname9, "..", "packages/cli/template")
|
|
352500
352930
|
];
|
|
352501
352931
|
for (const templatePath of possiblePaths) {
|
|
352502
|
-
if (
|
|
352932
|
+
if (fs81.existsSync(templatePath)) {
|
|
352503
352933
|
return templatePath;
|
|
352504
352934
|
}
|
|
352505
352935
|
}
|
|
352506
|
-
return
|
|
352936
|
+
return path87.join(process.cwd(), "sns-demo");
|
|
352507
352937
|
}
|
|
352508
352938
|
__name(getTemplatePath, "getTemplatePath");
|
|
352509
352939
|
function replaceIdlProjectNames(content, oldName, newName) {
|
|
@@ -352547,18 +352977,18 @@ function replaceProjectNames(content, oldName, newName, businessModule) {
|
|
|
352547
352977
|
}
|
|
352548
352978
|
__name(replaceProjectNames, "replaceProjectNames");
|
|
352549
352979
|
async function copyAndReplaceFile(srcFile, destFile, oldName, newName, businessModule, isIdlProject = false) {
|
|
352550
|
-
const destDir =
|
|
352551
|
-
if (!
|
|
352552
|
-
|
|
352980
|
+
const destDir = path87.dirname(destFile);
|
|
352981
|
+
if (!fs81.existsSync(destDir)) {
|
|
352982
|
+
fs81.mkdirSync(destDir, { recursive: true });
|
|
352553
352983
|
}
|
|
352554
|
-
const content =
|
|
352984
|
+
const content = fs81.readFileSync(srcFile, "utf8");
|
|
352555
352985
|
let newContent;
|
|
352556
352986
|
if (isIdlProject) {
|
|
352557
352987
|
newContent = replaceIdlProjectNames(content, oldName, newName);
|
|
352558
352988
|
} else {
|
|
352559
352989
|
newContent = replaceProjectNames(content, oldName, newName, businessModule);
|
|
352560
352990
|
}
|
|
352561
|
-
|
|
352991
|
+
fs81.writeFileSync(destFile, newContent, "utf8");
|
|
352562
352992
|
}
|
|
352563
352993
|
__name(copyAndReplaceFile, "copyAndReplaceFile");
|
|
352564
352994
|
function shouldSkipItem(itemName) {
|
|
@@ -352596,12 +353026,12 @@ function shouldSkipItem(itemName) {
|
|
|
352596
353026
|
}
|
|
352597
353027
|
__name(shouldSkipItem, "shouldSkipItem");
|
|
352598
353028
|
async function copyAndReplaceDir(srcDir, destDir, oldName, newName, businessModule, isIdlProject = false) {
|
|
352599
|
-
if (!
|
|
352600
|
-
|
|
353029
|
+
if (!fs81.existsSync(destDir)) {
|
|
353030
|
+
fs81.mkdirSync(destDir, { recursive: true });
|
|
352601
353031
|
}
|
|
352602
|
-
const items =
|
|
353032
|
+
const items = fs81.readdirSync(srcDir);
|
|
352603
353033
|
for (const item of items) {
|
|
352604
|
-
const srcPath =
|
|
353034
|
+
const srcPath = path87.join(srcDir, item);
|
|
352605
353035
|
if (shouldSkipItem(item)) {
|
|
352606
353036
|
continue;
|
|
352607
353037
|
}
|
|
@@ -352614,7 +353044,7 @@ async function copyAndReplaceDir(srcDir, destDir, oldName, newName, businessModu
|
|
|
352614
353044
|
const pathParts = packageDirName.split("-");
|
|
352615
353045
|
const currentDestPath = destDir;
|
|
352616
353046
|
for (let i3 = 0; i3 < pathParts.length; i3++) {
|
|
352617
|
-
const partPath =
|
|
353047
|
+
const partPath = path87.join(
|
|
352618
353048
|
currentDestPath,
|
|
352619
353049
|
...pathParts.slice(0, i3 + 1)
|
|
352620
353050
|
);
|
|
@@ -352628,8 +353058,8 @@ async function copyAndReplaceDir(srcDir, destDir, oldName, newName, businessModu
|
|
|
352628
353058
|
isIdlProject
|
|
352629
353059
|
);
|
|
352630
353060
|
} else {
|
|
352631
|
-
if (!
|
|
352632
|
-
|
|
353061
|
+
if (!fs81.existsSync(partPath)) {
|
|
353062
|
+
fs81.mkdirSync(partPath, { recursive: true });
|
|
352633
353063
|
}
|
|
352634
353064
|
}
|
|
352635
353065
|
}
|
|
@@ -352646,8 +353076,8 @@ async function copyAndReplaceDir(srcDir, destDir, oldName, newName, businessModu
|
|
|
352646
353076
|
destItemName = item.replace(/sns-demo/g, newName);
|
|
352647
353077
|
}
|
|
352648
353078
|
}
|
|
352649
|
-
const destPath =
|
|
352650
|
-
const stats =
|
|
353079
|
+
const destPath = path87.join(destDir, destItemName);
|
|
353080
|
+
const stats = fs81.statSync(srcPath);
|
|
352651
353081
|
if (stats.isDirectory()) {
|
|
352652
353082
|
await copyAndReplaceDir(
|
|
352653
353083
|
srcPath,
|
|
@@ -352672,7 +353102,7 @@ async function copyAndReplaceDir(srcDir, destDir, oldName, newName, businessModu
|
|
|
352672
353102
|
__name(copyAndReplaceDir, "copyAndReplaceDir");
|
|
352673
353103
|
async function createJavaProject(context2, projectName, businessModule) {
|
|
352674
353104
|
const templatePath = getTemplatePath();
|
|
352675
|
-
if (!
|
|
353105
|
+
if (!fs81.existsSync(templatePath)) {
|
|
352676
353106
|
context2.ui.addItem(
|
|
352677
353107
|
{
|
|
352678
353108
|
type: "error" /* ERROR */,
|
|
@@ -352683,8 +353113,8 @@ async function createJavaProject(context2, projectName, businessModule) {
|
|
|
352683
353113
|
);
|
|
352684
353114
|
return;
|
|
352685
353115
|
}
|
|
352686
|
-
const targetPath =
|
|
352687
|
-
if (
|
|
353116
|
+
const targetPath = path87.join(process.cwd(), projectName);
|
|
353117
|
+
if (fs81.existsSync(targetPath)) {
|
|
352688
353118
|
context2.ui.addItem(
|
|
352689
353119
|
{
|
|
352690
353120
|
type: "error" /* ERROR */,
|
|
@@ -352733,9 +353163,9 @@ ${projectName}/
|
|
|
352733
353163
|
Date.now()
|
|
352734
353164
|
);
|
|
352735
353165
|
} catch (error2) {
|
|
352736
|
-
if (
|
|
353166
|
+
if (fs81.existsSync(targetPath)) {
|
|
352737
353167
|
try {
|
|
352738
|
-
|
|
353168
|
+
fs81.rmSync(targetPath, { recursive: true, force: true });
|
|
352739
353169
|
} catch (cleanupError) {
|
|
352740
353170
|
console.warn(
|
|
352741
353171
|
"Warning: Could not clean up failed project creation:",
|
|
@@ -352821,7 +353251,7 @@ var javaFlsCommand = {
|
|
|
352821
353251
|
};
|
|
352822
353252
|
async function createIdlProject(context2, projectName) {
|
|
352823
353253
|
const templatePath = getIdlExamplePath();
|
|
352824
|
-
if (!
|
|
353254
|
+
if (!fs81.existsSync(templatePath)) {
|
|
352825
353255
|
context2.ui.addItem(
|
|
352826
353256
|
{
|
|
352827
353257
|
type: "error" /* ERROR */,
|
|
@@ -352833,8 +353263,8 @@ async function createIdlProject(context2, projectName) {
|
|
|
352833
353263
|
return;
|
|
352834
353264
|
}
|
|
352835
353265
|
const projectDirectoryName = projectName;
|
|
352836
|
-
const targetPath =
|
|
352837
|
-
if (
|
|
353266
|
+
const targetPath = path87.join(process.cwd(), projectDirectoryName);
|
|
353267
|
+
if (fs81.existsSync(targetPath)) {
|
|
352838
353268
|
context2.ui.addItem(
|
|
352839
353269
|
{
|
|
352840
353270
|
type: "error" /* ERROR */,
|
|
@@ -352892,9 +353322,9 @@ ${projectDirectoryName}/
|
|
|
352892
353322
|
Date.now()
|
|
352893
353323
|
);
|
|
352894
353324
|
} catch (error2) {
|
|
352895
|
-
if (
|
|
353325
|
+
if (fs81.existsSync(targetPath)) {
|
|
352896
353326
|
try {
|
|
352897
|
-
|
|
353327
|
+
fs81.rmSync(targetPath, { recursive: true, force: true });
|
|
352898
353328
|
} catch (cleanupError) {
|
|
352899
353329
|
console.warn(
|
|
352900
353330
|
"Warning: Could not clean up failed project creation:",
|
|
@@ -353085,8 +353515,8 @@ var docsCommand = {
|
|
|
353085
353515
|
init_esbuild_shims();
|
|
353086
353516
|
init_core5();
|
|
353087
353517
|
import * as os32 from "node:os";
|
|
353088
|
-
import * as
|
|
353089
|
-
import * as
|
|
353518
|
+
import * as path88 from "node:path";
|
|
353519
|
+
import * as fs82 from "node:fs/promises";
|
|
353090
353520
|
function expandHomeDir(p2) {
|
|
353091
353521
|
if (!p2) {
|
|
353092
353522
|
return "";
|
|
@@ -353097,7 +353527,7 @@ function expandHomeDir(p2) {
|
|
|
353097
353527
|
} else if (p2 === "~" || p2.startsWith("~/")) {
|
|
353098
353528
|
expandedPath = os32.homedir() + p2.substring(1);
|
|
353099
353529
|
}
|
|
353100
|
-
return
|
|
353530
|
+
return path88.normalize(expandedPath);
|
|
353101
353531
|
}
|
|
353102
353532
|
__name(expandHomeDir, "expandHomeDir");
|
|
353103
353533
|
var directoryCommand = {
|
|
@@ -353405,25 +353835,25 @@ async function resolveCompletionPaths(partialPath, baseDir) {
|
|
|
353405
353835
|
resolvedPath = baseDir;
|
|
353406
353836
|
displayPrefix = "";
|
|
353407
353837
|
} else if (partialPath.startsWith("~")) {
|
|
353408
|
-
resolvedPath =
|
|
353838
|
+
resolvedPath = path88.join(os32.homedir(), partialPath.slice(1));
|
|
353409
353839
|
} else {
|
|
353410
|
-
resolvedPath =
|
|
353840
|
+
resolvedPath = path88.isAbsolute(partialPath) ? path88.resolve(partialPath || "/") : path88.resolve(baseDir, partialPath || ".");
|
|
353411
353841
|
}
|
|
353412
353842
|
let targetDir = resolvedPath;
|
|
353413
353843
|
let filterPrefix = "";
|
|
353414
353844
|
if (partialPath && !partialPath.endsWith("/") && !/^\.\/?$/.test(partialPath)) {
|
|
353415
|
-
targetDir =
|
|
353416
|
-
filterPrefix =
|
|
353845
|
+
targetDir = path88.dirname(resolvedPath);
|
|
353846
|
+
filterPrefix = path88.basename(resolvedPath);
|
|
353417
353847
|
}
|
|
353418
|
-
const entries = await
|
|
353848
|
+
const entries = await fs82.readdir(targetDir, { withFileTypes: true });
|
|
353419
353849
|
return entries.filter((entry) => entry.isDirectory()).filter((entry) => !filterPrefix || entry.name.startsWith(filterPrefix)).map((entry) => {
|
|
353420
353850
|
let completionPath;
|
|
353421
353851
|
if (partialPath.endsWith("/")) {
|
|
353422
|
-
completionPath =
|
|
353852
|
+
completionPath = path88.posix.join(displayPrefix, entry.name) + "/";
|
|
353423
353853
|
} else {
|
|
353424
|
-
const prefixDir = displayPrefix.includes("/") ?
|
|
353854
|
+
const prefixDir = displayPrefix.includes("/") ? path88.posix.dirname(displayPrefix) : "";
|
|
353425
353855
|
if (prefixDir && prefixDir !== ".") {
|
|
353426
|
-
completionPath =
|
|
353856
|
+
completionPath = path88.posix.join(prefixDir, entry.name) + "/";
|
|
353427
353857
|
} else {
|
|
353428
353858
|
completionPath = entry.name + "/";
|
|
353429
353859
|
if (displayPrefix && displayPrefix !== "." && !displayPrefix.includes("/")) {
|
|
@@ -353620,7 +354050,7 @@ var helpCommand = {
|
|
|
353620
354050
|
init_esbuild_shims();
|
|
353621
354051
|
init_core5();
|
|
353622
354052
|
init_core5();
|
|
353623
|
-
import
|
|
354053
|
+
import path89 from "node:path";
|
|
353624
354054
|
init_settings();
|
|
353625
354055
|
function getIdeStatusMessage(ideClient) {
|
|
353626
354056
|
const connection = ideClient.getConnectionStatus();
|
|
@@ -353651,13 +354081,13 @@ __name(getIdeStatusMessage, "getIdeStatusMessage");
|
|
|
353651
354081
|
function formatFileList(openFiles) {
|
|
353652
354082
|
const basenameCounts = /* @__PURE__ */ new Map();
|
|
353653
354083
|
for (const file of openFiles) {
|
|
353654
|
-
const basename21 =
|
|
354084
|
+
const basename21 = path89.basename(file.path);
|
|
353655
354085
|
basenameCounts.set(basename21, (basenameCounts.get(basename21) || 0) + 1);
|
|
353656
354086
|
}
|
|
353657
354087
|
const fileList = openFiles.map((file) => {
|
|
353658
|
-
const basename21 =
|
|
354088
|
+
const basename21 = path89.basename(file.path);
|
|
353659
354089
|
const isDuplicate = (basenameCounts.get(basename21) || 0) > 1;
|
|
353660
|
-
const parentDir =
|
|
354090
|
+
const parentDir = path89.basename(path89.dirname(file.path));
|
|
353661
354091
|
const displayName = isDuplicate ? `${basename21} (/${parentDir})` : basename21;
|
|
353662
354092
|
return ` - ${displayName}${file.isActive ? " (active)" : ""}`;
|
|
353663
354093
|
}).join("\n");
|
|
@@ -354637,8 +355067,8 @@ var importCommand = {
|
|
|
354637
355067
|
// packages/cli/src/ui/commands/initCommand.ts
|
|
354638
355068
|
init_esbuild_shims();
|
|
354639
355069
|
init_core5();
|
|
354640
|
-
import * as
|
|
354641
|
-
import * as
|
|
355070
|
+
import * as fs83 from "node:fs";
|
|
355071
|
+
import * as path90 from "node:path";
|
|
354642
355072
|
var import_react27 = __toESM(require_react(), 1);
|
|
354643
355073
|
var initCommand = {
|
|
354644
355074
|
name: "init",
|
|
@@ -354656,11 +355086,11 @@ var initCommand = {
|
|
|
354656
355086
|
}
|
|
354657
355087
|
const targetDir = context2.services.config.getTargetDir();
|
|
354658
355088
|
const contextFileName = getCurrentGeminiMdFilename();
|
|
354659
|
-
const contextFilePath =
|
|
355089
|
+
const contextFilePath = path90.join(targetDir, contextFileName);
|
|
354660
355090
|
try {
|
|
354661
|
-
if (
|
|
355091
|
+
if (fs83.existsSync(contextFilePath)) {
|
|
354662
355092
|
try {
|
|
354663
|
-
const existing =
|
|
355093
|
+
const existing = fs83.readFileSync(contextFilePath, "utf8");
|
|
354664
355094
|
if (existing && existing.trim().length > 0) {
|
|
354665
355095
|
if (!context2.overwriteConfirmed) {
|
|
354666
355096
|
return {
|
|
@@ -354682,7 +355112,7 @@ var initCommand = {
|
|
|
354682
355112
|
}
|
|
354683
355113
|
}
|
|
354684
355114
|
try {
|
|
354685
|
-
|
|
355115
|
+
fs83.writeFileSync(contextFilePath, "", "utf8");
|
|
354686
355116
|
context2.ui.addItem(
|
|
354687
355117
|
{
|
|
354688
355118
|
type: "info",
|
|
@@ -354745,354 +355175,6 @@ Write the complete content to the \`${contextFileName}\` file. The output must b
|
|
|
354745
355175
|
}, "action")
|
|
354746
355176
|
};
|
|
354747
355177
|
|
|
354748
|
-
// packages/cli/src/ui/commands/languageCommand.ts
|
|
354749
|
-
init_esbuild_shims();
|
|
354750
|
-
init_settings();
|
|
354751
|
-
init_core5();
|
|
354752
|
-
import * as fs83 from "node:fs";
|
|
354753
|
-
import * as path90 from "node:path";
|
|
354754
|
-
var LLM_OUTPUT_LANGUAGE_RULE_FILENAME = "output-language.md";
|
|
354755
|
-
function generateLlmOutputLanguageRule(language) {
|
|
354756
|
-
return `# \u26A0\uFE0F CRITICAL: ${language} Output Language Rule - HIGHEST PRIORITY \u26A0\uFE0F
|
|
354757
|
-
|
|
354758
|
-
## \u{1F6A8} MANDATORY RULE - NO EXCEPTIONS \u{1F6A8}
|
|
354759
|
-
|
|
354760
|
-
**YOU MUST RESPOND IN ${language.toUpperCase()} FOR EVERY SINGLE OUTPUT, REGARDLESS OF THE USER'S INPUT LANGUAGE.**
|
|
354761
|
-
|
|
354762
|
-
This is a **NON-NEGOTIABLE** requirement. Even if the user writes in English, says "hi", asks a simple question, or explicitly requests another language, **YOU MUST ALWAYS RESPOND IN ${language.toUpperCase()}.**
|
|
354763
|
-
|
|
354764
|
-
## What Must Be in ${language}
|
|
354765
|
-
|
|
354766
|
-
**EVERYTHING** you output: conversation replies, tool call descriptions, success/error messages, generated file content (comments, documentation), and all explanatory text.
|
|
354767
|
-
|
|
354768
|
-
**Tool outputs**: All descriptive text from \`read_file\`, \`write_file\`, \`codebase_search\`, \`run_terminal_cmd\`, \`todo_write\`, \`web_search\`, etc. MUST be in ${language}.
|
|
354769
|
-
|
|
354770
|
-
## Examples
|
|
354771
|
-
|
|
354772
|
-
### \u2705 CORRECT:
|
|
354773
|
-
- User says "hi" \u2192 Respond in ${language} (e.g., "Bonjour" if ${language} is French)
|
|
354774
|
-
- Tool result \u2192 "\u5DF2\u6210\u529F\u8BFB\u53D6\u6587\u4EF6 config.json" (if ${language} is Chinese)
|
|
354775
|
-
- Error \u2192 "\u65E0\u6CD5\u627E\u5230\u6307\u5B9A\u7684\u6587\u4EF6" (if ${language} is Chinese)
|
|
354776
|
-
|
|
354777
|
-
### \u274C WRONG:
|
|
354778
|
-
- User says "hi" \u2192 "Hello" in English
|
|
354779
|
-
- Tool result \u2192 "Successfully read file" in English
|
|
354780
|
-
- Error \u2192 "File not found" in English
|
|
354781
|
-
|
|
354782
|
-
## Notes
|
|
354783
|
-
|
|
354784
|
-
- Code elements (variable/function names, syntax) can remain in English
|
|
354785
|
-
- Comments, documentation, and all other text MUST be in ${language}
|
|
354786
|
-
|
|
354787
|
-
**THIS RULE IS ACTIVE NOW. ALL OUTPUTS MUST BE IN ${language.toUpperCase()}. NO EXCEPTIONS.**
|
|
354788
|
-
`;
|
|
354789
|
-
}
|
|
354790
|
-
__name(generateLlmOutputLanguageRule, "generateLlmOutputLanguageRule");
|
|
354791
|
-
function getLlmOutputLanguageRulePath() {
|
|
354792
|
-
return path90.join(
|
|
354793
|
-
Storage.getGlobalQwenDir(),
|
|
354794
|
-
LLM_OUTPUT_LANGUAGE_RULE_FILENAME
|
|
354795
|
-
);
|
|
354796
|
-
}
|
|
354797
|
-
__name(getLlmOutputLanguageRulePath, "getLlmOutputLanguageRulePath");
|
|
354798
|
-
function getCurrentLlmOutputLanguage() {
|
|
354799
|
-
const filePath = getLlmOutputLanguageRulePath();
|
|
354800
|
-
if (fs83.existsSync(filePath)) {
|
|
354801
|
-
try {
|
|
354802
|
-
const content = fs83.readFileSync(filePath, "utf-8");
|
|
354803
|
-
const match2 = content.match(/^#.*?(\w+)\s+Output Language Rule/i);
|
|
354804
|
-
if (match2) {
|
|
354805
|
-
return match2[1];
|
|
354806
|
-
}
|
|
354807
|
-
} catch {
|
|
354808
|
-
}
|
|
354809
|
-
}
|
|
354810
|
-
return null;
|
|
354811
|
-
}
|
|
354812
|
-
__name(getCurrentLlmOutputLanguage, "getCurrentLlmOutputLanguage");
|
|
354813
|
-
async function setUiLanguage(context2, lang) {
|
|
354814
|
-
const { services } = context2;
|
|
354815
|
-
const { settings } = services;
|
|
354816
|
-
if (!services.config) {
|
|
354817
|
-
return {
|
|
354818
|
-
type: "message",
|
|
354819
|
-
messageType: "error",
|
|
354820
|
-
content: t4("Configuration not available.")
|
|
354821
|
-
};
|
|
354822
|
-
}
|
|
354823
|
-
await setLanguageAsync(lang);
|
|
354824
|
-
if (settings && typeof settings.setValue === "function") {
|
|
354825
|
-
try {
|
|
354826
|
-
settings.setValue("User" /* User */, "general.language", lang);
|
|
354827
|
-
} catch (error2) {
|
|
354828
|
-
console.warn("Failed to save language setting:", error2);
|
|
354829
|
-
}
|
|
354830
|
-
}
|
|
354831
|
-
context2.ui.reloadCommands();
|
|
354832
|
-
const langDisplayNames = {
|
|
354833
|
-
zh: "\u4E2D\u6587\uFF08zh-CN\uFF09",
|
|
354834
|
-
en: "English\uFF08en-US\uFF09"
|
|
354835
|
-
};
|
|
354836
|
-
return {
|
|
354837
|
-
type: "message",
|
|
354838
|
-
messageType: "info",
|
|
354839
|
-
content: t4("UI language changed to {{lang}}", {
|
|
354840
|
-
lang: langDisplayNames[lang] || lang
|
|
354841
|
-
})
|
|
354842
|
-
};
|
|
354843
|
-
}
|
|
354844
|
-
__name(setUiLanguage, "setUiLanguage");
|
|
354845
|
-
function generateLlmOutputLanguageRuleFile(language) {
|
|
354846
|
-
try {
|
|
354847
|
-
const filePath = getLlmOutputLanguageRulePath();
|
|
354848
|
-
const content = generateLlmOutputLanguageRule(language);
|
|
354849
|
-
const dir = path90.dirname(filePath);
|
|
354850
|
-
fs83.mkdirSync(dir, { recursive: true });
|
|
354851
|
-
fs83.writeFileSync(filePath, content, "utf-8");
|
|
354852
|
-
return Promise.resolve({
|
|
354853
|
-
type: "message",
|
|
354854
|
-
messageType: "info",
|
|
354855
|
-
content: [
|
|
354856
|
-
t4("LLM output language rule file generated at {{path}}", {
|
|
354857
|
-
path: filePath
|
|
354858
|
-
}),
|
|
354859
|
-
"",
|
|
354860
|
-
t4("Please restart the application for the changes to take effect.")
|
|
354861
|
-
].join("\n")
|
|
354862
|
-
});
|
|
354863
|
-
} catch (error2) {
|
|
354864
|
-
return Promise.resolve({
|
|
354865
|
-
type: "message",
|
|
354866
|
-
messageType: "error",
|
|
354867
|
-
content: t4(
|
|
354868
|
-
"Failed to generate LLM output language rule file: {{error}}",
|
|
354869
|
-
{
|
|
354870
|
-
error: error2 instanceof Error ? error2.message : String(error2)
|
|
354871
|
-
}
|
|
354872
|
-
)
|
|
354873
|
-
});
|
|
354874
|
-
}
|
|
354875
|
-
}
|
|
354876
|
-
__name(generateLlmOutputLanguageRuleFile, "generateLlmOutputLanguageRuleFile");
|
|
354877
|
-
var languageCommand = {
|
|
354878
|
-
name: "language",
|
|
354879
|
-
get description() {
|
|
354880
|
-
return t4("View or change the language setting");
|
|
354881
|
-
},
|
|
354882
|
-
kind: "built-in" /* BUILT_IN */,
|
|
354883
|
-
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
354884
|
-
const { services } = context2;
|
|
354885
|
-
if (!services.config) {
|
|
354886
|
-
return {
|
|
354887
|
-
type: "message",
|
|
354888
|
-
messageType: "error",
|
|
354889
|
-
content: t4("Configuration not available.")
|
|
354890
|
-
};
|
|
354891
|
-
}
|
|
354892
|
-
const trimmedArgs = args.trim();
|
|
354893
|
-
if (!trimmedArgs) {
|
|
354894
|
-
const currentUiLang = getCurrentLanguage();
|
|
354895
|
-
const currentLlmLang = getCurrentLlmOutputLanguage();
|
|
354896
|
-
const message = [
|
|
354897
|
-
t4("Current UI language: {{lang}}", { lang: currentUiLang }),
|
|
354898
|
-
currentLlmLang ? t4("Current LLM output language: {{lang}}", { lang: currentLlmLang }) : t4("LLM output language not set"),
|
|
354899
|
-
"",
|
|
354900
|
-
t4("Available subcommands:"),
|
|
354901
|
-
` /language ui [zh-CN|en-US] - ${t4("Set UI language")}`,
|
|
354902
|
-
` /language output <language> - ${t4("Set LLM output language")}`
|
|
354903
|
-
].join("\n");
|
|
354904
|
-
return {
|
|
354905
|
-
type: "message",
|
|
354906
|
-
messageType: "info",
|
|
354907
|
-
content: message
|
|
354908
|
-
};
|
|
354909
|
-
}
|
|
354910
|
-
const parts = trimmedArgs.split(/\s+/);
|
|
354911
|
-
const subcommand = parts[0].toLowerCase();
|
|
354912
|
-
if (subcommand === "ui") {
|
|
354913
|
-
if (parts.length === 1) {
|
|
354914
|
-
return {
|
|
354915
|
-
type: "message",
|
|
354916
|
-
messageType: "info",
|
|
354917
|
-
content: [
|
|
354918
|
-
t4("Set UI language"),
|
|
354919
|
-
"",
|
|
354920
|
-
t4("Usage: /language ui [zh-CN|en-US]"),
|
|
354921
|
-
"",
|
|
354922
|
-
t4("Available options:"),
|
|
354923
|
-
t4(" - zh-CN: Simplified Chinese"),
|
|
354924
|
-
t4(" - en-US: English"),
|
|
354925
|
-
"",
|
|
354926
|
-
t4(
|
|
354927
|
-
"To request additional UI language packs, please open an issue on GitHub."
|
|
354928
|
-
)
|
|
354929
|
-
].join("\n")
|
|
354930
|
-
};
|
|
354931
|
-
}
|
|
354932
|
-
const langArg = parts[1].toLowerCase();
|
|
354933
|
-
let targetLang = null;
|
|
354934
|
-
if (langArg === "en" || langArg === "english" || langArg === "en-us") {
|
|
354935
|
-
targetLang = "en";
|
|
354936
|
-
} else if (langArg === "zh" || langArg === "chinese" || langArg === "\u4E2D\u6587" || langArg === "zh-cn") {
|
|
354937
|
-
targetLang = "zh";
|
|
354938
|
-
} else {
|
|
354939
|
-
return {
|
|
354940
|
-
type: "message",
|
|
354941
|
-
messageType: "error",
|
|
354942
|
-
content: t4("Invalid language. Available: en-US, zh-CN")
|
|
354943
|
-
};
|
|
354944
|
-
}
|
|
354945
|
-
return setUiLanguage(context2, targetLang);
|
|
354946
|
-
} else if (subcommand === "output") {
|
|
354947
|
-
if (parts.length === 1) {
|
|
354948
|
-
return {
|
|
354949
|
-
type: "message",
|
|
354950
|
-
messageType: "info",
|
|
354951
|
-
content: [
|
|
354952
|
-
t4("Set LLM output language"),
|
|
354953
|
-
"",
|
|
354954
|
-
t4("Usage: /language output <language>"),
|
|
354955
|
-
` ${t4("Example: /language output \u4E2D\u6587")}`
|
|
354956
|
-
].join("\n")
|
|
354957
|
-
};
|
|
354958
|
-
}
|
|
354959
|
-
const language = parts.slice(1).join(" ");
|
|
354960
|
-
return generateLlmOutputLanguageRuleFile(language);
|
|
354961
|
-
} else {
|
|
354962
|
-
const langArg = trimmedArgs.toLowerCase();
|
|
354963
|
-
let targetLang = null;
|
|
354964
|
-
if (langArg === "en" || langArg === "english" || langArg === "en-us") {
|
|
354965
|
-
targetLang = "en";
|
|
354966
|
-
} else if (langArg === "zh" || langArg === "chinese" || langArg === "\u4E2D\u6587" || langArg === "zh-cn") {
|
|
354967
|
-
targetLang = "zh";
|
|
354968
|
-
} else {
|
|
354969
|
-
return {
|
|
354970
|
-
type: "message",
|
|
354971
|
-
messageType: "error",
|
|
354972
|
-
content: [
|
|
354973
|
-
t4("Invalid command. Available subcommands:"),
|
|
354974
|
-
" - /language ui [zh-CN|en-US] - " + t4("Set UI language"),
|
|
354975
|
-
" - /language output <language> - " + t4("Set LLM output language")
|
|
354976
|
-
].join("\n")
|
|
354977
|
-
};
|
|
354978
|
-
}
|
|
354979
|
-
return setUiLanguage(context2, targetLang);
|
|
354980
|
-
}
|
|
354981
|
-
}, "action"),
|
|
354982
|
-
subCommands: [
|
|
354983
|
-
{
|
|
354984
|
-
name: "ui",
|
|
354985
|
-
get description() {
|
|
354986
|
-
return t4("Set UI language");
|
|
354987
|
-
},
|
|
354988
|
-
kind: "built-in" /* BUILT_IN */,
|
|
354989
|
-
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
354990
|
-
const trimmedArgs = args.trim();
|
|
354991
|
-
if (!trimmedArgs) {
|
|
354992
|
-
return {
|
|
354993
|
-
type: "message",
|
|
354994
|
-
messageType: "info",
|
|
354995
|
-
content: [
|
|
354996
|
-
t4("Set UI language"),
|
|
354997
|
-
"",
|
|
354998
|
-
t4("Usage: /language ui [zh-CN|en-US]"),
|
|
354999
|
-
"",
|
|
355000
|
-
t4("Available options:"),
|
|
355001
|
-
t4(" - zh-CN: Simplified Chinese"),
|
|
355002
|
-
t4(" - en-US: English"),
|
|
355003
|
-
"",
|
|
355004
|
-
t4(
|
|
355005
|
-
"To request additional UI language packs, please open an issue on GitHub."
|
|
355006
|
-
)
|
|
355007
|
-
].join("\n")
|
|
355008
|
-
};
|
|
355009
|
-
}
|
|
355010
|
-
const langArg = trimmedArgs.toLowerCase();
|
|
355011
|
-
let targetLang = null;
|
|
355012
|
-
if (langArg === "en" || langArg === "english" || langArg === "en-us") {
|
|
355013
|
-
targetLang = "en";
|
|
355014
|
-
} else if (langArg === "zh" || langArg === "chinese" || langArg === "\u4E2D\u6587" || langArg === "zh-cn") {
|
|
355015
|
-
targetLang = "zh";
|
|
355016
|
-
} else {
|
|
355017
|
-
return {
|
|
355018
|
-
type: "message",
|
|
355019
|
-
messageType: "error",
|
|
355020
|
-
content: t4("Invalid language. Available: en-US, zh-CN")
|
|
355021
|
-
};
|
|
355022
|
-
}
|
|
355023
|
-
return setUiLanguage(context2, targetLang);
|
|
355024
|
-
}, "action"),
|
|
355025
|
-
subCommands: [
|
|
355026
|
-
{
|
|
355027
|
-
name: "zh-CN",
|
|
355028
|
-
altNames: ["zh", "chinese", "\u4E2D\u6587"],
|
|
355029
|
-
get description() {
|
|
355030
|
-
return t4("Set UI language to Simplified Chinese (zh-CN)");
|
|
355031
|
-
},
|
|
355032
|
-
kind: "built-in" /* BUILT_IN */,
|
|
355033
|
-
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
355034
|
-
if (args.trim().length > 0) {
|
|
355035
|
-
return {
|
|
355036
|
-
type: "message",
|
|
355037
|
-
messageType: "error",
|
|
355038
|
-
content: t4(
|
|
355039
|
-
"Language subcommands do not accept additional arguments."
|
|
355040
|
-
)
|
|
355041
|
-
};
|
|
355042
|
-
}
|
|
355043
|
-
return setUiLanguage(context2, "zh");
|
|
355044
|
-
}, "action")
|
|
355045
|
-
},
|
|
355046
|
-
{
|
|
355047
|
-
name: "en-US",
|
|
355048
|
-
altNames: ["en", "english"],
|
|
355049
|
-
get description() {
|
|
355050
|
-
return t4("Set UI language to English (en-US)");
|
|
355051
|
-
},
|
|
355052
|
-
kind: "built-in" /* BUILT_IN */,
|
|
355053
|
-
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
355054
|
-
if (args.trim().length > 0) {
|
|
355055
|
-
return {
|
|
355056
|
-
type: "message",
|
|
355057
|
-
messageType: "error",
|
|
355058
|
-
content: t4(
|
|
355059
|
-
"Language subcommands do not accept additional arguments."
|
|
355060
|
-
)
|
|
355061
|
-
};
|
|
355062
|
-
}
|
|
355063
|
-
return setUiLanguage(context2, "en");
|
|
355064
|
-
}, "action")
|
|
355065
|
-
}
|
|
355066
|
-
]
|
|
355067
|
-
},
|
|
355068
|
-
{
|
|
355069
|
-
name: "output",
|
|
355070
|
-
get description() {
|
|
355071
|
-
return t4("Set LLM output language");
|
|
355072
|
-
},
|
|
355073
|
-
kind: "built-in" /* BUILT_IN */,
|
|
355074
|
-
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
355075
|
-
const trimmedArgs = args.trim();
|
|
355076
|
-
if (!trimmedArgs) {
|
|
355077
|
-
return {
|
|
355078
|
-
type: "message",
|
|
355079
|
-
messageType: "info",
|
|
355080
|
-
content: [
|
|
355081
|
-
t4("Set LLM output language"),
|
|
355082
|
-
"",
|
|
355083
|
-
t4("Usage: /language output <language>"),
|
|
355084
|
-
` ${t4("Example: /language output \u4E2D\u6587")}`,
|
|
355085
|
-
` ${t4("Example: /language output English")}`,
|
|
355086
|
-
` ${t4("Example: /language output \u65E5\u672C\u8A9E")}`
|
|
355087
|
-
].join("\n")
|
|
355088
|
-
};
|
|
355089
|
-
}
|
|
355090
|
-
return generateLlmOutputLanguageRuleFile(trimmedArgs);
|
|
355091
|
-
}, "action")
|
|
355092
|
-
}
|
|
355093
|
-
]
|
|
355094
|
-
};
|
|
355095
|
-
|
|
355096
355178
|
// packages/cli/src/ui/commands/mcpCommand.ts
|
|
355097
355179
|
init_esbuild_shims();
|
|
355098
355180
|
init_core5();
|
|
@@ -356920,6 +357002,7 @@ var summaryCommand = {
|
|
|
356920
357002
|
action: /* @__PURE__ */ __name(async (context2) => {
|
|
356921
357003
|
const { config: config2 } = context2.services;
|
|
356922
357004
|
const { ui: ui2 } = context2;
|
|
357005
|
+
const executionMode = context2.executionMode ?? "interactive";
|
|
356923
357006
|
if (!config2) {
|
|
356924
357007
|
return {
|
|
356925
357008
|
type: "message",
|
|
@@ -356935,7 +357018,7 @@ var summaryCommand = {
|
|
|
356935
357018
|
content: t4("No chat client available to generate summary.")
|
|
356936
357019
|
};
|
|
356937
357020
|
}
|
|
356938
|
-
if (ui2.pendingItem) {
|
|
357021
|
+
if (executionMode === "interactive" && ui2.pendingItem) {
|
|
356939
357022
|
ui2.addItem(
|
|
356940
357023
|
{
|
|
356941
357024
|
type: "error",
|
|
@@ -356953,25 +357036,17 @@ var summaryCommand = {
|
|
|
356953
357036
|
)
|
|
356954
357037
|
};
|
|
356955
357038
|
}
|
|
356956
|
-
|
|
357039
|
+
const getChatHistory = /* @__PURE__ */ __name(() => {
|
|
356957
357040
|
const chat = geminiClient.getChat();
|
|
356958
|
-
|
|
356959
|
-
|
|
356960
|
-
|
|
356961
|
-
|
|
356962
|
-
|
|
356963
|
-
|
|
356964
|
-
|
|
356965
|
-
|
|
356966
|
-
const
|
|
356967
|
-
type: "summary",
|
|
356968
|
-
summary: {
|
|
356969
|
-
isPending: true,
|
|
356970
|
-
stage: "generating"
|
|
356971
|
-
}
|
|
356972
|
-
};
|
|
356973
|
-
ui2.setPendingItem(pendingMessage);
|
|
356974
|
-
const conversationContext = history.map((message) => ({
|
|
357041
|
+
return chat.getHistory();
|
|
357042
|
+
}, "getChatHistory");
|
|
357043
|
+
const validateChatHistory = /* @__PURE__ */ __name((history2) => {
|
|
357044
|
+
if (history2.length <= 2) {
|
|
357045
|
+
throw new Error(t4("No conversation found to summarize."));
|
|
357046
|
+
}
|
|
357047
|
+
}, "validateChatHistory");
|
|
357048
|
+
const generateSummaryMarkdown = /* @__PURE__ */ __name(async (history2) => {
|
|
357049
|
+
const conversationContext = history2.map((message) => ({
|
|
356975
357050
|
role: message.role,
|
|
356976
357051
|
parts: message.parts
|
|
356977
357052
|
}));
|
|
@@ -356995,16 +357070,14 @@ var summaryCommand = {
|
|
|
356995
357070
|
const markdownSummary = parts?.map((part) => part.text).filter((text) => typeof text === "string").join("") || "";
|
|
356996
357071
|
if (!markdownSummary) {
|
|
356997
357072
|
throw new Error(
|
|
356998
|
-
|
|
357073
|
+
t4(
|
|
357074
|
+
"Failed to generate summary - no text content received from LLM response"
|
|
357075
|
+
)
|
|
356999
357076
|
);
|
|
357000
357077
|
}
|
|
357001
|
-
|
|
357002
|
-
|
|
357003
|
-
|
|
357004
|
-
isPending: true,
|
|
357005
|
-
stage: "saving"
|
|
357006
|
-
}
|
|
357007
|
-
});
|
|
357078
|
+
return markdownSummary;
|
|
357079
|
+
}, "generateSummaryMarkdown");
|
|
357080
|
+
const saveSummaryToDisk = /* @__PURE__ */ __name(async (markdownSummary) => {
|
|
357008
357081
|
const projectRoot = config2.getProjectRoot();
|
|
357009
357082
|
const qwenDir = path94.join(projectRoot, ".rdmind");
|
|
357010
357083
|
try {
|
|
@@ -357020,42 +357093,137 @@ var summaryCommand = {
|
|
|
357020
357093
|
**Update time**: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
357021
357094
|
`;
|
|
357022
357095
|
await fsPromises5.writeFile(summaryPath, summaryContent, "utf8");
|
|
357096
|
+
return {
|
|
357097
|
+
filePathForDisplay: ".qwen/PROJECT_SUMMARY.md",
|
|
357098
|
+
fullPath: summaryPath
|
|
357099
|
+
};
|
|
357100
|
+
}, "saveSummaryToDisk");
|
|
357101
|
+
const emitInteractivePending = /* @__PURE__ */ __name((stage) => {
|
|
357102
|
+
if (executionMode !== "interactive") {
|
|
357103
|
+
return;
|
|
357104
|
+
}
|
|
357105
|
+
const pendingMessage = {
|
|
357106
|
+
type: "summary",
|
|
357107
|
+
summary: {
|
|
357108
|
+
isPending: true,
|
|
357109
|
+
stage
|
|
357110
|
+
}
|
|
357111
|
+
};
|
|
357112
|
+
ui2.setPendingItem(pendingMessage);
|
|
357113
|
+
}, "emitInteractivePending");
|
|
357114
|
+
const completeInteractive = /* @__PURE__ */ __name((filePathForDisplay) => {
|
|
357115
|
+
if (executionMode !== "interactive") {
|
|
357116
|
+
return;
|
|
357117
|
+
}
|
|
357023
357118
|
ui2.setPendingItem(null);
|
|
357024
357119
|
const completedSummaryItem = {
|
|
357025
357120
|
type: "summary",
|
|
357026
357121
|
summary: {
|
|
357027
357122
|
isPending: false,
|
|
357028
357123
|
stage: "completed",
|
|
357029
|
-
filePath:
|
|
357124
|
+
filePath: filePathForDisplay
|
|
357030
357125
|
}
|
|
357031
357126
|
};
|
|
357032
357127
|
ui2.addItem(completedSummaryItem, Date.now());
|
|
357033
|
-
|
|
357034
|
-
|
|
357035
|
-
|
|
357036
|
-
|
|
357037
|
-
|
|
357038
|
-
|
|
357039
|
-
|
|
357128
|
+
}, "completeInteractive");
|
|
357129
|
+
const formatErrorMessage = /* @__PURE__ */ __name((error2) => t4("Failed to generate project context summary: {{error}}", {
|
|
357130
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
357131
|
+
}), "formatErrorMessage");
|
|
357132
|
+
const failInteractive = /* @__PURE__ */ __name((error2) => {
|
|
357133
|
+
if (executionMode !== "interactive") {
|
|
357134
|
+
return;
|
|
357135
|
+
}
|
|
357040
357136
|
ui2.setPendingItem(null);
|
|
357041
357137
|
ui2.addItem(
|
|
357042
357138
|
{
|
|
357043
357139
|
type: "error",
|
|
357044
|
-
text: `\u274C ${
|
|
357045
|
-
"Failed to generate project context summary: {{error}}",
|
|
357046
|
-
{
|
|
357047
|
-
error: error2 instanceof Error ? error2.message : String(error2)
|
|
357048
|
-
}
|
|
357049
|
-
)}`
|
|
357140
|
+
text: `\u274C ${formatErrorMessage(error2)}`
|
|
357050
357141
|
},
|
|
357051
357142
|
Date.now()
|
|
357052
357143
|
);
|
|
357144
|
+
}, "failInteractive");
|
|
357145
|
+
const formatSuccessMessage = /* @__PURE__ */ __name((filePathForDisplay) => t4("Saved project summary to {{filePathForDisplay}}.", {
|
|
357146
|
+
filePathForDisplay
|
|
357147
|
+
}), "formatSuccessMessage");
|
|
357148
|
+
const returnNoConversationMessage = /* @__PURE__ */ __name(() => {
|
|
357149
|
+
const msg = t4("No conversation found to summarize.");
|
|
357150
|
+
if (executionMode === "acp") {
|
|
357151
|
+
const messages = /* @__PURE__ */ __name(async function* () {
|
|
357152
|
+
yield {
|
|
357153
|
+
messageType: "info",
|
|
357154
|
+
content: msg
|
|
357155
|
+
};
|
|
357156
|
+
}, "messages");
|
|
357157
|
+
return {
|
|
357158
|
+
type: "stream_messages",
|
|
357159
|
+
messages: messages()
|
|
357160
|
+
};
|
|
357161
|
+
}
|
|
357162
|
+
return {
|
|
357163
|
+
type: "message",
|
|
357164
|
+
messageType: "info",
|
|
357165
|
+
content: msg
|
|
357166
|
+
};
|
|
357167
|
+
}, "returnNoConversationMessage");
|
|
357168
|
+
const executeSummaryGeneration = /* @__PURE__ */ __name(async (history2) => {
|
|
357169
|
+
emitInteractivePending("generating");
|
|
357170
|
+
const markdownSummary = await generateSummaryMarkdown(history2);
|
|
357171
|
+
emitInteractivePending("saving");
|
|
357172
|
+
const { filePathForDisplay } = await saveSummaryToDisk(markdownSummary);
|
|
357173
|
+
completeInteractive(filePathForDisplay);
|
|
357174
|
+
return { markdownSummary, filePathForDisplay };
|
|
357175
|
+
}, "executeSummaryGeneration");
|
|
357176
|
+
const history = getChatHistory();
|
|
357177
|
+
try {
|
|
357178
|
+
validateChatHistory(history);
|
|
357179
|
+
} catch (_error) {
|
|
357180
|
+
return returnNoConversationMessage();
|
|
357181
|
+
}
|
|
357182
|
+
if (executionMode === "acp") {
|
|
357183
|
+
const messages = /* @__PURE__ */ __name(async function* () {
|
|
357184
|
+
try {
|
|
357185
|
+
yield {
|
|
357186
|
+
messageType: "info",
|
|
357187
|
+
content: t4("Generating project summary...")
|
|
357188
|
+
};
|
|
357189
|
+
const { filePathForDisplay } = await executeSummaryGeneration(history);
|
|
357190
|
+
yield {
|
|
357191
|
+
messageType: "info",
|
|
357192
|
+
content: formatSuccessMessage(filePathForDisplay)
|
|
357193
|
+
};
|
|
357194
|
+
} catch (error2) {
|
|
357195
|
+
failInteractive(error2);
|
|
357196
|
+
yield {
|
|
357197
|
+
messageType: "error",
|
|
357198
|
+
content: formatErrorMessage(error2)
|
|
357199
|
+
};
|
|
357200
|
+
}
|
|
357201
|
+
}, "messages");
|
|
357202
|
+
return {
|
|
357203
|
+
type: "stream_messages",
|
|
357204
|
+
messages: messages()
|
|
357205
|
+
};
|
|
357206
|
+
}
|
|
357207
|
+
try {
|
|
357208
|
+
const { filePathForDisplay } = await executeSummaryGeneration(history);
|
|
357209
|
+
if (executionMode === "non_interactive") {
|
|
357210
|
+
return {
|
|
357211
|
+
type: "message",
|
|
357212
|
+
messageType: "info",
|
|
357213
|
+
content: formatSuccessMessage(filePathForDisplay)
|
|
357214
|
+
};
|
|
357215
|
+
}
|
|
357216
|
+
return {
|
|
357217
|
+
type: "message",
|
|
357218
|
+
messageType: "info",
|
|
357219
|
+
content: ""
|
|
357220
|
+
};
|
|
357221
|
+
} catch (error2) {
|
|
357222
|
+
failInteractive(error2);
|
|
357053
357223
|
return {
|
|
357054
357224
|
type: "message",
|
|
357055
357225
|
messageType: "error",
|
|
357056
|
-
content:
|
|
357057
|
-
error: error2 instanceof Error ? error2.message : String(error2)
|
|
357058
|
-
})
|
|
357226
|
+
content: formatErrorMessage(error2)
|
|
357059
357227
|
};
|
|
357060
357228
|
}
|
|
357061
357229
|
}, "action")
|
|
@@ -358468,67 +358636,908 @@ var BuiltinCommandLoader = class {
|
|
|
358468
358636
|
}
|
|
358469
358637
|
};
|
|
358470
358638
|
|
|
358471
|
-
// packages/cli/src/
|
|
358639
|
+
// packages/cli/src/services/FileCommandLoader.ts
|
|
358472
358640
|
init_esbuild_shims();
|
|
358473
|
-
|
|
358474
|
-
|
|
358475
|
-
|
|
358641
|
+
var import_toml = __toESM(require_toml(), 1);
|
|
358642
|
+
init_esm11();
|
|
358643
|
+
init_zod();
|
|
358644
|
+
init_core5();
|
|
358645
|
+
import { promises as fs90 } from "node:fs";
|
|
358646
|
+
import path98 from "node:path";
|
|
358647
|
+
|
|
358648
|
+
// packages/cli/src/services/prompt-processors/argumentProcessor.ts
|
|
358649
|
+
init_esbuild_shims();
|
|
358650
|
+
init_core5();
|
|
358651
|
+
var DefaultArgumentProcessor = class {
|
|
358652
|
+
static {
|
|
358653
|
+
__name(this, "DefaultArgumentProcessor");
|
|
358476
358654
|
}
|
|
358477
|
-
|
|
358655
|
+
async process(prompt, context2) {
|
|
358656
|
+
if (context2.invocation?.args) {
|
|
358657
|
+
return appendToLastTextPart(prompt, context2.invocation.raw);
|
|
358658
|
+
}
|
|
358659
|
+
return prompt;
|
|
358660
|
+
}
|
|
358661
|
+
};
|
|
358662
|
+
|
|
358663
|
+
// packages/cli/src/services/prompt-processors/types.ts
|
|
358664
|
+
init_esbuild_shims();
|
|
358665
|
+
var SHORTHAND_ARGS_PLACEHOLDER = "{{args}}";
|
|
358666
|
+
var SHELL_INJECTION_TRIGGER = "!{";
|
|
358667
|
+
var AT_FILE_INJECTION_TRIGGER = "@{";
|
|
358668
|
+
|
|
358669
|
+
// packages/cli/src/services/prompt-processors/shellProcessor.ts
|
|
358670
|
+
init_esbuild_shims();
|
|
358671
|
+
init_core5();
|
|
358672
|
+
|
|
358673
|
+
// packages/cli/src/services/prompt-processors/injectionParser.ts
|
|
358674
|
+
init_esbuild_shims();
|
|
358675
|
+
function extractInjections(prompt, trigger, contextName) {
|
|
358676
|
+
const injections = [];
|
|
358677
|
+
let index = 0;
|
|
358678
|
+
while (index < prompt.length) {
|
|
358679
|
+
const startIndex = prompt.indexOf(trigger, index);
|
|
358680
|
+
if (startIndex === -1) {
|
|
358681
|
+
break;
|
|
358682
|
+
}
|
|
358683
|
+
let currentIndex = startIndex + trigger.length;
|
|
358684
|
+
let braceCount = 1;
|
|
358685
|
+
let foundEnd = false;
|
|
358686
|
+
while (currentIndex < prompt.length) {
|
|
358687
|
+
const char = prompt[currentIndex];
|
|
358688
|
+
if (char === "{") {
|
|
358689
|
+
braceCount++;
|
|
358690
|
+
} else if (char === "}") {
|
|
358691
|
+
braceCount--;
|
|
358692
|
+
if (braceCount === 0) {
|
|
358693
|
+
const injectionContent = prompt.substring(
|
|
358694
|
+
startIndex + trigger.length,
|
|
358695
|
+
currentIndex
|
|
358696
|
+
);
|
|
358697
|
+
const endIndex = currentIndex + 1;
|
|
358698
|
+
injections.push({
|
|
358699
|
+
content: injectionContent.trim(),
|
|
358700
|
+
startIndex,
|
|
358701
|
+
endIndex
|
|
358702
|
+
});
|
|
358703
|
+
index = endIndex;
|
|
358704
|
+
foundEnd = true;
|
|
358705
|
+
break;
|
|
358706
|
+
}
|
|
358707
|
+
}
|
|
358708
|
+
currentIndex++;
|
|
358709
|
+
}
|
|
358710
|
+
if (!foundEnd) {
|
|
358711
|
+
const contextInfo = contextName ? ` in command '${contextName}'` : "";
|
|
358712
|
+
throw new Error(
|
|
358713
|
+
`Invalid syntax${contextInfo}: Unclosed injection starting at index ${startIndex} ('${trigger}'). Ensure braces are balanced. Paths or commands with unbalanced braces are not supported directly.`
|
|
358714
|
+
);
|
|
358715
|
+
}
|
|
358716
|
+
}
|
|
358717
|
+
return injections;
|
|
358478
358718
|
}
|
|
358479
|
-
__name(
|
|
358480
|
-
|
|
358481
|
-
|
|
358482
|
-
|
|
358719
|
+
__name(extractInjections, "extractInjections");
|
|
358720
|
+
|
|
358721
|
+
// packages/cli/src/services/prompt-processors/shellProcessor.ts
|
|
358722
|
+
var ConfirmationRequiredError = class extends Error {
|
|
358723
|
+
constructor(message, commandsToConfirm) {
|
|
358724
|
+
super(message);
|
|
358725
|
+
this.commandsToConfirm = commandsToConfirm;
|
|
358726
|
+
this.name = "ConfirmationRequiredError";
|
|
358483
358727
|
}
|
|
358484
|
-
|
|
358728
|
+
static {
|
|
358729
|
+
__name(this, "ConfirmationRequiredError");
|
|
358730
|
+
}
|
|
358731
|
+
};
|
|
358732
|
+
var ShellProcessor = class {
|
|
358733
|
+
constructor(commandName) {
|
|
358734
|
+
this.commandName = commandName;
|
|
358735
|
+
}
|
|
358736
|
+
static {
|
|
358737
|
+
__name(this, "ShellProcessor");
|
|
358738
|
+
}
|
|
358739
|
+
async process(prompt, context2) {
|
|
358740
|
+
return flatMapTextParts(
|
|
358741
|
+
prompt,
|
|
358742
|
+
(text) => this.processString(text, context2)
|
|
358743
|
+
);
|
|
358744
|
+
}
|
|
358745
|
+
async processString(prompt, context2) {
|
|
358746
|
+
const userArgsRaw = context2.invocation?.args || "";
|
|
358747
|
+
if (!prompt.includes(SHELL_INJECTION_TRIGGER)) {
|
|
358748
|
+
return [
|
|
358749
|
+
{ text: prompt.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw) }
|
|
358750
|
+
];
|
|
358751
|
+
}
|
|
358752
|
+
const config2 = context2.services.config;
|
|
358753
|
+
if (!config2) {
|
|
358754
|
+
throw new Error(
|
|
358755
|
+
`Security configuration not loaded. Cannot verify shell command permissions for '${this.commandName}'. Aborting.`
|
|
358756
|
+
);
|
|
358757
|
+
}
|
|
358758
|
+
const { sessionShellAllowlist } = context2.session;
|
|
358759
|
+
const injections = extractInjections(
|
|
358760
|
+
prompt,
|
|
358761
|
+
SHELL_INJECTION_TRIGGER,
|
|
358762
|
+
this.commandName
|
|
358763
|
+
);
|
|
358764
|
+
if (injections.length === 0) {
|
|
358765
|
+
return [
|
|
358766
|
+
{ text: prompt.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw) }
|
|
358767
|
+
];
|
|
358768
|
+
}
|
|
358769
|
+
const { shell: shell2 } = getShellConfiguration();
|
|
358770
|
+
const userArgsEscaped = escapeShellArg(userArgsRaw, shell2);
|
|
358771
|
+
const resolvedInjections = injections.map(
|
|
358772
|
+
(injection) => {
|
|
358773
|
+
const command2 = injection.content;
|
|
358774
|
+
if (command2 === "") {
|
|
358775
|
+
return { ...injection, resolvedCommand: void 0 };
|
|
358776
|
+
}
|
|
358777
|
+
const resolvedCommand = command2.replaceAll(
|
|
358778
|
+
SHORTHAND_ARGS_PLACEHOLDER,
|
|
358779
|
+
userArgsEscaped
|
|
358780
|
+
);
|
|
358781
|
+
return { ...injection, resolvedCommand };
|
|
358782
|
+
}
|
|
358783
|
+
);
|
|
358784
|
+
const commandsToConfirm = /* @__PURE__ */ new Set();
|
|
358785
|
+
for (const injection of resolvedInjections) {
|
|
358786
|
+
const command2 = injection.resolvedCommand;
|
|
358787
|
+
if (!command2) continue;
|
|
358788
|
+
const { allAllowed, disallowedCommands, blockReason, isHardDenial } = checkCommandPermissions(command2, config2, sessionShellAllowlist);
|
|
358789
|
+
if (!allAllowed) {
|
|
358790
|
+
if (isHardDenial) {
|
|
358791
|
+
throw new Error(
|
|
358792
|
+
`${this.commandName} cannot be run. Blocked command: "${command2}". Reason: ${blockReason || "Blocked by configuration."}`
|
|
358793
|
+
);
|
|
358794
|
+
}
|
|
358795
|
+
if (config2.getApprovalMode() !== "yolo" /* YOLO */) {
|
|
358796
|
+
disallowedCommands.forEach((uc) => commandsToConfirm.add(uc));
|
|
358797
|
+
}
|
|
358798
|
+
}
|
|
358799
|
+
}
|
|
358800
|
+
if (commandsToConfirm.size > 0) {
|
|
358801
|
+
throw new ConfirmationRequiredError(
|
|
358802
|
+
"Shell command confirmation required",
|
|
358803
|
+
Array.from(commandsToConfirm)
|
|
358804
|
+
);
|
|
358805
|
+
}
|
|
358806
|
+
let processedPrompt = "";
|
|
358807
|
+
let lastIndex = 0;
|
|
358808
|
+
for (const injection of resolvedInjections) {
|
|
358809
|
+
const segment = prompt.substring(lastIndex, injection.startIndex);
|
|
358810
|
+
processedPrompt += segment.replaceAll(
|
|
358811
|
+
SHORTHAND_ARGS_PLACEHOLDER,
|
|
358812
|
+
userArgsRaw
|
|
358813
|
+
);
|
|
358814
|
+
if (injection.resolvedCommand) {
|
|
358815
|
+
const activeTheme = themeManager.getActiveTheme();
|
|
358816
|
+
const shellExecutionConfig = {
|
|
358817
|
+
...config2.getShellExecutionConfig(),
|
|
358818
|
+
defaultFg: activeTheme.colors.Foreground,
|
|
358819
|
+
defaultBg: activeTheme.colors.Background
|
|
358820
|
+
};
|
|
358821
|
+
const { result } = await ShellExecutionService.execute(
|
|
358822
|
+
injection.resolvedCommand,
|
|
358823
|
+
config2.getTargetDir(),
|
|
358824
|
+
() => {
|
|
358825
|
+
},
|
|
358826
|
+
new AbortController().signal,
|
|
358827
|
+
config2.getShouldUseNodePtyShell(),
|
|
358828
|
+
shellExecutionConfig
|
|
358829
|
+
);
|
|
358830
|
+
const executionResult = await result;
|
|
358831
|
+
if (executionResult.error && !executionResult.aborted) {
|
|
358832
|
+
throw new Error(
|
|
358833
|
+
`Failed to start shell command in '${this.commandName}': ${executionResult.error.message}. Command: ${injection.resolvedCommand}`
|
|
358834
|
+
);
|
|
358835
|
+
}
|
|
358836
|
+
processedPrompt += executionResult.output;
|
|
358837
|
+
if (executionResult.aborted) {
|
|
358838
|
+
processedPrompt += `
|
|
358839
|
+
[Shell command '${injection.resolvedCommand}' aborted]`;
|
|
358840
|
+
} else if (executionResult.exitCode !== 0 && executionResult.exitCode !== null) {
|
|
358841
|
+
processedPrompt += `
|
|
358842
|
+
[Shell command '${injection.resolvedCommand}' exited with code ${executionResult.exitCode}]`;
|
|
358843
|
+
} else if (executionResult.signal !== null) {
|
|
358844
|
+
processedPrompt += `
|
|
358845
|
+
[Shell command '${injection.resolvedCommand}' terminated by signal ${executionResult.signal}]`;
|
|
358846
|
+
}
|
|
358847
|
+
}
|
|
358848
|
+
lastIndex = injection.endIndex;
|
|
358849
|
+
}
|
|
358850
|
+
const finalSegment = prompt.substring(lastIndex);
|
|
358851
|
+
processedPrompt += finalSegment.replaceAll(
|
|
358852
|
+
SHORTHAND_ARGS_PLACEHOLDER,
|
|
358853
|
+
userArgsRaw
|
|
358854
|
+
);
|
|
358855
|
+
return [{ text: processedPrompt }];
|
|
358856
|
+
}
|
|
358857
|
+
};
|
|
358858
|
+
|
|
358859
|
+
// packages/cli/src/services/prompt-processors/atFileProcessor.ts
|
|
358860
|
+
init_esbuild_shims();
|
|
358861
|
+
init_core5();
|
|
358862
|
+
var AtFileProcessor = class {
|
|
358863
|
+
constructor(commandName) {
|
|
358864
|
+
this.commandName = commandName;
|
|
358865
|
+
}
|
|
358866
|
+
static {
|
|
358867
|
+
__name(this, "AtFileProcessor");
|
|
358868
|
+
}
|
|
358869
|
+
async process(input, context2) {
|
|
358870
|
+
const config2 = context2.services.config;
|
|
358871
|
+
if (!config2) {
|
|
358872
|
+
return input;
|
|
358873
|
+
}
|
|
358874
|
+
return flatMapTextParts(input, async (text) => {
|
|
358875
|
+
if (!text.includes(AT_FILE_INJECTION_TRIGGER)) {
|
|
358876
|
+
return [{ text }];
|
|
358877
|
+
}
|
|
358878
|
+
const injections = extractInjections(
|
|
358879
|
+
text,
|
|
358880
|
+
AT_FILE_INJECTION_TRIGGER,
|
|
358881
|
+
this.commandName
|
|
358882
|
+
);
|
|
358883
|
+
if (injections.length === 0) {
|
|
358884
|
+
return [{ text }];
|
|
358885
|
+
}
|
|
358886
|
+
const output = [];
|
|
358887
|
+
let lastIndex = 0;
|
|
358888
|
+
for (const injection of injections) {
|
|
358889
|
+
const prefix = text.substring(lastIndex, injection.startIndex);
|
|
358890
|
+
if (prefix) {
|
|
358891
|
+
output.push({ text: prefix });
|
|
358892
|
+
}
|
|
358893
|
+
const pathStr = injection.content;
|
|
358894
|
+
try {
|
|
358895
|
+
const fileContentParts = await readPathFromWorkspace(pathStr, config2);
|
|
358896
|
+
if (fileContentParts.length === 0) {
|
|
358897
|
+
const uiMessage = `File '@{${pathStr}}' was ignored by .gitignore or .rdmindignore and was not included in the prompt.`;
|
|
358898
|
+
context2.ui.addItem(
|
|
358899
|
+
{ type: "info" /* INFO */, text: uiMessage },
|
|
358900
|
+
Date.now()
|
|
358901
|
+
);
|
|
358902
|
+
}
|
|
358903
|
+
output.push(...fileContentParts);
|
|
358904
|
+
} catch (error2) {
|
|
358905
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
358906
|
+
const uiMessage = `Failed to inject content for '@{${pathStr}}': ${message}`;
|
|
358907
|
+
console.error(
|
|
358908
|
+
`[AtFileProcessor] ${uiMessage}. Leaving placeholder in prompt.`
|
|
358909
|
+
);
|
|
358910
|
+
context2.ui.addItem(
|
|
358911
|
+
{ type: "error" /* ERROR */, text: uiMessage },
|
|
358912
|
+
Date.now()
|
|
358913
|
+
);
|
|
358914
|
+
const placeholder = text.substring(
|
|
358915
|
+
injection.startIndex,
|
|
358916
|
+
injection.endIndex
|
|
358917
|
+
);
|
|
358918
|
+
output.push({ text: placeholder });
|
|
358919
|
+
}
|
|
358920
|
+
lastIndex = injection.endIndex;
|
|
358921
|
+
}
|
|
358922
|
+
const suffix = text.substring(lastIndex);
|
|
358923
|
+
if (suffix) {
|
|
358924
|
+
output.push({ text: suffix });
|
|
358925
|
+
}
|
|
358926
|
+
return output;
|
|
358927
|
+
});
|
|
358928
|
+
}
|
|
358929
|
+
};
|
|
358930
|
+
|
|
358931
|
+
// packages/cli/src/services/FileCommandLoader.ts
|
|
358932
|
+
var TomlCommandDefSchema = external_exports.object({
|
|
358933
|
+
prompt: external_exports.string({
|
|
358934
|
+
required_error: "The 'prompt' field is required.",
|
|
358935
|
+
invalid_type_error: "The 'prompt' field must be a string."
|
|
358936
|
+
}),
|
|
358937
|
+
description: external_exports.string().optional()
|
|
358938
|
+
});
|
|
358939
|
+
var FileCommandLoader = class {
|
|
358940
|
+
constructor(config2) {
|
|
358941
|
+
this.config = config2;
|
|
358942
|
+
this.folderTrustEnabled = !!config2?.getFolderTrustFeature();
|
|
358943
|
+
this.folderTrust = !!config2?.getFolderTrust();
|
|
358944
|
+
this.projectRoot = config2?.getProjectRoot() || process.cwd();
|
|
358945
|
+
}
|
|
358946
|
+
static {
|
|
358947
|
+
__name(this, "FileCommandLoader");
|
|
358948
|
+
}
|
|
358949
|
+
projectRoot;
|
|
358950
|
+
folderTrustEnabled;
|
|
358951
|
+
folderTrust;
|
|
358952
|
+
/**
|
|
358953
|
+
* Loads all commands from user, project, and extension directories.
|
|
358954
|
+
* Returns commands in order: user → project → extensions (alphabetically).
|
|
358955
|
+
*
|
|
358956
|
+
* Order is important for conflict resolution in CommandService:
|
|
358957
|
+
* - User/project commands (without extensionName) use "last wins" strategy
|
|
358958
|
+
* - Extension commands (with extensionName) get renamed if conflicts exist
|
|
358959
|
+
*
|
|
358960
|
+
* @param signal An AbortSignal to cancel the loading process.
|
|
358961
|
+
* @returns A promise that resolves to an array of all loaded SlashCommands.
|
|
358962
|
+
*/
|
|
358963
|
+
async loadCommands(signal) {
|
|
358964
|
+
const allCommands = [];
|
|
358965
|
+
const globOptions = {
|
|
358966
|
+
nodir: true,
|
|
358967
|
+
dot: true,
|
|
358968
|
+
signal,
|
|
358969
|
+
follow: true
|
|
358970
|
+
};
|
|
358971
|
+
const commandDirs = this.getCommandDirectories();
|
|
358972
|
+
for (const dirInfo of commandDirs) {
|
|
358973
|
+
try {
|
|
358974
|
+
const files = await glob("**/*.toml", {
|
|
358975
|
+
...globOptions,
|
|
358976
|
+
cwd: dirInfo.path
|
|
358977
|
+
});
|
|
358978
|
+
if (this.folderTrustEnabled && !this.folderTrust) {
|
|
358979
|
+
return [];
|
|
358980
|
+
}
|
|
358981
|
+
const commandPromises = files.map(
|
|
358982
|
+
(file) => this.parseAndAdaptFile(
|
|
358983
|
+
path98.join(dirInfo.path, file),
|
|
358984
|
+
dirInfo.path,
|
|
358985
|
+
dirInfo.extensionName
|
|
358986
|
+
)
|
|
358987
|
+
);
|
|
358988
|
+
const commands = (await Promise.all(commandPromises)).filter(
|
|
358989
|
+
(cmd) => cmd !== null
|
|
358990
|
+
);
|
|
358991
|
+
allCommands.push(...commands);
|
|
358992
|
+
} catch (error2) {
|
|
358993
|
+
const isEnoent = error2.code === "ENOENT";
|
|
358994
|
+
const isAbortError2 = error2 instanceof Error && error2.name === "AbortError";
|
|
358995
|
+
if (!isEnoent && !isAbortError2) {
|
|
358996
|
+
console.error(
|
|
358997
|
+
`[FileCommandLoader] Error loading commands from ${dirInfo.path}:`,
|
|
358998
|
+
error2
|
|
358999
|
+
);
|
|
359000
|
+
}
|
|
359001
|
+
}
|
|
359002
|
+
}
|
|
359003
|
+
return allCommands;
|
|
359004
|
+
}
|
|
359005
|
+
/**
|
|
359006
|
+
* Get all command directories in order for loading.
|
|
359007
|
+
* User commands → Project commands → Extension commands
|
|
359008
|
+
* This order ensures extension commands can detect all conflicts.
|
|
359009
|
+
*/
|
|
359010
|
+
getCommandDirectories() {
|
|
359011
|
+
const dirs = [];
|
|
359012
|
+
const storage = this.config?.storage ?? new Storage(this.projectRoot);
|
|
359013
|
+
dirs.push({ path: Storage.getUserCommandsDir() });
|
|
359014
|
+
dirs.push({ path: storage.getProjectCommandsDir() });
|
|
359015
|
+
if (this.config) {
|
|
359016
|
+
const activeExtensions = this.config.getExtensions().filter((ext2) => ext2.isActive).sort((a2, b2) => a2.name.localeCompare(b2.name));
|
|
359017
|
+
const extensionCommandDirs = activeExtensions.map((ext2) => ({
|
|
359018
|
+
path: path98.join(ext2.path, "commands"),
|
|
359019
|
+
extensionName: ext2.name
|
|
359020
|
+
}));
|
|
359021
|
+
dirs.push(...extensionCommandDirs);
|
|
359022
|
+
}
|
|
359023
|
+
return dirs;
|
|
359024
|
+
}
|
|
359025
|
+
/**
|
|
359026
|
+
* Parses a single .toml file and transforms it into a SlashCommand object.
|
|
359027
|
+
* @param filePath The absolute path to the .toml file.
|
|
359028
|
+
* @param baseDir The root command directory for name calculation.
|
|
359029
|
+
* @param extensionName Optional extension name to prefix commands with.
|
|
359030
|
+
* @returns A promise resolving to a SlashCommand, or null if the file is invalid.
|
|
359031
|
+
*/
|
|
359032
|
+
async parseAndAdaptFile(filePath, baseDir, extensionName) {
|
|
359033
|
+
let fileContent;
|
|
359034
|
+
try {
|
|
359035
|
+
fileContent = await fs90.readFile(filePath, "utf-8");
|
|
359036
|
+
} catch (error2) {
|
|
359037
|
+
console.error(
|
|
359038
|
+
`[FileCommandLoader] Failed to read file ${filePath}:`,
|
|
359039
|
+
error2 instanceof Error ? error2.message : String(error2)
|
|
359040
|
+
);
|
|
359041
|
+
return null;
|
|
359042
|
+
}
|
|
359043
|
+
let parsed;
|
|
359044
|
+
try {
|
|
359045
|
+
parsed = import_toml.default.parse(fileContent);
|
|
359046
|
+
} catch (error2) {
|
|
359047
|
+
console.error(
|
|
359048
|
+
`[FileCommandLoader] Failed to parse TOML file ${filePath}:`,
|
|
359049
|
+
error2 instanceof Error ? error2.message : String(error2)
|
|
359050
|
+
);
|
|
359051
|
+
return null;
|
|
359052
|
+
}
|
|
359053
|
+
const validationResult = TomlCommandDefSchema.safeParse(parsed);
|
|
359054
|
+
if (!validationResult.success) {
|
|
359055
|
+
console.error(
|
|
359056
|
+
`[FileCommandLoader] Skipping invalid command file: ${filePath}. Validation errors:`,
|
|
359057
|
+
validationResult.error.flatten()
|
|
359058
|
+
);
|
|
359059
|
+
return null;
|
|
359060
|
+
}
|
|
359061
|
+
const validDef = validationResult.data;
|
|
359062
|
+
const relativePathWithExt = path98.relative(baseDir, filePath);
|
|
359063
|
+
const relativePath = relativePathWithExt.substring(
|
|
359064
|
+
0,
|
|
359065
|
+
relativePathWithExt.length - 5
|
|
359066
|
+
// length of '.toml'
|
|
359067
|
+
);
|
|
359068
|
+
const baseCommandName = relativePath.split(path98.sep).map((segment) => segment.replaceAll(":", "_")).join(":");
|
|
359069
|
+
const defaultDescription = `Custom command from ${path98.basename(filePath)}`;
|
|
359070
|
+
let description = validDef.description || defaultDescription;
|
|
359071
|
+
if (extensionName) {
|
|
359072
|
+
description = `[${extensionName}] ${description}`;
|
|
359073
|
+
}
|
|
359074
|
+
const processors = [];
|
|
359075
|
+
const usesArgs = validDef.prompt.includes(SHORTHAND_ARGS_PLACEHOLDER);
|
|
359076
|
+
const usesShellInjection = validDef.prompt.includes(
|
|
359077
|
+
SHELL_INJECTION_TRIGGER
|
|
359078
|
+
);
|
|
359079
|
+
const usesAtFileInjection = validDef.prompt.includes(
|
|
359080
|
+
AT_FILE_INJECTION_TRIGGER
|
|
359081
|
+
);
|
|
359082
|
+
if (usesAtFileInjection) {
|
|
359083
|
+
processors.push(new AtFileProcessor(baseCommandName));
|
|
359084
|
+
}
|
|
359085
|
+
if (usesShellInjection || usesArgs) {
|
|
359086
|
+
processors.push(new ShellProcessor(baseCommandName));
|
|
359087
|
+
}
|
|
359088
|
+
if (!usesArgs) {
|
|
359089
|
+
processors.push(new DefaultArgumentProcessor());
|
|
359090
|
+
}
|
|
359091
|
+
return {
|
|
359092
|
+
name: baseCommandName,
|
|
359093
|
+
description,
|
|
359094
|
+
kind: "file" /* FILE */,
|
|
359095
|
+
extensionName,
|
|
359096
|
+
action: /* @__PURE__ */ __name(async (context2, _args) => {
|
|
359097
|
+
if (!context2.invocation) {
|
|
359098
|
+
console.error(
|
|
359099
|
+
`[FileCommandLoader] Critical error: Command '${baseCommandName}' was executed without invocation context.`
|
|
359100
|
+
);
|
|
359101
|
+
return {
|
|
359102
|
+
type: "submit_prompt",
|
|
359103
|
+
content: [{ text: validDef.prompt }]
|
|
359104
|
+
// Fallback to unprocessed prompt
|
|
359105
|
+
};
|
|
359106
|
+
}
|
|
359107
|
+
try {
|
|
359108
|
+
let processedContent = [
|
|
359109
|
+
{ text: validDef.prompt }
|
|
359110
|
+
];
|
|
359111
|
+
for (const processor of processors) {
|
|
359112
|
+
processedContent = await processor.process(
|
|
359113
|
+
processedContent,
|
|
359114
|
+
context2
|
|
359115
|
+
);
|
|
359116
|
+
}
|
|
359117
|
+
return {
|
|
359118
|
+
type: "submit_prompt",
|
|
359119
|
+
content: processedContent
|
|
359120
|
+
};
|
|
359121
|
+
} catch (e4) {
|
|
359122
|
+
if (e4 instanceof ConfirmationRequiredError) {
|
|
359123
|
+
return {
|
|
359124
|
+
type: "confirm_shell_commands",
|
|
359125
|
+
commandsToConfirm: e4.commandsToConfirm,
|
|
359126
|
+
originalInvocation: {
|
|
359127
|
+
raw: context2.invocation.raw
|
|
359128
|
+
}
|
|
359129
|
+
};
|
|
359130
|
+
}
|
|
359131
|
+
throw e4;
|
|
359132
|
+
}
|
|
359133
|
+
}, "action")
|
|
359134
|
+
};
|
|
359135
|
+
}
|
|
359136
|
+
};
|
|
359137
|
+
|
|
359138
|
+
// packages/cli/src/services/MarkdownCommandLoader.ts
|
|
359139
|
+
init_esbuild_shims();
|
|
359140
|
+
init_esm11();
|
|
359141
|
+
init_zod();
|
|
359142
|
+
import { promises as fs91 } from "node:fs";
|
|
359143
|
+
import path99 from "node:path";
|
|
359144
|
+
var MarkdownCommandDefSchema = external_exports.object({
|
|
359145
|
+
name: external_exports.string(),
|
|
359146
|
+
id: external_exports.string().optional(),
|
|
359147
|
+
category: external_exports.string().optional(),
|
|
359148
|
+
description: external_exports.string()
|
|
359149
|
+
});
|
|
359150
|
+
var MarkdownCommandLoader = class {
|
|
359151
|
+
static {
|
|
359152
|
+
__name(this, "MarkdownCommandLoader");
|
|
359153
|
+
}
|
|
359154
|
+
projectRoot;
|
|
359155
|
+
folderTrustEnabled;
|
|
359156
|
+
folderTrust;
|
|
359157
|
+
constructor(config2) {
|
|
359158
|
+
this.folderTrustEnabled = !!config2?.getFolderTrustFeature();
|
|
359159
|
+
this.folderTrust = !!config2?.getFolderTrust();
|
|
359160
|
+
this.projectRoot = config2?.getProjectRoot() || process.cwd();
|
|
359161
|
+
}
|
|
359162
|
+
/**
|
|
359163
|
+
* Loads all markdown commands from OpenSpec directories.
|
|
359164
|
+
*/
|
|
359165
|
+
async loadCommands(signal) {
|
|
359166
|
+
if (this.folderTrustEnabled && !this.folderTrust) {
|
|
359167
|
+
return [];
|
|
359168
|
+
}
|
|
359169
|
+
const allCommands = [];
|
|
359170
|
+
const globOptions = {
|
|
359171
|
+
nodir: true,
|
|
359172
|
+
dot: true,
|
|
359173
|
+
signal,
|
|
359174
|
+
follow: true
|
|
359175
|
+
};
|
|
359176
|
+
const commandDirs = this.getOpenSpecCommandDirectories();
|
|
359177
|
+
for (const dirPath of commandDirs) {
|
|
359178
|
+
try {
|
|
359179
|
+
const files = await glob("**/*.md", {
|
|
359180
|
+
...globOptions,
|
|
359181
|
+
cwd: dirPath
|
|
359182
|
+
});
|
|
359183
|
+
const commandPromises = files.map(
|
|
359184
|
+
(file) => this.parseAndAdaptFile(path99.join(dirPath, file))
|
|
359185
|
+
);
|
|
359186
|
+
const commands = (await Promise.all(commandPromises)).filter(
|
|
359187
|
+
(cmd) => cmd !== null
|
|
359188
|
+
);
|
|
359189
|
+
allCommands.push(...commands);
|
|
359190
|
+
} catch (error2) {
|
|
359191
|
+
const isEnoent = error2.code === "ENOENT";
|
|
359192
|
+
const isAbortError2 = error2 instanceof Error && error2.name === "AbortError";
|
|
359193
|
+
if (!isEnoent && !isAbortError2) {
|
|
359194
|
+
console.error(
|
|
359195
|
+
`[MarkdownCommandLoader] Error loading commands from ${dirPath}:`,
|
|
359196
|
+
error2
|
|
359197
|
+
);
|
|
359198
|
+
}
|
|
359199
|
+
}
|
|
359200
|
+
}
|
|
359201
|
+
return allCommands;
|
|
359202
|
+
}
|
|
359203
|
+
/**
|
|
359204
|
+
* Get directories containing OpenSpec markdown command files.
|
|
359205
|
+
*/
|
|
359206
|
+
getOpenSpecCommandDirectories() {
|
|
359207
|
+
const rdmindCommandsDir = path99.join(
|
|
359208
|
+
this.projectRoot,
|
|
359209
|
+
".rdmind",
|
|
359210
|
+
"commands"
|
|
359211
|
+
);
|
|
359212
|
+
return [rdmindCommandsDir];
|
|
359213
|
+
}
|
|
359214
|
+
/**
|
|
359215
|
+
* Parses a markdown file with YAML front matter and converts it to a SlashCommand.
|
|
359216
|
+
*/
|
|
359217
|
+
async parseAndAdaptFile(filePath) {
|
|
359218
|
+
let fileContent;
|
|
359219
|
+
try {
|
|
359220
|
+
fileContent = await fs91.readFile(filePath, "utf-8");
|
|
359221
|
+
} catch (error2) {
|
|
359222
|
+
console.error(
|
|
359223
|
+
`[MarkdownCommandLoader] Failed to read file ${filePath}:`,
|
|
359224
|
+
error2 instanceof Error ? error2.message : String(error2)
|
|
359225
|
+
);
|
|
359226
|
+
return null;
|
|
359227
|
+
}
|
|
359228
|
+
const frontMatterResult = this.parseFrontMatter(fileContent);
|
|
359229
|
+
if (!frontMatterResult) {
|
|
359230
|
+
return null;
|
|
359231
|
+
}
|
|
359232
|
+
const { frontMatter, content } = frontMatterResult;
|
|
359233
|
+
const validationResult = MarkdownCommandDefSchema.safeParse(frontMatter);
|
|
359234
|
+
if (!validationResult.success) {
|
|
359235
|
+
console.error(
|
|
359236
|
+
`[MarkdownCommandLoader] Invalid front matter in ${filePath}:`,
|
|
359237
|
+
validationResult.error.flatten()
|
|
359238
|
+
);
|
|
359239
|
+
return null;
|
|
359240
|
+
}
|
|
359241
|
+
const validDef = validationResult.data;
|
|
359242
|
+
const commandName = validDef.name.startsWith("/") ? validDef.name.substring(1) : validDef.name;
|
|
359243
|
+
let description = validDef.description;
|
|
359244
|
+
if (commandName === "openspec-proposal") {
|
|
359245
|
+
description = t4("Scaffold a new OpenSpec change and validate strictly.");
|
|
359246
|
+
} else if (commandName === "openspec-apply") {
|
|
359247
|
+
description = t4(
|
|
359248
|
+
"Implement an approved OpenSpec change and keep tasks in sync."
|
|
359249
|
+
);
|
|
359250
|
+
} else if (commandName === "openspec-archive") {
|
|
359251
|
+
description = t4("Archive a deployed OpenSpec change and update specs.");
|
|
359252
|
+
}
|
|
359253
|
+
return {
|
|
359254
|
+
name: commandName,
|
|
359255
|
+
description,
|
|
359256
|
+
kind: "file" /* FILE */,
|
|
359257
|
+
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
359258
|
+
const prompt = content.trim() + (args ? `
|
|
359259
|
+
|
|
359260
|
+
${args}` : "");
|
|
359261
|
+
return {
|
|
359262
|
+
type: "submit_prompt",
|
|
359263
|
+
content: [{ text: prompt }]
|
|
359264
|
+
};
|
|
359265
|
+
}, "action")
|
|
359266
|
+
};
|
|
359267
|
+
}
|
|
359268
|
+
/**
|
|
359269
|
+
* Parses YAML front matter from markdown content.
|
|
359270
|
+
*/
|
|
359271
|
+
parseFrontMatter(content) {
|
|
359272
|
+
const lines = content.split("\n");
|
|
359273
|
+
if (lines[0]?.trim() !== "---") {
|
|
359274
|
+
return null;
|
|
359275
|
+
}
|
|
359276
|
+
let endIndex = -1;
|
|
359277
|
+
for (let i3 = 1; i3 < lines.length; i3++) {
|
|
359278
|
+
if (lines[i3]?.trim() === "---") {
|
|
359279
|
+
endIndex = i3;
|
|
359280
|
+
break;
|
|
359281
|
+
}
|
|
359282
|
+
}
|
|
359283
|
+
if (endIndex === -1) {
|
|
359284
|
+
return null;
|
|
359285
|
+
}
|
|
359286
|
+
const frontMatterLines = lines.slice(1, endIndex);
|
|
359287
|
+
const contentLines = lines.slice(endIndex + 1);
|
|
359288
|
+
try {
|
|
359289
|
+
const frontMatter = {};
|
|
359290
|
+
for (const line of frontMatterLines) {
|
|
359291
|
+
const trimmed2 = line.trim();
|
|
359292
|
+
if (trimmed2 && !trimmed2.startsWith("#")) {
|
|
359293
|
+
const colonIndex = trimmed2.indexOf(":");
|
|
359294
|
+
if (colonIndex > 0) {
|
|
359295
|
+
const key = trimmed2.substring(0, colonIndex).trim();
|
|
359296
|
+
const value = trimmed2.substring(colonIndex + 1).trim();
|
|
359297
|
+
frontMatter[key] = value;
|
|
359298
|
+
}
|
|
359299
|
+
}
|
|
359300
|
+
}
|
|
359301
|
+
return {
|
|
359302
|
+
frontMatter,
|
|
359303
|
+
content: contentLines.join("\n")
|
|
359304
|
+
};
|
|
359305
|
+
} catch (error2) {
|
|
359306
|
+
console.error("Failed to parse front matter:", error2);
|
|
359307
|
+
return null;
|
|
359308
|
+
}
|
|
359309
|
+
}
|
|
359310
|
+
};
|
|
359311
|
+
|
|
359312
|
+
// packages/cli/src/ui/noninteractive/nonInteractiveUi.ts
|
|
359313
|
+
init_esbuild_shims();
|
|
359314
|
+
function createNonInteractiveUI() {
|
|
359315
|
+
return {
|
|
359316
|
+
addItem: /* @__PURE__ */ __name((_item, _timestamp) => 0, "addItem"),
|
|
359317
|
+
clear: /* @__PURE__ */ __name(() => {
|
|
359318
|
+
}, "clear"),
|
|
359319
|
+
setDebugMessage: /* @__PURE__ */ __name((_message) => {
|
|
359320
|
+
}, "setDebugMessage"),
|
|
359321
|
+
loadHistory: /* @__PURE__ */ __name((_newHistory) => {
|
|
359322
|
+
}, "loadHistory"),
|
|
359323
|
+
pendingItem: null,
|
|
359324
|
+
setPendingItem: /* @__PURE__ */ __name((_item) => {
|
|
359325
|
+
}, "setPendingItem"),
|
|
359326
|
+
toggleVimEnabled: /* @__PURE__ */ __name(async () => false, "toggleVimEnabled"),
|
|
359327
|
+
setGeminiMdFileCount: /* @__PURE__ */ __name((_count) => {
|
|
359328
|
+
}, "setGeminiMdFileCount"),
|
|
359329
|
+
reloadCommands: /* @__PURE__ */ __name(() => {
|
|
359330
|
+
}, "reloadCommands"),
|
|
359331
|
+
extensionsUpdateState: /* @__PURE__ */ new Map(),
|
|
359332
|
+
dispatchExtensionStateUpdate: /* @__PURE__ */ __name((_action) => {
|
|
359333
|
+
}, "dispatchExtensionStateUpdate"),
|
|
359334
|
+
addConfirmUpdateExtensionRequest: /* @__PURE__ */ __name((_request) => {
|
|
359335
|
+
}, "addConfirmUpdateExtensionRequest")
|
|
359336
|
+
};
|
|
358485
359337
|
}
|
|
358486
|
-
__name(
|
|
358487
|
-
|
|
358488
|
-
|
|
358489
|
-
|
|
359338
|
+
__name(createNonInteractiveUI, "createNonInteractiveUI");
|
|
359339
|
+
|
|
359340
|
+
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
359341
|
+
var ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE = [
|
|
359342
|
+
"init",
|
|
359343
|
+
"summary",
|
|
359344
|
+
"compress"
|
|
359345
|
+
];
|
|
359346
|
+
function handleCommandResult(result) {
|
|
359347
|
+
switch (result.type) {
|
|
359348
|
+
case "submit_prompt":
|
|
359349
|
+
return {
|
|
359350
|
+
type: "submit_prompt",
|
|
359351
|
+
content: result.content
|
|
359352
|
+
};
|
|
359353
|
+
case "message":
|
|
359354
|
+
return {
|
|
359355
|
+
type: "message",
|
|
359356
|
+
messageType: result.messageType,
|
|
359357
|
+
content: result.content
|
|
359358
|
+
};
|
|
359359
|
+
case "stream_messages":
|
|
359360
|
+
return {
|
|
359361
|
+
type: "stream_messages",
|
|
359362
|
+
messages: result.messages
|
|
359363
|
+
};
|
|
359364
|
+
/**
|
|
359365
|
+
* Currently return types below are never generated due to the
|
|
359366
|
+
* whitelist of allowed slash commands in ACP and non-interactive mode.
|
|
359367
|
+
* We'll try to add more supported return types in the future.
|
|
359368
|
+
*/
|
|
359369
|
+
case "tool":
|
|
359370
|
+
return {
|
|
359371
|
+
type: "unsupported",
|
|
359372
|
+
reason: "Tool execution from slash commands is not supported in non-interactive mode.",
|
|
359373
|
+
originalType: "tool"
|
|
359374
|
+
};
|
|
359375
|
+
case "quit":
|
|
359376
|
+
return {
|
|
359377
|
+
type: "unsupported",
|
|
359378
|
+
reason: "Quit command is not supported in non-interactive mode. The process will exit naturally after completion.",
|
|
359379
|
+
originalType: "quit"
|
|
359380
|
+
};
|
|
359381
|
+
case "dialog":
|
|
359382
|
+
return {
|
|
359383
|
+
type: "unsupported",
|
|
359384
|
+
reason: `Dialog '${result.dialog}' cannot be opened in non-interactive mode.`,
|
|
359385
|
+
originalType: "dialog"
|
|
359386
|
+
};
|
|
359387
|
+
case "load_history":
|
|
359388
|
+
return {
|
|
359389
|
+
type: "unsupported",
|
|
359390
|
+
reason: "Loading history is not supported in non-interactive mode. Each invocation starts with a fresh context.",
|
|
359391
|
+
originalType: "load_history"
|
|
359392
|
+
};
|
|
359393
|
+
case "confirm_shell_commands":
|
|
359394
|
+
return {
|
|
359395
|
+
type: "unsupported",
|
|
359396
|
+
reason: "Shell command confirmation is not supported in non-interactive mode. Use YOLO mode or pre-approve commands.",
|
|
359397
|
+
originalType: "confirm_shell_commands"
|
|
359398
|
+
};
|
|
359399
|
+
case "confirm_action":
|
|
359400
|
+
return {
|
|
359401
|
+
type: "unsupported",
|
|
359402
|
+
reason: "Action confirmation is not supported in non-interactive mode. Commands requiring confirmation cannot be executed.",
|
|
359403
|
+
originalType: "confirm_action"
|
|
359404
|
+
};
|
|
359405
|
+
default: {
|
|
359406
|
+
const _exhaustive = result;
|
|
359407
|
+
return {
|
|
359408
|
+
type: "unsupported",
|
|
359409
|
+
reason: `Unknown command result type: ${_exhaustive.type}`,
|
|
359410
|
+
originalType: "unknown"
|
|
359411
|
+
};
|
|
359412
|
+
}
|
|
358490
359413
|
}
|
|
358491
|
-
return metrics2.tokens.cached / metrics2.tokens.prompt * 100;
|
|
358492
359414
|
}
|
|
358493
|
-
__name(
|
|
358494
|
-
|
|
358495
|
-
|
|
358496
|
-
|
|
358497
|
-
|
|
358498
|
-
|
|
359415
|
+
__name(handleCommandResult, "handleCommandResult");
|
|
359416
|
+
function filterCommandsForNonInteractive(commands, allowedBuiltinCommandNames) {
|
|
359417
|
+
return commands.filter((cmd) => {
|
|
359418
|
+
if (cmd.kind === "file" /* FILE */) {
|
|
359419
|
+
return true;
|
|
359420
|
+
}
|
|
359421
|
+
if (cmd.kind === "markdown" /* MARKDOWN */) {
|
|
359422
|
+
return true;
|
|
359423
|
+
}
|
|
359424
|
+
if (cmd.kind === "built-in" /* BUILT_IN */) {
|
|
359425
|
+
return allowedBuiltinCommandNames.has(cmd.name);
|
|
359426
|
+
}
|
|
359427
|
+
return false;
|
|
359428
|
+
});
|
|
359429
|
+
}
|
|
359430
|
+
__name(filterCommandsForNonInteractive, "filterCommandsForNonInteractive");
|
|
359431
|
+
var handleSlashCommand = /* @__PURE__ */ __name(async (rawQuery, abortController, config2, settings, allowedBuiltinCommandNames = [
|
|
359432
|
+
...ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE
|
|
359433
|
+
]) => {
|
|
359434
|
+
const trimmed2 = rawQuery.trim();
|
|
359435
|
+
if (!trimmed2.startsWith("/")) {
|
|
359436
|
+
return { type: "no_command" };
|
|
359437
|
+
}
|
|
359438
|
+
const isAcpMode = config2.getExperimentalZedIntegration();
|
|
359439
|
+
const isInteractive = config2.isInteractive();
|
|
359440
|
+
const executionMode = isAcpMode ? "acp" : isInteractive ? "interactive" : "non_interactive";
|
|
359441
|
+
const allowedBuiltinSet = new Set(allowedBuiltinCommandNames ?? []);
|
|
359442
|
+
const allLoaders = [
|
|
359443
|
+
new BuiltinCommandLoader(config2),
|
|
359444
|
+
new FileCommandLoader(config2),
|
|
359445
|
+
new MarkdownCommandLoader(config2)
|
|
359446
|
+
];
|
|
359447
|
+
const commandService = await CommandService.create(
|
|
359448
|
+
allLoaders,
|
|
359449
|
+
abortController.signal
|
|
358499
359450
|
);
|
|
358500
|
-
const
|
|
358501
|
-
const
|
|
358502
|
-
|
|
358503
|
-
|
|
358504
|
-
const totalCachedTokens = Object.values(models).reduce(
|
|
358505
|
-
(acc, model) => acc + model.tokens.cached,
|
|
358506
|
-
0
|
|
359451
|
+
const allCommands = commandService.getCommands();
|
|
359452
|
+
const filteredCommands = filterCommandsForNonInteractive(
|
|
359453
|
+
allCommands,
|
|
359454
|
+
allowedBuiltinSet
|
|
358507
359455
|
);
|
|
358508
|
-
const
|
|
358509
|
-
|
|
358510
|
-
|
|
359456
|
+
const { commandToExecute, args } = parseSlashCommand(
|
|
359457
|
+
rawQuery,
|
|
359458
|
+
filteredCommands
|
|
358511
359459
|
);
|
|
358512
|
-
|
|
358513
|
-
|
|
358514
|
-
|
|
358515
|
-
|
|
358516
|
-
|
|
358517
|
-
|
|
358518
|
-
|
|
358519
|
-
|
|
358520
|
-
|
|
358521
|
-
|
|
358522
|
-
|
|
358523
|
-
|
|
358524
|
-
|
|
358525
|
-
|
|
358526
|
-
|
|
358527
|
-
|
|
358528
|
-
|
|
358529
|
-
|
|
359460
|
+
if (!commandToExecute) {
|
|
359461
|
+
const { commandToExecute: knownCommand } = parseSlashCommand(
|
|
359462
|
+
rawQuery,
|
|
359463
|
+
allCommands
|
|
359464
|
+
);
|
|
359465
|
+
if (knownCommand) {
|
|
359466
|
+
return {
|
|
359467
|
+
type: "unsupported",
|
|
359468
|
+
reason: t4(
|
|
359469
|
+
'The command "/{{command}}" is not supported in non-interactive mode.',
|
|
359470
|
+
{ command: knownCommand.name }
|
|
359471
|
+
),
|
|
359472
|
+
originalType: "filtered_command"
|
|
359473
|
+
};
|
|
359474
|
+
}
|
|
359475
|
+
return { type: "no_command" };
|
|
359476
|
+
}
|
|
359477
|
+
if (!commandToExecute.action) {
|
|
359478
|
+
return { type: "no_command" };
|
|
359479
|
+
}
|
|
359480
|
+
const sessionStats = {
|
|
359481
|
+
sessionId: config2?.getSessionId(),
|
|
359482
|
+
sessionStartTime: /* @__PURE__ */ new Date(),
|
|
359483
|
+
metrics: uiTelemetryService.getMetrics(),
|
|
359484
|
+
lastPromptTokenCount: 0,
|
|
359485
|
+
promptCount: 1
|
|
358530
359486
|
};
|
|
358531
|
-
|
|
359487
|
+
const logger6 = new Logger(config2?.getSessionId() || "", config2?.storage);
|
|
359488
|
+
const context2 = {
|
|
359489
|
+
executionMode,
|
|
359490
|
+
services: {
|
|
359491
|
+
config: config2,
|
|
359492
|
+
settings,
|
|
359493
|
+
git: void 0,
|
|
359494
|
+
logger: logger6
|
|
359495
|
+
},
|
|
359496
|
+
ui: createNonInteractiveUI(),
|
|
359497
|
+
session: {
|
|
359498
|
+
stats: sessionStats,
|
|
359499
|
+
sessionShellAllowlist: /* @__PURE__ */ new Set()
|
|
359500
|
+
},
|
|
359501
|
+
invocation: {
|
|
359502
|
+
raw: trimmed2,
|
|
359503
|
+
name: commandToExecute.name,
|
|
359504
|
+
args
|
|
359505
|
+
}
|
|
359506
|
+
};
|
|
359507
|
+
const result = await commandToExecute.action(context2, args);
|
|
359508
|
+
if (!result) {
|
|
359509
|
+
return {
|
|
359510
|
+
type: "message",
|
|
359511
|
+
messageType: "info",
|
|
359512
|
+
content: "Command executed successfully."
|
|
359513
|
+
};
|
|
359514
|
+
}
|
|
359515
|
+
return handleCommandResult(result);
|
|
359516
|
+
}, "handleSlashCommand");
|
|
359517
|
+
var getAvailableCommands = /* @__PURE__ */ __name(async (config2, abortSignal, allowedBuiltinCommandNames = [
|
|
359518
|
+
...ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE
|
|
359519
|
+
]) => {
|
|
359520
|
+
try {
|
|
359521
|
+
const allowedBuiltinSet = new Set(allowedBuiltinCommandNames ?? []);
|
|
359522
|
+
const loaders = [
|
|
359523
|
+
new FileCommandLoader(config2),
|
|
359524
|
+
new MarkdownCommandLoader(config2)
|
|
359525
|
+
];
|
|
359526
|
+
if (allowedBuiltinSet.size > 0) {
|
|
359527
|
+
loaders.push(new BuiltinCommandLoader(config2));
|
|
359528
|
+
}
|
|
359529
|
+
const commandService = await CommandService.create(loaders, abortSignal);
|
|
359530
|
+
const commands = commandService.getCommands();
|
|
359531
|
+
const filteredCommands = filterCommandsForNonInteractive(
|
|
359532
|
+
commands,
|
|
359533
|
+
allowedBuiltinSet
|
|
359534
|
+
);
|
|
359535
|
+
return filteredCommands.filter((cmd) => !cmd.hidden);
|
|
359536
|
+
} catch (error2) {
|
|
359537
|
+
console.error("Error loading available commands:", error2);
|
|
359538
|
+
return [];
|
|
359539
|
+
}
|
|
359540
|
+
}, "getAvailableCommands");
|
|
358532
359541
|
|
|
358533
359542
|
// packages/cli/src/utils/nonInteractiveHelpers.ts
|
|
358534
359543
|
function normalizePartList(parts) {
|
|
@@ -358593,19 +359602,15 @@ function computeUsageFromMetrics(metrics2) {
|
|
|
358593
359602
|
return usage2;
|
|
358594
359603
|
}
|
|
358595
359604
|
__name(computeUsageFromMetrics, "computeUsageFromMetrics");
|
|
358596
|
-
async function loadSlashCommandNames(config2) {
|
|
359605
|
+
async function loadSlashCommandNames(config2, allowedBuiltinCommandNames) {
|
|
358597
359606
|
const controller = new AbortController();
|
|
358598
359607
|
try {
|
|
358599
|
-
const
|
|
358600
|
-
|
|
358601
|
-
controller.signal
|
|
359608
|
+
const commands = await getAvailableCommands(
|
|
359609
|
+
config2,
|
|
359610
|
+
controller.signal,
|
|
359611
|
+
allowedBuiltinCommandNames
|
|
358602
359612
|
);
|
|
358603
|
-
|
|
358604
|
-
const commands = service.getCommands();
|
|
358605
|
-
for (const command2 of commands) {
|
|
358606
|
-
names.add(command2.name);
|
|
358607
|
-
}
|
|
358608
|
-
return Array.from(names).sort();
|
|
359613
|
+
return commands.map((cmd) => cmd.name).sort();
|
|
358609
359614
|
} catch (error2) {
|
|
358610
359615
|
if (config2.getDebugMode()) {
|
|
358611
359616
|
console.error(
|
|
@@ -358619,7 +359624,7 @@ async function loadSlashCommandNames(config2) {
|
|
|
358619
359624
|
}
|
|
358620
359625
|
}
|
|
358621
359626
|
__name(loadSlashCommandNames, "loadSlashCommandNames");
|
|
358622
|
-
async function buildSystemMessage(config2, sessionId, permissionMode) {
|
|
359627
|
+
async function buildSystemMessage(config2, sessionId, permissionMode, allowedBuiltinCommandNames) {
|
|
358623
359628
|
const toolRegistry = config2.getToolRegistry();
|
|
358624
359629
|
const tools = toolRegistry ? toolRegistry.getAllToolNames() : [];
|
|
358625
359630
|
const mcpServers = config2.getMcpServers();
|
|
@@ -358627,7 +359632,10 @@ async function buildSystemMessage(config2, sessionId, permissionMode) {
|
|
|
358627
359632
|
name: name3,
|
|
358628
359633
|
status: getMCPServerStatus(name3)
|
|
358629
359634
|
})) : [];
|
|
358630
|
-
const slashCommands = await loadSlashCommandNames(
|
|
359635
|
+
const slashCommands = await loadSlashCommandNames(
|
|
359636
|
+
config2,
|
|
359637
|
+
allowedBuiltinCommandNames
|
|
359638
|
+
);
|
|
358631
359639
|
let agentNames = [];
|
|
358632
359640
|
try {
|
|
358633
359641
|
const subagentManager = config2.getSubagentManager();
|
|
@@ -359880,866 +360888,6 @@ var StreamJsonOutputAdapter = class extends BaseJsonOutputAdapter {
|
|
|
359880
360888
|
}
|
|
359881
360889
|
};
|
|
359882
360890
|
|
|
359883
|
-
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
359884
|
-
init_esbuild_shims();
|
|
359885
|
-
|
|
359886
|
-
// packages/cli/src/utils/commands.ts
|
|
359887
|
-
init_esbuild_shims();
|
|
359888
|
-
var parseSlashCommand = /* @__PURE__ */ __name((query, commands) => {
|
|
359889
|
-
const trimmed2 = query.trim();
|
|
359890
|
-
const parts = trimmed2.substring(1).trim().split(/\s+/);
|
|
359891
|
-
const commandPath = parts.filter((p2) => p2);
|
|
359892
|
-
let currentCommands = commands;
|
|
359893
|
-
let commandToExecute;
|
|
359894
|
-
let pathIndex = 0;
|
|
359895
|
-
const canonicalPath = [];
|
|
359896
|
-
for (const part of commandPath) {
|
|
359897
|
-
let foundCommand = currentCommands.find((cmd) => cmd.name === part);
|
|
359898
|
-
if (!foundCommand) {
|
|
359899
|
-
foundCommand = currentCommands.find(
|
|
359900
|
-
(cmd) => cmd.altNames?.includes(part)
|
|
359901
|
-
);
|
|
359902
|
-
}
|
|
359903
|
-
if (foundCommand) {
|
|
359904
|
-
commandToExecute = foundCommand;
|
|
359905
|
-
canonicalPath.push(foundCommand.name);
|
|
359906
|
-
pathIndex++;
|
|
359907
|
-
if (foundCommand.subCommands) {
|
|
359908
|
-
currentCommands = foundCommand.subCommands;
|
|
359909
|
-
} else {
|
|
359910
|
-
break;
|
|
359911
|
-
}
|
|
359912
|
-
} else {
|
|
359913
|
-
break;
|
|
359914
|
-
}
|
|
359915
|
-
}
|
|
359916
|
-
const args = parts.slice(pathIndex).join(" ");
|
|
359917
|
-
return { commandToExecute, args, canonicalPath };
|
|
359918
|
-
}, "parseSlashCommand");
|
|
359919
|
-
|
|
359920
|
-
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
359921
|
-
init_core5();
|
|
359922
|
-
|
|
359923
|
-
// packages/cli/src/services/FileCommandLoader.ts
|
|
359924
|
-
init_esbuild_shims();
|
|
359925
|
-
var import_toml = __toESM(require_toml(), 1);
|
|
359926
|
-
init_esm11();
|
|
359927
|
-
init_zod();
|
|
359928
|
-
init_core5();
|
|
359929
|
-
import { promises as fs90 } from "node:fs";
|
|
359930
|
-
import path98 from "node:path";
|
|
359931
|
-
|
|
359932
|
-
// packages/cli/src/services/prompt-processors/argumentProcessor.ts
|
|
359933
|
-
init_esbuild_shims();
|
|
359934
|
-
init_core5();
|
|
359935
|
-
var DefaultArgumentProcessor = class {
|
|
359936
|
-
static {
|
|
359937
|
-
__name(this, "DefaultArgumentProcessor");
|
|
359938
|
-
}
|
|
359939
|
-
async process(prompt, context2) {
|
|
359940
|
-
if (context2.invocation?.args) {
|
|
359941
|
-
return appendToLastTextPart(prompt, context2.invocation.raw);
|
|
359942
|
-
}
|
|
359943
|
-
return prompt;
|
|
359944
|
-
}
|
|
359945
|
-
};
|
|
359946
|
-
|
|
359947
|
-
// packages/cli/src/services/prompt-processors/types.ts
|
|
359948
|
-
init_esbuild_shims();
|
|
359949
|
-
var SHORTHAND_ARGS_PLACEHOLDER = "{{args}}";
|
|
359950
|
-
var SHELL_INJECTION_TRIGGER = "!{";
|
|
359951
|
-
var AT_FILE_INJECTION_TRIGGER = "@{";
|
|
359952
|
-
|
|
359953
|
-
// packages/cli/src/services/prompt-processors/shellProcessor.ts
|
|
359954
|
-
init_esbuild_shims();
|
|
359955
|
-
init_core5();
|
|
359956
|
-
|
|
359957
|
-
// packages/cli/src/services/prompt-processors/injectionParser.ts
|
|
359958
|
-
init_esbuild_shims();
|
|
359959
|
-
function extractInjections(prompt, trigger, contextName) {
|
|
359960
|
-
const injections = [];
|
|
359961
|
-
let index = 0;
|
|
359962
|
-
while (index < prompt.length) {
|
|
359963
|
-
const startIndex = prompt.indexOf(trigger, index);
|
|
359964
|
-
if (startIndex === -1) {
|
|
359965
|
-
break;
|
|
359966
|
-
}
|
|
359967
|
-
let currentIndex = startIndex + trigger.length;
|
|
359968
|
-
let braceCount = 1;
|
|
359969
|
-
let foundEnd = false;
|
|
359970
|
-
while (currentIndex < prompt.length) {
|
|
359971
|
-
const char = prompt[currentIndex];
|
|
359972
|
-
if (char === "{") {
|
|
359973
|
-
braceCount++;
|
|
359974
|
-
} else if (char === "}") {
|
|
359975
|
-
braceCount--;
|
|
359976
|
-
if (braceCount === 0) {
|
|
359977
|
-
const injectionContent = prompt.substring(
|
|
359978
|
-
startIndex + trigger.length,
|
|
359979
|
-
currentIndex
|
|
359980
|
-
);
|
|
359981
|
-
const endIndex = currentIndex + 1;
|
|
359982
|
-
injections.push({
|
|
359983
|
-
content: injectionContent.trim(),
|
|
359984
|
-
startIndex,
|
|
359985
|
-
endIndex
|
|
359986
|
-
});
|
|
359987
|
-
index = endIndex;
|
|
359988
|
-
foundEnd = true;
|
|
359989
|
-
break;
|
|
359990
|
-
}
|
|
359991
|
-
}
|
|
359992
|
-
currentIndex++;
|
|
359993
|
-
}
|
|
359994
|
-
if (!foundEnd) {
|
|
359995
|
-
const contextInfo = contextName ? ` in command '${contextName}'` : "";
|
|
359996
|
-
throw new Error(
|
|
359997
|
-
`Invalid syntax${contextInfo}: Unclosed injection starting at index ${startIndex} ('${trigger}'). Ensure braces are balanced. Paths or commands with unbalanced braces are not supported directly.`
|
|
359998
|
-
);
|
|
359999
|
-
}
|
|
360000
|
-
}
|
|
360001
|
-
return injections;
|
|
360002
|
-
}
|
|
360003
|
-
__name(extractInjections, "extractInjections");
|
|
360004
|
-
|
|
360005
|
-
// packages/cli/src/services/prompt-processors/shellProcessor.ts
|
|
360006
|
-
var ConfirmationRequiredError = class extends Error {
|
|
360007
|
-
constructor(message, commandsToConfirm) {
|
|
360008
|
-
super(message);
|
|
360009
|
-
this.commandsToConfirm = commandsToConfirm;
|
|
360010
|
-
this.name = "ConfirmationRequiredError";
|
|
360011
|
-
}
|
|
360012
|
-
static {
|
|
360013
|
-
__name(this, "ConfirmationRequiredError");
|
|
360014
|
-
}
|
|
360015
|
-
};
|
|
360016
|
-
var ShellProcessor = class {
|
|
360017
|
-
constructor(commandName) {
|
|
360018
|
-
this.commandName = commandName;
|
|
360019
|
-
}
|
|
360020
|
-
static {
|
|
360021
|
-
__name(this, "ShellProcessor");
|
|
360022
|
-
}
|
|
360023
|
-
async process(prompt, context2) {
|
|
360024
|
-
return flatMapTextParts(
|
|
360025
|
-
prompt,
|
|
360026
|
-
(text) => this.processString(text, context2)
|
|
360027
|
-
);
|
|
360028
|
-
}
|
|
360029
|
-
async processString(prompt, context2) {
|
|
360030
|
-
const userArgsRaw = context2.invocation?.args || "";
|
|
360031
|
-
if (!prompt.includes(SHELL_INJECTION_TRIGGER)) {
|
|
360032
|
-
return [
|
|
360033
|
-
{ text: prompt.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw) }
|
|
360034
|
-
];
|
|
360035
|
-
}
|
|
360036
|
-
const config2 = context2.services.config;
|
|
360037
|
-
if (!config2) {
|
|
360038
|
-
throw new Error(
|
|
360039
|
-
`Security configuration not loaded. Cannot verify shell command permissions for '${this.commandName}'. Aborting.`
|
|
360040
|
-
);
|
|
360041
|
-
}
|
|
360042
|
-
const { sessionShellAllowlist } = context2.session;
|
|
360043
|
-
const injections = extractInjections(
|
|
360044
|
-
prompt,
|
|
360045
|
-
SHELL_INJECTION_TRIGGER,
|
|
360046
|
-
this.commandName
|
|
360047
|
-
);
|
|
360048
|
-
if (injections.length === 0) {
|
|
360049
|
-
return [
|
|
360050
|
-
{ text: prompt.replaceAll(SHORTHAND_ARGS_PLACEHOLDER, userArgsRaw) }
|
|
360051
|
-
];
|
|
360052
|
-
}
|
|
360053
|
-
const { shell: shell2 } = getShellConfiguration();
|
|
360054
|
-
const userArgsEscaped = escapeShellArg(userArgsRaw, shell2);
|
|
360055
|
-
const resolvedInjections = injections.map(
|
|
360056
|
-
(injection) => {
|
|
360057
|
-
const command2 = injection.content;
|
|
360058
|
-
if (command2 === "") {
|
|
360059
|
-
return { ...injection, resolvedCommand: void 0 };
|
|
360060
|
-
}
|
|
360061
|
-
const resolvedCommand = command2.replaceAll(
|
|
360062
|
-
SHORTHAND_ARGS_PLACEHOLDER,
|
|
360063
|
-
userArgsEscaped
|
|
360064
|
-
);
|
|
360065
|
-
return { ...injection, resolvedCommand };
|
|
360066
|
-
}
|
|
360067
|
-
);
|
|
360068
|
-
const commandsToConfirm = /* @__PURE__ */ new Set();
|
|
360069
|
-
for (const injection of resolvedInjections) {
|
|
360070
|
-
const command2 = injection.resolvedCommand;
|
|
360071
|
-
if (!command2) continue;
|
|
360072
|
-
const { allAllowed, disallowedCommands, blockReason, isHardDenial } = checkCommandPermissions(command2, config2, sessionShellAllowlist);
|
|
360073
|
-
if (!allAllowed) {
|
|
360074
|
-
if (isHardDenial) {
|
|
360075
|
-
throw new Error(
|
|
360076
|
-
`${this.commandName} cannot be run. Blocked command: "${command2}". Reason: ${blockReason || "Blocked by configuration."}`
|
|
360077
|
-
);
|
|
360078
|
-
}
|
|
360079
|
-
if (config2.getApprovalMode() !== "yolo" /* YOLO */) {
|
|
360080
|
-
disallowedCommands.forEach((uc) => commandsToConfirm.add(uc));
|
|
360081
|
-
}
|
|
360082
|
-
}
|
|
360083
|
-
}
|
|
360084
|
-
if (commandsToConfirm.size > 0) {
|
|
360085
|
-
throw new ConfirmationRequiredError(
|
|
360086
|
-
"Shell command confirmation required",
|
|
360087
|
-
Array.from(commandsToConfirm)
|
|
360088
|
-
);
|
|
360089
|
-
}
|
|
360090
|
-
let processedPrompt = "";
|
|
360091
|
-
let lastIndex = 0;
|
|
360092
|
-
for (const injection of resolvedInjections) {
|
|
360093
|
-
const segment = prompt.substring(lastIndex, injection.startIndex);
|
|
360094
|
-
processedPrompt += segment.replaceAll(
|
|
360095
|
-
SHORTHAND_ARGS_PLACEHOLDER,
|
|
360096
|
-
userArgsRaw
|
|
360097
|
-
);
|
|
360098
|
-
if (injection.resolvedCommand) {
|
|
360099
|
-
const activeTheme = themeManager.getActiveTheme();
|
|
360100
|
-
const shellExecutionConfig = {
|
|
360101
|
-
...config2.getShellExecutionConfig(),
|
|
360102
|
-
defaultFg: activeTheme.colors.Foreground,
|
|
360103
|
-
defaultBg: activeTheme.colors.Background
|
|
360104
|
-
};
|
|
360105
|
-
const { result } = await ShellExecutionService.execute(
|
|
360106
|
-
injection.resolvedCommand,
|
|
360107
|
-
config2.getTargetDir(),
|
|
360108
|
-
() => {
|
|
360109
|
-
},
|
|
360110
|
-
new AbortController().signal,
|
|
360111
|
-
config2.getShouldUseNodePtyShell(),
|
|
360112
|
-
shellExecutionConfig
|
|
360113
|
-
);
|
|
360114
|
-
const executionResult = await result;
|
|
360115
|
-
if (executionResult.error && !executionResult.aborted) {
|
|
360116
|
-
throw new Error(
|
|
360117
|
-
`Failed to start shell command in '${this.commandName}': ${executionResult.error.message}. Command: ${injection.resolvedCommand}`
|
|
360118
|
-
);
|
|
360119
|
-
}
|
|
360120
|
-
processedPrompt += executionResult.output;
|
|
360121
|
-
if (executionResult.aborted) {
|
|
360122
|
-
processedPrompt += `
|
|
360123
|
-
[Shell command '${injection.resolvedCommand}' aborted]`;
|
|
360124
|
-
} else if (executionResult.exitCode !== 0 && executionResult.exitCode !== null) {
|
|
360125
|
-
processedPrompt += `
|
|
360126
|
-
[Shell command '${injection.resolvedCommand}' exited with code ${executionResult.exitCode}]`;
|
|
360127
|
-
} else if (executionResult.signal !== null) {
|
|
360128
|
-
processedPrompt += `
|
|
360129
|
-
[Shell command '${injection.resolvedCommand}' terminated by signal ${executionResult.signal}]`;
|
|
360130
|
-
}
|
|
360131
|
-
}
|
|
360132
|
-
lastIndex = injection.endIndex;
|
|
360133
|
-
}
|
|
360134
|
-
const finalSegment = prompt.substring(lastIndex);
|
|
360135
|
-
processedPrompt += finalSegment.replaceAll(
|
|
360136
|
-
SHORTHAND_ARGS_PLACEHOLDER,
|
|
360137
|
-
userArgsRaw
|
|
360138
|
-
);
|
|
360139
|
-
return [{ text: processedPrompt }];
|
|
360140
|
-
}
|
|
360141
|
-
};
|
|
360142
|
-
|
|
360143
|
-
// packages/cli/src/services/prompt-processors/atFileProcessor.ts
|
|
360144
|
-
init_esbuild_shims();
|
|
360145
|
-
init_core5();
|
|
360146
|
-
var AtFileProcessor = class {
|
|
360147
|
-
constructor(commandName) {
|
|
360148
|
-
this.commandName = commandName;
|
|
360149
|
-
}
|
|
360150
|
-
static {
|
|
360151
|
-
__name(this, "AtFileProcessor");
|
|
360152
|
-
}
|
|
360153
|
-
async process(input, context2) {
|
|
360154
|
-
const config2 = context2.services.config;
|
|
360155
|
-
if (!config2) {
|
|
360156
|
-
return input;
|
|
360157
|
-
}
|
|
360158
|
-
return flatMapTextParts(input, async (text) => {
|
|
360159
|
-
if (!text.includes(AT_FILE_INJECTION_TRIGGER)) {
|
|
360160
|
-
return [{ text }];
|
|
360161
|
-
}
|
|
360162
|
-
const injections = extractInjections(
|
|
360163
|
-
text,
|
|
360164
|
-
AT_FILE_INJECTION_TRIGGER,
|
|
360165
|
-
this.commandName
|
|
360166
|
-
);
|
|
360167
|
-
if (injections.length === 0) {
|
|
360168
|
-
return [{ text }];
|
|
360169
|
-
}
|
|
360170
|
-
const output = [];
|
|
360171
|
-
let lastIndex = 0;
|
|
360172
|
-
for (const injection of injections) {
|
|
360173
|
-
const prefix = text.substring(lastIndex, injection.startIndex);
|
|
360174
|
-
if (prefix) {
|
|
360175
|
-
output.push({ text: prefix });
|
|
360176
|
-
}
|
|
360177
|
-
const pathStr = injection.content;
|
|
360178
|
-
try {
|
|
360179
|
-
const fileContentParts = await readPathFromWorkspace(pathStr, config2);
|
|
360180
|
-
if (fileContentParts.length === 0) {
|
|
360181
|
-
const uiMessage = `File '@{${pathStr}}' was ignored by .gitignore or .rdmindignore and was not included in the prompt.`;
|
|
360182
|
-
context2.ui.addItem(
|
|
360183
|
-
{ type: "info" /* INFO */, text: uiMessage },
|
|
360184
|
-
Date.now()
|
|
360185
|
-
);
|
|
360186
|
-
}
|
|
360187
|
-
output.push(...fileContentParts);
|
|
360188
|
-
} catch (error2) {
|
|
360189
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
360190
|
-
const uiMessage = `Failed to inject content for '@{${pathStr}}': ${message}`;
|
|
360191
|
-
console.error(
|
|
360192
|
-
`[AtFileProcessor] ${uiMessage}. Leaving placeholder in prompt.`
|
|
360193
|
-
);
|
|
360194
|
-
context2.ui.addItem(
|
|
360195
|
-
{ type: "error" /* ERROR */, text: uiMessage },
|
|
360196
|
-
Date.now()
|
|
360197
|
-
);
|
|
360198
|
-
const placeholder = text.substring(
|
|
360199
|
-
injection.startIndex,
|
|
360200
|
-
injection.endIndex
|
|
360201
|
-
);
|
|
360202
|
-
output.push({ text: placeholder });
|
|
360203
|
-
}
|
|
360204
|
-
lastIndex = injection.endIndex;
|
|
360205
|
-
}
|
|
360206
|
-
const suffix = text.substring(lastIndex);
|
|
360207
|
-
if (suffix) {
|
|
360208
|
-
output.push({ text: suffix });
|
|
360209
|
-
}
|
|
360210
|
-
return output;
|
|
360211
|
-
});
|
|
360212
|
-
}
|
|
360213
|
-
};
|
|
360214
|
-
|
|
360215
|
-
// packages/cli/src/services/FileCommandLoader.ts
|
|
360216
|
-
var TomlCommandDefSchema = external_exports.object({
|
|
360217
|
-
prompt: external_exports.string({
|
|
360218
|
-
required_error: "The 'prompt' field is required.",
|
|
360219
|
-
invalid_type_error: "The 'prompt' field must be a string."
|
|
360220
|
-
}),
|
|
360221
|
-
description: external_exports.string().optional()
|
|
360222
|
-
});
|
|
360223
|
-
var FileCommandLoader = class {
|
|
360224
|
-
constructor(config2) {
|
|
360225
|
-
this.config = config2;
|
|
360226
|
-
this.folderTrustEnabled = !!config2?.getFolderTrustFeature();
|
|
360227
|
-
this.folderTrust = !!config2?.getFolderTrust();
|
|
360228
|
-
this.projectRoot = config2?.getProjectRoot() || process.cwd();
|
|
360229
|
-
}
|
|
360230
|
-
static {
|
|
360231
|
-
__name(this, "FileCommandLoader");
|
|
360232
|
-
}
|
|
360233
|
-
projectRoot;
|
|
360234
|
-
folderTrustEnabled;
|
|
360235
|
-
folderTrust;
|
|
360236
|
-
/**
|
|
360237
|
-
* Loads all commands from user, project, and extension directories.
|
|
360238
|
-
* Returns commands in order: user → project → extensions (alphabetically).
|
|
360239
|
-
*
|
|
360240
|
-
* Order is important for conflict resolution in CommandService:
|
|
360241
|
-
* - User/project commands (without extensionName) use "last wins" strategy
|
|
360242
|
-
* - Extension commands (with extensionName) get renamed if conflicts exist
|
|
360243
|
-
*
|
|
360244
|
-
* @param signal An AbortSignal to cancel the loading process.
|
|
360245
|
-
* @returns A promise that resolves to an array of all loaded SlashCommands.
|
|
360246
|
-
*/
|
|
360247
|
-
async loadCommands(signal) {
|
|
360248
|
-
const allCommands = [];
|
|
360249
|
-
const globOptions = {
|
|
360250
|
-
nodir: true,
|
|
360251
|
-
dot: true,
|
|
360252
|
-
signal,
|
|
360253
|
-
follow: true
|
|
360254
|
-
};
|
|
360255
|
-
const commandDirs = this.getCommandDirectories();
|
|
360256
|
-
for (const dirInfo of commandDirs) {
|
|
360257
|
-
try {
|
|
360258
|
-
const files = await glob("**/*.toml", {
|
|
360259
|
-
...globOptions,
|
|
360260
|
-
cwd: dirInfo.path
|
|
360261
|
-
});
|
|
360262
|
-
if (this.folderTrustEnabled && !this.folderTrust) {
|
|
360263
|
-
return [];
|
|
360264
|
-
}
|
|
360265
|
-
const commandPromises = files.map(
|
|
360266
|
-
(file) => this.parseAndAdaptFile(
|
|
360267
|
-
path98.join(dirInfo.path, file),
|
|
360268
|
-
dirInfo.path,
|
|
360269
|
-
dirInfo.extensionName
|
|
360270
|
-
)
|
|
360271
|
-
);
|
|
360272
|
-
const commands = (await Promise.all(commandPromises)).filter(
|
|
360273
|
-
(cmd) => cmd !== null
|
|
360274
|
-
);
|
|
360275
|
-
allCommands.push(...commands);
|
|
360276
|
-
} catch (error2) {
|
|
360277
|
-
const isEnoent = error2.code === "ENOENT";
|
|
360278
|
-
const isAbortError2 = error2 instanceof Error && error2.name === "AbortError";
|
|
360279
|
-
if (!isEnoent && !isAbortError2) {
|
|
360280
|
-
console.error(
|
|
360281
|
-
`[FileCommandLoader] Error loading commands from ${dirInfo.path}:`,
|
|
360282
|
-
error2
|
|
360283
|
-
);
|
|
360284
|
-
}
|
|
360285
|
-
}
|
|
360286
|
-
}
|
|
360287
|
-
return allCommands;
|
|
360288
|
-
}
|
|
360289
|
-
/**
|
|
360290
|
-
* Get all command directories in order for loading.
|
|
360291
|
-
* User commands → Project commands → Extension commands
|
|
360292
|
-
* This order ensures extension commands can detect all conflicts.
|
|
360293
|
-
*/
|
|
360294
|
-
getCommandDirectories() {
|
|
360295
|
-
const dirs = [];
|
|
360296
|
-
const storage = this.config?.storage ?? new Storage(this.projectRoot);
|
|
360297
|
-
dirs.push({ path: Storage.getUserCommandsDir() });
|
|
360298
|
-
dirs.push({ path: storage.getProjectCommandsDir() });
|
|
360299
|
-
if (this.config) {
|
|
360300
|
-
const activeExtensions = this.config.getExtensions().filter((ext2) => ext2.isActive).sort((a2, b2) => a2.name.localeCompare(b2.name));
|
|
360301
|
-
const extensionCommandDirs = activeExtensions.map((ext2) => ({
|
|
360302
|
-
path: path98.join(ext2.path, "commands"),
|
|
360303
|
-
extensionName: ext2.name
|
|
360304
|
-
}));
|
|
360305
|
-
dirs.push(...extensionCommandDirs);
|
|
360306
|
-
}
|
|
360307
|
-
return dirs;
|
|
360308
|
-
}
|
|
360309
|
-
/**
|
|
360310
|
-
* Parses a single .toml file and transforms it into a SlashCommand object.
|
|
360311
|
-
* @param filePath The absolute path to the .toml file.
|
|
360312
|
-
* @param baseDir The root command directory for name calculation.
|
|
360313
|
-
* @param extensionName Optional extension name to prefix commands with.
|
|
360314
|
-
* @returns A promise resolving to a SlashCommand, or null if the file is invalid.
|
|
360315
|
-
*/
|
|
360316
|
-
async parseAndAdaptFile(filePath, baseDir, extensionName) {
|
|
360317
|
-
let fileContent;
|
|
360318
|
-
try {
|
|
360319
|
-
fileContent = await fs90.readFile(filePath, "utf-8");
|
|
360320
|
-
} catch (error2) {
|
|
360321
|
-
console.error(
|
|
360322
|
-
`[FileCommandLoader] Failed to read file ${filePath}:`,
|
|
360323
|
-
error2 instanceof Error ? error2.message : String(error2)
|
|
360324
|
-
);
|
|
360325
|
-
return null;
|
|
360326
|
-
}
|
|
360327
|
-
let parsed;
|
|
360328
|
-
try {
|
|
360329
|
-
parsed = import_toml.default.parse(fileContent);
|
|
360330
|
-
} catch (error2) {
|
|
360331
|
-
console.error(
|
|
360332
|
-
`[FileCommandLoader] Failed to parse TOML file ${filePath}:`,
|
|
360333
|
-
error2 instanceof Error ? error2.message : String(error2)
|
|
360334
|
-
);
|
|
360335
|
-
return null;
|
|
360336
|
-
}
|
|
360337
|
-
const validationResult = TomlCommandDefSchema.safeParse(parsed);
|
|
360338
|
-
if (!validationResult.success) {
|
|
360339
|
-
console.error(
|
|
360340
|
-
`[FileCommandLoader] Skipping invalid command file: ${filePath}. Validation errors:`,
|
|
360341
|
-
validationResult.error.flatten()
|
|
360342
|
-
);
|
|
360343
|
-
return null;
|
|
360344
|
-
}
|
|
360345
|
-
const validDef = validationResult.data;
|
|
360346
|
-
const relativePathWithExt = path98.relative(baseDir, filePath);
|
|
360347
|
-
const relativePath = relativePathWithExt.substring(
|
|
360348
|
-
0,
|
|
360349
|
-
relativePathWithExt.length - 5
|
|
360350
|
-
// length of '.toml'
|
|
360351
|
-
);
|
|
360352
|
-
const baseCommandName = relativePath.split(path98.sep).map((segment) => segment.replaceAll(":", "_")).join(":");
|
|
360353
|
-
const defaultDescription = `Custom command from ${path98.basename(filePath)}`;
|
|
360354
|
-
let description = validDef.description || defaultDescription;
|
|
360355
|
-
if (extensionName) {
|
|
360356
|
-
description = `[${extensionName}] ${description}`;
|
|
360357
|
-
}
|
|
360358
|
-
const processors = [];
|
|
360359
|
-
const usesArgs = validDef.prompt.includes(SHORTHAND_ARGS_PLACEHOLDER);
|
|
360360
|
-
const usesShellInjection = validDef.prompt.includes(
|
|
360361
|
-
SHELL_INJECTION_TRIGGER
|
|
360362
|
-
);
|
|
360363
|
-
const usesAtFileInjection = validDef.prompt.includes(
|
|
360364
|
-
AT_FILE_INJECTION_TRIGGER
|
|
360365
|
-
);
|
|
360366
|
-
if (usesAtFileInjection) {
|
|
360367
|
-
processors.push(new AtFileProcessor(baseCommandName));
|
|
360368
|
-
}
|
|
360369
|
-
if (usesShellInjection || usesArgs) {
|
|
360370
|
-
processors.push(new ShellProcessor(baseCommandName));
|
|
360371
|
-
}
|
|
360372
|
-
if (!usesArgs) {
|
|
360373
|
-
processors.push(new DefaultArgumentProcessor());
|
|
360374
|
-
}
|
|
360375
|
-
return {
|
|
360376
|
-
name: baseCommandName,
|
|
360377
|
-
description,
|
|
360378
|
-
kind: "file" /* FILE */,
|
|
360379
|
-
extensionName,
|
|
360380
|
-
action: /* @__PURE__ */ __name(async (context2, _args) => {
|
|
360381
|
-
if (!context2.invocation) {
|
|
360382
|
-
console.error(
|
|
360383
|
-
`[FileCommandLoader] Critical error: Command '${baseCommandName}' was executed without invocation context.`
|
|
360384
|
-
);
|
|
360385
|
-
return {
|
|
360386
|
-
type: "submit_prompt",
|
|
360387
|
-
content: [{ text: validDef.prompt }]
|
|
360388
|
-
// Fallback to unprocessed prompt
|
|
360389
|
-
};
|
|
360390
|
-
}
|
|
360391
|
-
try {
|
|
360392
|
-
let processedContent = [
|
|
360393
|
-
{ text: validDef.prompt }
|
|
360394
|
-
];
|
|
360395
|
-
for (const processor of processors) {
|
|
360396
|
-
processedContent = await processor.process(
|
|
360397
|
-
processedContent,
|
|
360398
|
-
context2
|
|
360399
|
-
);
|
|
360400
|
-
}
|
|
360401
|
-
return {
|
|
360402
|
-
type: "submit_prompt",
|
|
360403
|
-
content: processedContent
|
|
360404
|
-
};
|
|
360405
|
-
} catch (e4) {
|
|
360406
|
-
if (e4 instanceof ConfirmationRequiredError) {
|
|
360407
|
-
return {
|
|
360408
|
-
type: "confirm_shell_commands",
|
|
360409
|
-
commandsToConfirm: e4.commandsToConfirm,
|
|
360410
|
-
originalInvocation: {
|
|
360411
|
-
raw: context2.invocation.raw
|
|
360412
|
-
}
|
|
360413
|
-
};
|
|
360414
|
-
}
|
|
360415
|
-
throw e4;
|
|
360416
|
-
}
|
|
360417
|
-
}, "action")
|
|
360418
|
-
};
|
|
360419
|
-
}
|
|
360420
|
-
};
|
|
360421
|
-
|
|
360422
|
-
// packages/cli/src/services/MarkdownCommandLoader.ts
|
|
360423
|
-
init_esbuild_shims();
|
|
360424
|
-
init_esm11();
|
|
360425
|
-
init_zod();
|
|
360426
|
-
import { promises as fs91 } from "node:fs";
|
|
360427
|
-
import path99 from "node:path";
|
|
360428
|
-
var MarkdownCommandDefSchema = external_exports.object({
|
|
360429
|
-
name: external_exports.string(),
|
|
360430
|
-
id: external_exports.string().optional(),
|
|
360431
|
-
category: external_exports.string().optional(),
|
|
360432
|
-
description: external_exports.string()
|
|
360433
|
-
});
|
|
360434
|
-
var MarkdownCommandLoader = class {
|
|
360435
|
-
static {
|
|
360436
|
-
__name(this, "MarkdownCommandLoader");
|
|
360437
|
-
}
|
|
360438
|
-
projectRoot;
|
|
360439
|
-
folderTrustEnabled;
|
|
360440
|
-
folderTrust;
|
|
360441
|
-
constructor(config2) {
|
|
360442
|
-
this.folderTrustEnabled = !!config2?.getFolderTrustFeature();
|
|
360443
|
-
this.folderTrust = !!config2?.getFolderTrust();
|
|
360444
|
-
this.projectRoot = config2?.getProjectRoot() || process.cwd();
|
|
360445
|
-
}
|
|
360446
|
-
/**
|
|
360447
|
-
* Loads all markdown commands from OpenSpec directories.
|
|
360448
|
-
*/
|
|
360449
|
-
async loadCommands(signal) {
|
|
360450
|
-
if (this.folderTrustEnabled && !this.folderTrust) {
|
|
360451
|
-
return [];
|
|
360452
|
-
}
|
|
360453
|
-
const allCommands = [];
|
|
360454
|
-
const globOptions = {
|
|
360455
|
-
nodir: true,
|
|
360456
|
-
dot: true,
|
|
360457
|
-
signal,
|
|
360458
|
-
follow: true
|
|
360459
|
-
};
|
|
360460
|
-
const commandDirs = this.getOpenSpecCommandDirectories();
|
|
360461
|
-
for (const dirPath of commandDirs) {
|
|
360462
|
-
try {
|
|
360463
|
-
const files = await glob("**/*.md", {
|
|
360464
|
-
...globOptions,
|
|
360465
|
-
cwd: dirPath
|
|
360466
|
-
});
|
|
360467
|
-
const commandPromises = files.map(
|
|
360468
|
-
(file) => this.parseAndAdaptFile(path99.join(dirPath, file))
|
|
360469
|
-
);
|
|
360470
|
-
const commands = (await Promise.all(commandPromises)).filter(
|
|
360471
|
-
(cmd) => cmd !== null
|
|
360472
|
-
);
|
|
360473
|
-
allCommands.push(...commands);
|
|
360474
|
-
} catch (error2) {
|
|
360475
|
-
const isEnoent = error2.code === "ENOENT";
|
|
360476
|
-
const isAbortError2 = error2 instanceof Error && error2.name === "AbortError";
|
|
360477
|
-
if (!isEnoent && !isAbortError2) {
|
|
360478
|
-
console.error(
|
|
360479
|
-
`[MarkdownCommandLoader] Error loading commands from ${dirPath}:`,
|
|
360480
|
-
error2
|
|
360481
|
-
);
|
|
360482
|
-
}
|
|
360483
|
-
}
|
|
360484
|
-
}
|
|
360485
|
-
return allCommands;
|
|
360486
|
-
}
|
|
360487
|
-
/**
|
|
360488
|
-
* Get directories containing OpenSpec markdown command files.
|
|
360489
|
-
*/
|
|
360490
|
-
getOpenSpecCommandDirectories() {
|
|
360491
|
-
const rdmindCommandsDir = path99.join(
|
|
360492
|
-
this.projectRoot,
|
|
360493
|
-
".rdmind",
|
|
360494
|
-
"commands"
|
|
360495
|
-
);
|
|
360496
|
-
return [rdmindCommandsDir];
|
|
360497
|
-
}
|
|
360498
|
-
/**
|
|
360499
|
-
* Parses a markdown file with YAML front matter and converts it to a SlashCommand.
|
|
360500
|
-
*/
|
|
360501
|
-
async parseAndAdaptFile(filePath) {
|
|
360502
|
-
let fileContent;
|
|
360503
|
-
try {
|
|
360504
|
-
fileContent = await fs91.readFile(filePath, "utf-8");
|
|
360505
|
-
} catch (error2) {
|
|
360506
|
-
console.error(
|
|
360507
|
-
`[MarkdownCommandLoader] Failed to read file ${filePath}:`,
|
|
360508
|
-
error2 instanceof Error ? error2.message : String(error2)
|
|
360509
|
-
);
|
|
360510
|
-
return null;
|
|
360511
|
-
}
|
|
360512
|
-
const frontMatterResult = this.parseFrontMatter(fileContent);
|
|
360513
|
-
if (!frontMatterResult) {
|
|
360514
|
-
return null;
|
|
360515
|
-
}
|
|
360516
|
-
const { frontMatter, content } = frontMatterResult;
|
|
360517
|
-
const validationResult = MarkdownCommandDefSchema.safeParse(frontMatter);
|
|
360518
|
-
if (!validationResult.success) {
|
|
360519
|
-
console.error(
|
|
360520
|
-
`[MarkdownCommandLoader] Invalid front matter in ${filePath}:`,
|
|
360521
|
-
validationResult.error.flatten()
|
|
360522
|
-
);
|
|
360523
|
-
return null;
|
|
360524
|
-
}
|
|
360525
|
-
const validDef = validationResult.data;
|
|
360526
|
-
const commandName = validDef.name.startsWith("/") ? validDef.name.substring(1) : validDef.name;
|
|
360527
|
-
let description = validDef.description;
|
|
360528
|
-
if (commandName === "openspec-proposal") {
|
|
360529
|
-
description = t4("Scaffold a new OpenSpec change and validate strictly.");
|
|
360530
|
-
} else if (commandName === "openspec-apply") {
|
|
360531
|
-
description = t4(
|
|
360532
|
-
"Implement an approved OpenSpec change and keep tasks in sync."
|
|
360533
|
-
);
|
|
360534
|
-
} else if (commandName === "openspec-archive") {
|
|
360535
|
-
description = t4("Archive a deployed OpenSpec change and update specs.");
|
|
360536
|
-
}
|
|
360537
|
-
return {
|
|
360538
|
-
name: commandName,
|
|
360539
|
-
description,
|
|
360540
|
-
kind: "file" /* FILE */,
|
|
360541
|
-
action: /* @__PURE__ */ __name(async (context2, args) => {
|
|
360542
|
-
const prompt = content.trim() + (args ? `
|
|
360543
|
-
|
|
360544
|
-
${args}` : "");
|
|
360545
|
-
return {
|
|
360546
|
-
type: "submit_prompt",
|
|
360547
|
-
content: [{ text: prompt }]
|
|
360548
|
-
};
|
|
360549
|
-
}, "action")
|
|
360550
|
-
};
|
|
360551
|
-
}
|
|
360552
|
-
/**
|
|
360553
|
-
* Parses YAML front matter from markdown content.
|
|
360554
|
-
*/
|
|
360555
|
-
parseFrontMatter(content) {
|
|
360556
|
-
const lines = content.split("\n");
|
|
360557
|
-
if (lines[0]?.trim() !== "---") {
|
|
360558
|
-
return null;
|
|
360559
|
-
}
|
|
360560
|
-
let endIndex = -1;
|
|
360561
|
-
for (let i3 = 1; i3 < lines.length; i3++) {
|
|
360562
|
-
if (lines[i3]?.trim() === "---") {
|
|
360563
|
-
endIndex = i3;
|
|
360564
|
-
break;
|
|
360565
|
-
}
|
|
360566
|
-
}
|
|
360567
|
-
if (endIndex === -1) {
|
|
360568
|
-
return null;
|
|
360569
|
-
}
|
|
360570
|
-
const frontMatterLines = lines.slice(1, endIndex);
|
|
360571
|
-
const contentLines = lines.slice(endIndex + 1);
|
|
360572
|
-
try {
|
|
360573
|
-
const frontMatter = {};
|
|
360574
|
-
for (const line of frontMatterLines) {
|
|
360575
|
-
const trimmed2 = line.trim();
|
|
360576
|
-
if (trimmed2 && !trimmed2.startsWith("#")) {
|
|
360577
|
-
const colonIndex = trimmed2.indexOf(":");
|
|
360578
|
-
if (colonIndex > 0) {
|
|
360579
|
-
const key = trimmed2.substring(0, colonIndex).trim();
|
|
360580
|
-
const value = trimmed2.substring(colonIndex + 1).trim();
|
|
360581
|
-
frontMatter[key] = value;
|
|
360582
|
-
}
|
|
360583
|
-
}
|
|
360584
|
-
}
|
|
360585
|
-
return {
|
|
360586
|
-
frontMatter,
|
|
360587
|
-
content: contentLines.join("\n")
|
|
360588
|
-
};
|
|
360589
|
-
} catch (error2) {
|
|
360590
|
-
console.error("Failed to parse front matter:", error2);
|
|
360591
|
-
return null;
|
|
360592
|
-
}
|
|
360593
|
-
}
|
|
360594
|
-
};
|
|
360595
|
-
|
|
360596
|
-
// packages/cli/src/ui/noninteractive/nonInteractiveUi.ts
|
|
360597
|
-
init_esbuild_shims();
|
|
360598
|
-
function createNonInteractiveUI() {
|
|
360599
|
-
return {
|
|
360600
|
-
addItem: /* @__PURE__ */ __name((_item, _timestamp) => 0, "addItem"),
|
|
360601
|
-
clear: /* @__PURE__ */ __name(() => {
|
|
360602
|
-
}, "clear"),
|
|
360603
|
-
setDebugMessage: /* @__PURE__ */ __name((_message) => {
|
|
360604
|
-
}, "setDebugMessage"),
|
|
360605
|
-
loadHistory: /* @__PURE__ */ __name((_newHistory) => {
|
|
360606
|
-
}, "loadHistory"),
|
|
360607
|
-
pendingItem: null,
|
|
360608
|
-
setPendingItem: /* @__PURE__ */ __name((_item) => {
|
|
360609
|
-
}, "setPendingItem"),
|
|
360610
|
-
toggleVimEnabled: /* @__PURE__ */ __name(async () => false, "toggleVimEnabled"),
|
|
360611
|
-
setGeminiMdFileCount: /* @__PURE__ */ __name((_count) => {
|
|
360612
|
-
}, "setGeminiMdFileCount"),
|
|
360613
|
-
reloadCommands: /* @__PURE__ */ __name(() => {
|
|
360614
|
-
}, "reloadCommands"),
|
|
360615
|
-
extensionsUpdateState: /* @__PURE__ */ new Map(),
|
|
360616
|
-
dispatchExtensionStateUpdate: /* @__PURE__ */ __name((_action) => {
|
|
360617
|
-
}, "dispatchExtensionStateUpdate"),
|
|
360618
|
-
addConfirmUpdateExtensionRequest: /* @__PURE__ */ __name((_request) => {
|
|
360619
|
-
}, "addConfirmUpdateExtensionRequest")
|
|
360620
|
-
};
|
|
360621
|
-
}
|
|
360622
|
-
__name(createNonInteractiveUI, "createNonInteractiveUI");
|
|
360623
|
-
|
|
360624
|
-
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
360625
|
-
function filterCommandsForNonInteractive(commands, allowedBuiltinCommandNames) {
|
|
360626
|
-
return commands.filter((cmd) => {
|
|
360627
|
-
if (cmd.kind === "file" /* FILE */) {
|
|
360628
|
-
return true;
|
|
360629
|
-
}
|
|
360630
|
-
if (cmd.kind === "markdown" /* MARKDOWN */) {
|
|
360631
|
-
return true;
|
|
360632
|
-
}
|
|
360633
|
-
if (cmd.kind === "built-in" /* BUILT_IN */) {
|
|
360634
|
-
return allowedBuiltinCommandNames.has(cmd.name);
|
|
360635
|
-
}
|
|
360636
|
-
return false;
|
|
360637
|
-
});
|
|
360638
|
-
}
|
|
360639
|
-
__name(filterCommandsForNonInteractive, "filterCommandsForNonInteractive");
|
|
360640
|
-
var handleSlashCommand = /* @__PURE__ */ __name(async (rawQuery, abortController, config2, settings, allowedBuiltinCommandNames) => {
|
|
360641
|
-
const trimmed2 = rawQuery.trim();
|
|
360642
|
-
if (!trimmed2.startsWith("/")) {
|
|
360643
|
-
return;
|
|
360644
|
-
}
|
|
360645
|
-
const allowedBuiltinSet = new Set(allowedBuiltinCommandNames ?? []);
|
|
360646
|
-
const loaders = [
|
|
360647
|
-
new FileCommandLoader(config2),
|
|
360648
|
-
new MarkdownCommandLoader(config2)
|
|
360649
|
-
];
|
|
360650
|
-
if (allowedBuiltinSet.size > 0) {
|
|
360651
|
-
loaders.push(new BuiltinCommandLoader(config2));
|
|
360652
|
-
}
|
|
360653
|
-
const commandService = await CommandService.create(
|
|
360654
|
-
loaders,
|
|
360655
|
-
abortController.signal
|
|
360656
|
-
);
|
|
360657
|
-
const commands = commandService.getCommands();
|
|
360658
|
-
const filteredCommands = filterCommandsForNonInteractive(
|
|
360659
|
-
commands,
|
|
360660
|
-
allowedBuiltinSet
|
|
360661
|
-
);
|
|
360662
|
-
const { commandToExecute, args } = parseSlashCommand(
|
|
360663
|
-
rawQuery,
|
|
360664
|
-
filteredCommands
|
|
360665
|
-
);
|
|
360666
|
-
if (commandToExecute) {
|
|
360667
|
-
if (commandToExecute.action) {
|
|
360668
|
-
const sessionStats = {
|
|
360669
|
-
sessionId: config2?.getSessionId(),
|
|
360670
|
-
sessionStartTime: /* @__PURE__ */ new Date(),
|
|
360671
|
-
metrics: uiTelemetryService.getMetrics(),
|
|
360672
|
-
lastPromptTokenCount: 0,
|
|
360673
|
-
promptCount: 1
|
|
360674
|
-
};
|
|
360675
|
-
const logger6 = new Logger(config2?.getSessionId() || "", config2?.storage);
|
|
360676
|
-
const context2 = {
|
|
360677
|
-
services: {
|
|
360678
|
-
config: config2,
|
|
360679
|
-
settings,
|
|
360680
|
-
git: void 0,
|
|
360681
|
-
logger: logger6
|
|
360682
|
-
},
|
|
360683
|
-
ui: createNonInteractiveUI(),
|
|
360684
|
-
session: {
|
|
360685
|
-
stats: sessionStats,
|
|
360686
|
-
sessionShellAllowlist: /* @__PURE__ */ new Set()
|
|
360687
|
-
},
|
|
360688
|
-
invocation: {
|
|
360689
|
-
raw: trimmed2,
|
|
360690
|
-
name: commandToExecute.name,
|
|
360691
|
-
args
|
|
360692
|
-
}
|
|
360693
|
-
};
|
|
360694
|
-
const result = await commandToExecute.action(context2, args);
|
|
360695
|
-
if (result) {
|
|
360696
|
-
switch (result.type) {
|
|
360697
|
-
case "submit_prompt":
|
|
360698
|
-
return result.content;
|
|
360699
|
-
case "message":
|
|
360700
|
-
if (result.messageType === "info") {
|
|
360701
|
-
console.log(result.content);
|
|
360702
|
-
} else {
|
|
360703
|
-
console.error(result.content);
|
|
360704
|
-
}
|
|
360705
|
-
return;
|
|
360706
|
-
case "confirm_shell_commands":
|
|
360707
|
-
throw new FatalInputError(
|
|
360708
|
-
"Exiting due to a confirmation prompt requested by the command."
|
|
360709
|
-
);
|
|
360710
|
-
default:
|
|
360711
|
-
throw new FatalInputError(
|
|
360712
|
-
"Exiting due to command result that is not supported in non-interactive mode."
|
|
360713
|
-
);
|
|
360714
|
-
}
|
|
360715
|
-
}
|
|
360716
|
-
}
|
|
360717
|
-
}
|
|
360718
|
-
return;
|
|
360719
|
-
}, "handleSlashCommand");
|
|
360720
|
-
var getAvailableCommands = /* @__PURE__ */ __name(async (config2, settings, abortSignal, allowedBuiltinCommandNames) => {
|
|
360721
|
-
try {
|
|
360722
|
-
const allowedBuiltinSet = new Set(allowedBuiltinCommandNames ?? []);
|
|
360723
|
-
const loaders = [
|
|
360724
|
-
new FileCommandLoader(config2),
|
|
360725
|
-
new MarkdownCommandLoader(config2)
|
|
360726
|
-
];
|
|
360727
|
-
if (allowedBuiltinSet.size > 0) {
|
|
360728
|
-
loaders.push(new BuiltinCommandLoader(config2));
|
|
360729
|
-
}
|
|
360730
|
-
const commandService = await CommandService.create(loaders, abortSignal);
|
|
360731
|
-
const commands = commandService.getCommands();
|
|
360732
|
-
const filteredCommands = filterCommandsForNonInteractive(
|
|
360733
|
-
commands,
|
|
360734
|
-
allowedBuiltinSet
|
|
360735
|
-
);
|
|
360736
|
-
return filteredCommands.filter((cmd) => !cmd.hidden);
|
|
360737
|
-
} catch (error2) {
|
|
360738
|
-
console.error("Error loading available commands:", error2);
|
|
360739
|
-
return [];
|
|
360740
|
-
}
|
|
360741
|
-
}, "getAvailableCommands");
|
|
360742
|
-
|
|
360743
360891
|
// packages/cli/src/ui/hooks/atCommandProcessor.ts
|
|
360744
360892
|
init_esbuild_shims();
|
|
360745
360893
|
init_core5();
|
|
@@ -361081,6 +361229,36 @@ __name(handleAtCommand, "handleAtCommand");
|
|
|
361081
361229
|
|
|
361082
361230
|
// packages/cli/src/nonInteractiveCli.ts
|
|
361083
361231
|
init_errors7();
|
|
361232
|
+
async function emitNonInteractiveFinalMessage(params) {
|
|
361233
|
+
const { message, isError, adapter, config: config2 } = params;
|
|
361234
|
+
if (!adapter) {
|
|
361235
|
+
const target = isError ? process.stderr : process.stdout;
|
|
361236
|
+
target.write(`${message}
|
|
361237
|
+
`);
|
|
361238
|
+
return;
|
|
361239
|
+
}
|
|
361240
|
+
adapter.startAssistantMessage();
|
|
361241
|
+
adapter.processEvent({
|
|
361242
|
+
type: "content" /* Content */,
|
|
361243
|
+
value: message
|
|
361244
|
+
});
|
|
361245
|
+
adapter.finalizeAssistantMessage();
|
|
361246
|
+
const metrics2 = uiTelemetryService.getMetrics();
|
|
361247
|
+
const usage2 = computeUsageFromMetrics(metrics2);
|
|
361248
|
+
const outputFormat = config2.getOutputFormat();
|
|
361249
|
+
const stats = outputFormat === "json" /* JSON */ ? uiTelemetryService.getMetrics() : void 0;
|
|
361250
|
+
adapter.emitResult({
|
|
361251
|
+
isError,
|
|
361252
|
+
durationMs: Date.now() - params.startTimeMs,
|
|
361253
|
+
apiDurationMs: 0,
|
|
361254
|
+
numTurns: 0,
|
|
361255
|
+
errorMessage: isError ? message : void 0,
|
|
361256
|
+
usage: usage2,
|
|
361257
|
+
stats,
|
|
361258
|
+
summary: message
|
|
361259
|
+
});
|
|
361260
|
+
}
|
|
361261
|
+
__name(emitNonInteractiveFinalMessage, "emitNonInteractiveFinalMessage");
|
|
361084
361262
|
async function runNonInteractive(config2, settings, input, prompt_id, options2 = {}) {
|
|
361085
361263
|
return promptIdContext.run(prompt_id, async () => {
|
|
361086
361264
|
let adapter;
|
|
@@ -361118,6 +361296,14 @@ async function runNonInteractive(config2, settings, input, prompt_id, options2 =
|
|
|
361118
361296
|
process.stdout.on("error", stdoutErrorHandler);
|
|
361119
361297
|
process.on("SIGINT", shutdownHandler);
|
|
361120
361298
|
process.on("SIGTERM", shutdownHandler);
|
|
361299
|
+
if (adapter) {
|
|
361300
|
+
const systemMessage = await buildSystemMessage(
|
|
361301
|
+
config2,
|
|
361302
|
+
sessionId,
|
|
361303
|
+
permissionMode
|
|
361304
|
+
);
|
|
361305
|
+
adapter.emitMessage(systemMessage);
|
|
361306
|
+
}
|
|
361121
361307
|
let initialPartList = extractPartsFromUserMessage(
|
|
361122
361308
|
options2.userMessage
|
|
361123
361309
|
);
|
|
@@ -361130,9 +361316,43 @@ async function runNonInteractive(config2, settings, input, prompt_id, options2 =
|
|
|
361130
361316
|
config2,
|
|
361131
361317
|
settings
|
|
361132
361318
|
);
|
|
361133
|
-
|
|
361134
|
-
|
|
361135
|
-
|
|
361319
|
+
switch (slashCommandResult.type) {
|
|
361320
|
+
case "submit_prompt":
|
|
361321
|
+
initialPartList = slashCommandResult.content;
|
|
361322
|
+
slashHandled = true;
|
|
361323
|
+
break;
|
|
361324
|
+
case "message": {
|
|
361325
|
+
await emitNonInteractiveFinalMessage({
|
|
361326
|
+
message: slashCommandResult.content,
|
|
361327
|
+
isError: slashCommandResult.messageType === "error",
|
|
361328
|
+
adapter,
|
|
361329
|
+
config: config2,
|
|
361330
|
+
startTimeMs: startTime
|
|
361331
|
+
});
|
|
361332
|
+
return;
|
|
361333
|
+
}
|
|
361334
|
+
case "stream_messages":
|
|
361335
|
+
throw new FatalInputError(
|
|
361336
|
+
"Stream messages mode is not supported in non-interactive CLI"
|
|
361337
|
+
);
|
|
361338
|
+
case "unsupported": {
|
|
361339
|
+
await emitNonInteractiveFinalMessage({
|
|
361340
|
+
message: slashCommandResult.reason,
|
|
361341
|
+
isError: true,
|
|
361342
|
+
adapter,
|
|
361343
|
+
config: config2,
|
|
361344
|
+
startTimeMs: startTime
|
|
361345
|
+
});
|
|
361346
|
+
return;
|
|
361347
|
+
}
|
|
361348
|
+
case "no_command":
|
|
361349
|
+
break;
|
|
361350
|
+
default: {
|
|
361351
|
+
const _exhaustive = slashCommandResult;
|
|
361352
|
+
throw new FatalInputError(
|
|
361353
|
+
`Unhandled slash command result type: ${_exhaustive.type}`
|
|
361354
|
+
);
|
|
361355
|
+
}
|
|
361136
361356
|
}
|
|
361137
361357
|
}
|
|
361138
361358
|
if (!slashHandled) {
|
|
@@ -361158,14 +361378,6 @@ async function runNonInteractive(config2, settings, input, prompt_id, options2 =
|
|
|
361158
361378
|
}
|
|
361159
361379
|
const initialParts = normalizePartList(initialPartList);
|
|
361160
361380
|
let currentMessages = [{ role: "user", parts: initialParts }];
|
|
361161
|
-
if (adapter) {
|
|
361162
|
-
const systemMessage = await buildSystemMessage(
|
|
361163
|
-
config2,
|
|
361164
|
-
sessionId,
|
|
361165
|
-
permissionMode
|
|
361166
|
-
);
|
|
361167
|
-
adapter.emitMessage(systemMessage);
|
|
361168
|
-
}
|
|
361169
361381
|
let isFirstTurn = true;
|
|
361170
361382
|
while (true) {
|
|
361171
361383
|
turnCount++;
|
|
@@ -361846,7 +362058,7 @@ var SystemController = class extends BaseController {
|
|
|
361846
362058
|
};
|
|
361847
362059
|
}
|
|
361848
362060
|
/**
|
|
361849
|
-
* Load slash command names using
|
|
362061
|
+
* Load slash command names using getAvailableCommands
|
|
361850
362062
|
*
|
|
361851
362063
|
* @param signal - AbortSignal to respect for cancellation
|
|
361852
362064
|
* @returns Promise resolving to array of slash command names
|
|
@@ -361856,19 +362068,11 @@ var SystemController = class extends BaseController {
|
|
|
361856
362068
|
return [];
|
|
361857
362069
|
}
|
|
361858
362070
|
try {
|
|
361859
|
-
const
|
|
361860
|
-
[new BuiltinCommandLoader(this.context.config)],
|
|
361861
|
-
signal
|
|
361862
|
-
);
|
|
362071
|
+
const commands = await getAvailableCommands(this.context.config, signal);
|
|
361863
362072
|
if (signal.aborted) {
|
|
361864
362073
|
return [];
|
|
361865
362074
|
}
|
|
361866
|
-
|
|
361867
|
-
const commands = service.getCommands();
|
|
361868
|
-
for (const command2 of commands) {
|
|
361869
|
-
names.add(command2.name);
|
|
361870
|
-
}
|
|
361871
|
-
return Array.from(names).sort();
|
|
362075
|
+
return commands.map((cmd) => cmd.name).sort();
|
|
361872
362076
|
} catch (error2) {
|
|
361873
362077
|
if (signal.aborted) {
|
|
361874
362078
|
return [];
|
|
@@ -390188,13 +390392,6 @@ var import_react82 = __toESM(require_react(), 1);
|
|
|
390188
390392
|
// packages/cli/src/config/xhsSsoProviders.ts
|
|
390189
390393
|
init_esbuild_shims();
|
|
390190
390394
|
var XHS_SSO_MODELS = [
|
|
390191
|
-
{
|
|
390192
|
-
id: "kimi-k2-turbo-preview",
|
|
390193
|
-
displayName: "kimi-k2-turbo-preview",
|
|
390194
|
-
baseUrl: "https://runway.devops.xiaohongshu.com/openai/moonshot/v1",
|
|
390195
|
-
contextWindow: "256K",
|
|
390196
|
-
description: "kimi k2 \u7684\u9AD8\u901F\u7248\u672C"
|
|
390197
|
-
},
|
|
390198
390395
|
{
|
|
390199
390396
|
id: "qwen3-coder-plus",
|
|
390200
390397
|
displayName: "qwen3-coder-plus",
|
|
@@ -390236,6 +390433,13 @@ var XHS_SSO_MODELS = [
|
|
|
390236
390433
|
baseUrl: "https://runway.devops.rednote.life/openai/google/v1",
|
|
390237
390434
|
contextWindow: "1M",
|
|
390238
390435
|
description: "Google \u9AD8\u901F\u667A\u80FD\u6A21\u578B(\u601D\u8003\u65F6\u95F4\u957F)"
|
|
390436
|
+
},
|
|
390437
|
+
{
|
|
390438
|
+
id: "glm-4.7",
|
|
390439
|
+
displayName: "glm-4.7",
|
|
390440
|
+
baseUrl: "https://runway.devops.xiaohongshu.com/openai/zhipu/paas/v4/",
|
|
390441
|
+
contextWindow: "200K",
|
|
390442
|
+
description: "\u667A\u8C31\u6700\u65B0\u65D7\u8230\u6A21\u578B\uFF0C\u9762\u5411 Agentic Coding \u573A\u666F\u5F3A\u5316"
|
|
390239
390443
|
}
|
|
390240
390444
|
];
|
|
390241
390445
|
|
|
@@ -396127,6 +396331,11 @@ var useSlashCommandProcessor = /* @__PURE__ */ __name((config2, settings, addIte
|
|
|
396127
396331
|
true
|
|
396128
396332
|
);
|
|
396129
396333
|
}
|
|
396334
|
+
case "stream_messages": {
|
|
396335
|
+
throw new Error(
|
|
396336
|
+
"stream_messages result type is not supported in interactive mode"
|
|
396337
|
+
);
|
|
396338
|
+
}
|
|
396130
396339
|
default: {
|
|
396131
396340
|
const unhandled = result;
|
|
396132
396341
|
throw new Error(
|
|
@@ -398821,10 +399030,13 @@ var WITTY_LOADING_PHRASES = [
|
|
|
398821
399030
|
];
|
|
398822
399031
|
var PHRASE_CHANGE_INTERVAL_MS = 15e3;
|
|
398823
399032
|
var usePhraseCycler = /* @__PURE__ */ __name((isActive, isWaiting, customPhrases) => {
|
|
398824
|
-
const loadingPhrases = (0, import_react120.useMemo)(
|
|
398825
|
-
(
|
|
398826
|
-
|
|
398827
|
-
|
|
399033
|
+
const loadingPhrases = (0, import_react120.useMemo)(() => {
|
|
399034
|
+
if (customPhrases && customPhrases.length > 0) {
|
|
399035
|
+
return customPhrases;
|
|
399036
|
+
}
|
|
399037
|
+
const translatedPhrases = ta("WITTY_LOADING_PHRASES");
|
|
399038
|
+
return translatedPhrases.length > 0 ? translatedPhrases : WITTY_LOADING_PHRASES;
|
|
399039
|
+
}, [customPhrases]);
|
|
398828
399040
|
const [currentLoadingPhrase, setCurrentLoadingPhrase] = (0, import_react120.useState)(
|
|
398829
399041
|
loadingPhrases[0]
|
|
398830
399042
|
);
|
|
@@ -401969,7 +402181,9 @@ ${installationInfo.updateMessage}`;
|
|
|
401969
402181
|
updateProcess.on("close", (code2) => {
|
|
401970
402182
|
if (code2 === 0) {
|
|
401971
402183
|
updateEventEmitter.emit("update-success", {
|
|
401972
|
-
message: t4(
|
|
402184
|
+
message: t4(
|
|
402185
|
+
"Update successful! The new version will be used on your next run."
|
|
402186
|
+
)
|
|
401973
402187
|
});
|
|
401974
402188
|
} else {
|
|
401975
402189
|
updateEventEmitter.emit("update-failed", {
|
|
@@ -402019,7 +402233,9 @@ function setUpdateHandler(addItem, setUpdateInfo) {
|
|
|
402019
402233
|
addItem(
|
|
402020
402234
|
{
|
|
402021
402235
|
type: "info" /* INFO */,
|
|
402022
|
-
text: t4(
|
|
402236
|
+
text: t4(
|
|
402237
|
+
"Update successful! The new version will be used on your next run."
|
|
402238
|
+
)
|
|
402023
402239
|
},
|
|
402024
402240
|
Date.now()
|
|
402025
402241
|
);
|
|
@@ -405611,7 +405827,11 @@ async function showResumeSessionPicker(cwd7 = process.cwd()) {
|
|
|
405611
405827
|
const sessionService = new SessionService(cwd7);
|
|
405612
405828
|
const hasSession = await sessionService.loadLastSession();
|
|
405613
405829
|
if (!hasSession) {
|
|
405614
|
-
console.log(
|
|
405830
|
+
console.log(
|
|
405831
|
+
t4("No sessions found. Start a new session with {{cmd}}.", {
|
|
405832
|
+
cmd: "rdmind"
|
|
405833
|
+
})
|
|
405834
|
+
);
|
|
405615
405835
|
return void 0;
|
|
405616
405836
|
}
|
|
405617
405837
|
clearScreen2();
|
|
@@ -405766,8 +405986,22 @@ var authenticateUpdateSchema = external_exports.object({
|
|
|
405766
405986
|
authUri: external_exports.string()
|
|
405767
405987
|
})
|
|
405768
405988
|
});
|
|
405989
|
+
var acpMetaSchema = external_exports.record(external_exports.unknown()).nullable().optional();
|
|
405990
|
+
var modelIdSchema = external_exports.string();
|
|
405991
|
+
var modelInfoSchema = external_exports.object({
|
|
405992
|
+
_meta: acpMetaSchema,
|
|
405993
|
+
description: external_exports.string().nullable().optional(),
|
|
405994
|
+
modelId: modelIdSchema,
|
|
405995
|
+
name: external_exports.string()
|
|
405996
|
+
});
|
|
405997
|
+
var sessionModelStateSchema = external_exports.object({
|
|
405998
|
+
_meta: acpMetaSchema,
|
|
405999
|
+
availableModels: external_exports.array(modelInfoSchema),
|
|
406000
|
+
currentModelId: modelIdSchema
|
|
406001
|
+
});
|
|
405769
406002
|
var newSessionResponseSchema = external_exports.object({
|
|
405770
|
-
sessionId: external_exports.string()
|
|
406003
|
+
sessionId: external_exports.string(),
|
|
406004
|
+
models: sessionModelStateSchema
|
|
405771
406005
|
});
|
|
405772
406006
|
var loadSessionResponseSchema = external_exports.null();
|
|
405773
406007
|
var sessionListItemSchema = external_exports.object({
|
|
@@ -405981,6 +406215,10 @@ var currentModeUpdateSchema = external_exports.object({
|
|
|
405981
406215
|
sessionUpdate: external_exports.literal("current_mode_update"),
|
|
405982
406216
|
modeId: approvalModeValueSchema
|
|
405983
406217
|
});
|
|
406218
|
+
var currentModelUpdateSchema = external_exports.object({
|
|
406219
|
+
sessionUpdate: external_exports.literal("current_model_update"),
|
|
406220
|
+
model: modelInfoSchema
|
|
406221
|
+
});
|
|
405984
406222
|
var sessionUpdateSchema = external_exports.union([
|
|
405985
406223
|
external_exports.object({
|
|
405986
406224
|
content: contentBlockSchema,
|
|
@@ -406022,6 +406260,7 @@ var sessionUpdateSchema = external_exports.union([
|
|
|
406022
406260
|
sessionUpdate: external_exports.literal("plan")
|
|
406023
406261
|
}),
|
|
406024
406262
|
currentModeUpdateSchema,
|
|
406263
|
+
currentModelUpdateSchema,
|
|
406025
406264
|
availableCommandsUpdateSchema
|
|
406026
406265
|
]);
|
|
406027
406266
|
var agentResponseSchema = external_exports.union([
|
|
@@ -406135,6 +406374,13 @@ var AgentSideConnection = class {
|
|
|
406135
406374
|
params
|
|
406136
406375
|
);
|
|
406137
406376
|
}
|
|
406377
|
+
/**
|
|
406378
|
+
* Sends a custom notification to the client.
|
|
406379
|
+
* Used for extension-specific notifications that are not part of the core ACP protocol.
|
|
406380
|
+
*/
|
|
406381
|
+
async sendCustomNotification(method, params) {
|
|
406382
|
+
return await this.#connection.sendNotification(method, params);
|
|
406383
|
+
}
|
|
406138
406384
|
/**
|
|
406139
406385
|
* Request permission before running a tool
|
|
406140
406386
|
*
|
|
@@ -407131,7 +407377,6 @@ var SubAgentTracker = class {
|
|
|
407131
407377
|
};
|
|
407132
407378
|
|
|
407133
407379
|
// packages/cli/src/acp-integration/session/Session.ts
|
|
407134
|
-
var ALLOWED_BUILTIN_COMMANDS_FOR_ACP = ["init"];
|
|
407135
407380
|
var Session3 = class {
|
|
407136
407381
|
constructor(id, chat, config2, client, settings) {
|
|
407137
407382
|
this.chat = chat;
|
|
@@ -407202,13 +407447,14 @@ var Session3 = class {
|
|
|
407202
407447
|
inputText,
|
|
407203
407448
|
pendingSend,
|
|
407204
407449
|
this.config,
|
|
407205
|
-
this.settings
|
|
407206
|
-
ALLOWED_BUILTIN_COMMANDS_FOR_ACP
|
|
407450
|
+
this.settings
|
|
407207
407451
|
);
|
|
407208
|
-
|
|
407209
|
-
|
|
407210
|
-
|
|
407211
|
-
|
|
407452
|
+
parts = await this.#processSlashCommandResult(
|
|
407453
|
+
slashCommandResult,
|
|
407454
|
+
params.prompt
|
|
407455
|
+
);
|
|
407456
|
+
if (parts === null) {
|
|
407457
|
+
return { stopReason: "end_turn" };
|
|
407212
407458
|
}
|
|
407213
407459
|
} else {
|
|
407214
407460
|
parts = await this.#resolvePrompt(params.prompt, pendingSend.signal);
|
|
@@ -407298,9 +407544,7 @@ var Session3 = class {
|
|
|
407298
407544
|
try {
|
|
407299
407545
|
const slashCommands = await getAvailableCommands(
|
|
407300
407546
|
this.config,
|
|
407301
|
-
|
|
407302
|
-
abortController.signal,
|
|
407303
|
-
ALLOWED_BUILTIN_COMMANDS_FOR_ACP
|
|
407547
|
+
abortController.signal
|
|
407304
407548
|
);
|
|
407305
407549
|
const availableCommands = slashCommands.map(
|
|
407306
407550
|
(cmd) => ({
|
|
@@ -407547,6 +407791,71 @@ var Session3 = class {
|
|
|
407547
407791
|
return errorResponse(error2);
|
|
407548
407792
|
}
|
|
407549
407793
|
}
|
|
407794
|
+
/**
|
|
407795
|
+
* Processes the result of a slash command execution.
|
|
407796
|
+
*
|
|
407797
|
+
* Supported result types in ACP mode:
|
|
407798
|
+
* - submit_prompt: Submits content to the model
|
|
407799
|
+
* - stream_messages: Streams multiple messages to the client (ACP-specific)
|
|
407800
|
+
* - unsupported: Command cannot be executed in ACP mode
|
|
407801
|
+
* - no_command: No command was found, use original prompt
|
|
407802
|
+
*
|
|
407803
|
+
* Note: 'message' type is not supported in ACP mode - commands should use
|
|
407804
|
+
* 'stream_messages' instead for consistent async handling.
|
|
407805
|
+
*
|
|
407806
|
+
* @param result The result from handleSlashCommand
|
|
407807
|
+
* @param originalPrompt The original prompt blocks
|
|
407808
|
+
* @returns Parts to use for the prompt, or null if command was handled without needing model interaction
|
|
407809
|
+
*/
|
|
407810
|
+
async #processSlashCommandResult(result, originalPrompt) {
|
|
407811
|
+
switch (result.type) {
|
|
407812
|
+
case "submit_prompt":
|
|
407813
|
+
return normalizePartList(result.content);
|
|
407814
|
+
case "message": {
|
|
407815
|
+
await this.client.sendCustomNotification("_qwencode/slash_command", {
|
|
407816
|
+
sessionId: this.sessionId,
|
|
407817
|
+
command: originalPrompt.filter((block2) => block2.type === "text").map((block2) => block2.type === "text" ? block2.text : "").join(" "),
|
|
407818
|
+
messageType: result.messageType,
|
|
407819
|
+
message: result.content || ""
|
|
407820
|
+
});
|
|
407821
|
+
if (result.messageType === "error") {
|
|
407822
|
+
throw new Error(result.content || "Slash command failed.");
|
|
407823
|
+
}
|
|
407824
|
+
return null;
|
|
407825
|
+
}
|
|
407826
|
+
case "stream_messages": {
|
|
407827
|
+
const command2 = originalPrompt.filter((block2) => block2.type === "text").map((block2) => block2.type === "text" ? block2.text : "").join(" ");
|
|
407828
|
+
for await (const msg of result.messages) {
|
|
407829
|
+
await this.client.sendCustomNotification("_qwencode/slash_command", {
|
|
407830
|
+
sessionId: this.sessionId,
|
|
407831
|
+
command: command2,
|
|
407832
|
+
messageType: msg.messageType,
|
|
407833
|
+
message: msg.content
|
|
407834
|
+
});
|
|
407835
|
+
if (msg.messageType === "error") {
|
|
407836
|
+
throw new Error(msg.content || "Slash command failed.");
|
|
407837
|
+
}
|
|
407838
|
+
}
|
|
407839
|
+
return null;
|
|
407840
|
+
}
|
|
407841
|
+
case "unsupported": {
|
|
407842
|
+
const unsupportedError = `Slash command not supported in ACP integration: ${result.reason}`;
|
|
407843
|
+
throw new Error(unsupportedError);
|
|
407844
|
+
}
|
|
407845
|
+
case "no_command":
|
|
407846
|
+
return originalPrompt.map((block2) => {
|
|
407847
|
+
if (block2.type === "text") {
|
|
407848
|
+
return { text: block2.text };
|
|
407849
|
+
}
|
|
407850
|
+
throw new Error(`Unsupported block type: ${block2.type}`);
|
|
407851
|
+
});
|
|
407852
|
+
default: {
|
|
407853
|
+
const _exhaustive = result;
|
|
407854
|
+
const unknownError = `Unknown slash command result type: ${_exhaustive.type}`;
|
|
407855
|
+
throw new Error(unknownError);
|
|
407856
|
+
}
|
|
407857
|
+
}
|
|
407858
|
+
}
|
|
407550
407859
|
async #resolvePrompt(message, abortSignal) {
|
|
407551
407860
|
const FILE_URI_SCHEME = "file://";
|
|
407552
407861
|
const embeddedContext = [];
|
|
@@ -407891,7 +408200,7 @@ var GeminiAgent = class {
|
|
|
407891
408200
|
name: APPROVAL_MODE_INFO[mode].name,
|
|
407892
408201
|
description: APPROVAL_MODE_INFO[mode].description
|
|
407893
408202
|
}));
|
|
407894
|
-
const version2 = "0.1.8
|
|
408203
|
+
const version2 = "0.1.8";
|
|
407895
408204
|
return {
|
|
407896
408205
|
protocolVersion: PROTOCOL_VERSION,
|
|
407897
408206
|
agentInfo: {
|
|
@@ -407947,8 +408256,25 @@ var GeminiAgent = class {
|
|
|
407947
408256
|
await this.ensureAuthenticated(config2);
|
|
407948
408257
|
this.setupFileSystem(config2);
|
|
407949
408258
|
const session = await this.createAndStoreSession(config2);
|
|
408259
|
+
const configuredModel = (config2.getModel() || this.config.getModel() || "").trim();
|
|
408260
|
+
const modelId = configuredModel || "default";
|
|
408261
|
+
const modelName = configuredModel || modelId;
|
|
407950
408262
|
return {
|
|
407951
|
-
sessionId: session.getId()
|
|
408263
|
+
sessionId: session.getId(),
|
|
408264
|
+
models: {
|
|
408265
|
+
currentModelId: modelId,
|
|
408266
|
+
availableModels: [
|
|
408267
|
+
{
|
|
408268
|
+
modelId,
|
|
408269
|
+
name: modelName,
|
|
408270
|
+
description: null,
|
|
408271
|
+
_meta: {
|
|
408272
|
+
contextLimit: tokenLimit(modelId)
|
|
408273
|
+
}
|
|
408274
|
+
}
|
|
408275
|
+
],
|
|
408276
|
+
_meta: null
|
|
408277
|
+
}
|
|
407952
408278
|
};
|
|
407953
408279
|
}
|
|
407954
408280
|
async newSessionConfig(cwd7, mcpServers, sessionId) {
|
|
@@ -408074,8 +408400,10 @@ var GeminiAgent = class {
|
|
|
408074
408400
|
async createAndStoreSession(config2, conversation) {
|
|
408075
408401
|
const sessionId = config2.getSessionId();
|
|
408076
408402
|
const geminiClient = config2.getGeminiClient();
|
|
408077
|
-
|
|
408078
|
-
|
|
408403
|
+
if (!geminiClient.isInitialized()) {
|
|
408404
|
+
await geminiClient.initialize();
|
|
408405
|
+
}
|
|
408406
|
+
const chat = geminiClient.getChat();
|
|
408079
408407
|
const session = new Session3(
|
|
408080
408408
|
sessionId,
|
|
408081
408409
|
chat,
|
|
@@ -408511,6 +408839,11 @@ main().catch((error2) => {
|
|
|
408511
408839
|
* Copyright 2025 RDMind
|
|
408512
408840
|
* SPDX-License-Identifier: Apache-2.0
|
|
408513
408841
|
*/
|
|
408842
|
+
/**
|
|
408843
|
+
* @license
|
|
408844
|
+
* Copyright 2025 Qwen team
|
|
408845
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
408846
|
+
*/
|
|
408514
408847
|
/*! Bundled license information:
|
|
408515
408848
|
|
|
408516
408849
|
undici/lib/web/fetch/body.js:
|