wp-studio 1.7.9 → 1.7.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{_events-ByiJRMQ1.mjs → _events-BcapW3eh.mjs} +5 -5
- package/dist/cli/{certificate-manager-Bp1E0km4.mjs → certificate-manager-SVYcCL_i.mjs} +6 -1
- package/dist/cli/{delete-D1lAYFtg.mjs → delete-D1924O3o.mjs} +8 -4
- package/dist/cli/{helpers-Bh-WikQr.mjs → helpers-oQuItT8n.mjs} +4 -153
- package/dist/cli/{index-CyYXE85k.mjs → index-4lan3TI_.mjs} +24 -4
- package/dist/cli/{index-DBCpWm8k.mjs → index-BjzOJKPi.mjs} +525 -256
- package/dist/cli/{index-BiCiEz-r.mjs → index-DRQnCQvM.mjs} +510 -365
- package/dist/cli/{list-COLca0rr.mjs → list-DOFyyV1f.mjs} +4 -3
- package/dist/cli/{login-OvZJPTV5.mjs → login-BtPZeZ4G.mjs} +3 -3
- package/dist/cli/{logout-BaG-QFSN.mjs → logout-Cr631QzG.mjs} +3 -3
- package/dist/cli/main.mjs +2 -2
- package/dist/cli/paths-CqXGLB7R.mjs +195 -0
- package/dist/cli/plugin/.claude-plugin/plugin.json +5 -0
- package/dist/cli/plugin/skills/need-for-speed/SKILL.md +55 -0
- package/dist/cli/plugin/skills/site-spec/SKILL.md +35 -0
- package/dist/cli/plugin/skills/taxonomist/SKILL.md +270 -0
- package/dist/cli/plugin/skills/taxonomist/scripts/apply-changes.php +223 -0
- package/dist/cli/plugin/skills/taxonomist/scripts/backup.php +112 -0
- package/dist/cli/plugin/skills/taxonomist/scripts/export-posts.php +119 -0
- package/dist/cli/plugin/skills/taxonomist/scripts/restore.php +233 -0
- package/dist/cli/process-manager-daemon.mjs +11 -4
- package/dist/cli/{process-manager-ipc-heiF195f.mjs → process-manager-ipc-BisO0qtU.mjs} +1 -1
- package/dist/cli/proxy-daemon.mjs +1 -1
- package/dist/cli/prune-pm-logs-COryxqeo.mjs +41 -0
- package/dist/cli/resume-BwDwdJtq.mjs +113 -0
- package/dist/cli/{rewrite-wp-cli-post-content-DH3hRTU5.mjs → rewrite-wp-cli-post-content-2zlfFnKT.mjs} +1 -1
- package/dist/cli/{set-DY9OcXFg.mjs → set-D5eeqHbp.mjs} +3 -3
- package/dist/cli/{set-BX9MWFxi.mjs → set-DYnzUz_G.mjs} +4 -4
- package/dist/cli/{status-CgY39wpU.mjs → status-DNvMZBqD.mjs} +2 -2
- package/dist/cli/{well-known-paths-CG_o9mSO.mjs → well-known-paths-BYA1Bw5o.mjs} +1 -1
- package/dist/cli/wordpress-server-child.mjs +2 -2
- package/dist/cli/{wp-DeUSBbLc.mjs → wp-DD2-QiiP.mjs} +2 -2
- package/dist/cli/wp-files/latest/available-site-translations.json +1 -1
- package/dist/cli/wp-files/skills/STUDIO.md +1 -1
- package/dist/cli/wp-files/skills/studio-cli/SKILL.md +1 -1
- package/package.json +9 -10
- package/patches/@mariozechner+pi-tui+0.54.0.patch +12 -0
- package/scripts/postinstall-npm.mjs +1 -0
- package/dist/cli/paths-BPK_RySX.mjs +0 -31
- package/dist/cli/resume-DshNzC7q.mjs +0 -62
|
@@ -1,19 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as getAiSessionsDirectoryForDate, c as buildAiSessionFileName, l as listAiSessions, g as getAiSessionsRootDirectory } from "./paths-CqXGLB7R.mjs";
|
|
2
|
+
import { S as STUDIO_SITES_ROOT, c as createRemoteSiteTools, a as createStudioTools, r as readAuthToken, b as getSnapshotsFromConfig, i as isSnapshotExpired, d as captureCommandOutput, e as runCommand$3, f as runCommand$4, h as chalk, j as getSitesRunningStatus, k as getWpComSites, l as isSiteRunning, o as openBrowser, m as getSiteUrl, n as closeSharedBrowser } from "./index-DRQnCQvM.mjs";
|
|
2
3
|
import { __, sprintf, _n } from "@wordpress/i18n";
|
|
3
4
|
import fs__default from "fs";
|
|
4
5
|
import path__default from "path";
|
|
5
6
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
6
7
|
import os from "os";
|
|
8
|
+
import { l as lockCliConfig, r as readCliConfig, s as saveCliConfig, u as unlockCliConfig, g as updateCliConfigWithPartial } from "./certificate-manager-SVYcCL_i.mjs";
|
|
7
9
|
import { password } from "@inquirer/prompts";
|
|
8
|
-
import {
|
|
9
|
-
import { L as LoggerError, d as Logger, s as setProgressCallback } from "./well-known-paths-CG_o9mSO.mjs";
|
|
10
|
+
import { L as LoggerError, d as Logger, s as setProgressCallback } from "./well-known-paths-BYA1Bw5o.mjs";
|
|
10
11
|
import crypto from "crypto";
|
|
11
12
|
import fs from "fs/promises";
|
|
12
|
-
import {
|
|
13
|
-
import { runCommand as runCommand$
|
|
14
|
-
import { runCommand as runCommand$2 } from "./logout-BaG-QFSN.mjs";
|
|
13
|
+
import { runCommand as runCommand$1 } from "./login-BtPZeZ4G.mjs";
|
|
14
|
+
import { runCommand as runCommand$2 } from "./logout-Cr631QzG.mjs";
|
|
15
15
|
import { ProcessTerminal, TUI, Container, Loader, CombinedAutocompleteProvider, isKeyRelease, matchesKey, Text, SelectList, Input, Markdown, Editor, visibleWidth, CURSOR_MARKER, truncateToWidth } from "@mariozechner/pi-tui";
|
|
16
|
-
|
|
16
|
+
const AI_MODELS = {
|
|
17
|
+
"claude-sonnet-4-6": "Sonnet 4.6",
|
|
18
|
+
"claude-opus-4-6": "Opus 4.6",
|
|
19
|
+
"claude-opus-4-7": "Opus 4.7"
|
|
20
|
+
};
|
|
21
|
+
const DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
22
|
+
function isAiModelId(value) {
|
|
23
|
+
return Object.prototype.hasOwnProperty.call(AI_MODELS, value);
|
|
24
|
+
}
|
|
25
|
+
async function readApprovedPermissions() {
|
|
26
|
+
const config = await readCliConfig();
|
|
27
|
+
return config.approvedPermissions ?? [];
|
|
28
|
+
}
|
|
29
|
+
async function addApprovedPermission(entry) {
|
|
30
|
+
try {
|
|
31
|
+
await lockCliConfig();
|
|
32
|
+
const config = await readCliConfig();
|
|
33
|
+
const existing = config.approvedPermissions ?? [];
|
|
34
|
+
const alreadyPresent = existing.some(
|
|
35
|
+
(item) => item.toolName === entry.toolName && item.approvalPath === entry.approvalPath
|
|
36
|
+
);
|
|
37
|
+
if (alreadyPresent) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
config.approvedPermissions = [...existing, entry];
|
|
41
|
+
await saveCliConfig(config);
|
|
42
|
+
} finally {
|
|
43
|
+
await unlockCliConfig();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
17
46
|
const ALLOWED_TOOLS = [
|
|
18
47
|
"mcp__studio__*",
|
|
19
48
|
"Read",
|
|
@@ -25,21 +54,10 @@ const ALLOWED_TOOLS = [
|
|
|
25
54
|
"NotebookRead",
|
|
26
55
|
"AskUserQuestion"
|
|
27
56
|
];
|
|
28
|
-
const ALLOWED_TOOLS_REMOTE = [
|
|
29
|
-
"mcp__studio__*",
|
|
30
|
-
"Read",
|
|
31
|
-
"Glob",
|
|
32
|
-
"Grep",
|
|
33
|
-
"WebFetch",
|
|
34
|
-
"WebSearch",
|
|
35
|
-
"TodoRead",
|
|
36
|
-
"NotebookRead",
|
|
37
|
-
"AskUserQuestion"
|
|
38
|
-
];
|
|
39
57
|
const PATH_GATED_TOOLS = ["Write", "Edit", "Bash", "NotebookEdit"];
|
|
40
58
|
const PATH_INPUT_KEYS = ["path", "file_path", "filePath"];
|
|
41
59
|
const APPROVE_ONCE_LABEL = "Allow once";
|
|
42
|
-
const
|
|
60
|
+
const APPROVE_ALWAYS_LABEL = "Allow always";
|
|
43
61
|
const DENY_LABEL = "Deny";
|
|
44
62
|
const STUDIO_ROOT = path__default.resolve(STUDIO_SITES_ROOT);
|
|
45
63
|
const TMP_ROOT = path__default.resolve(os.tmpdir());
|
|
@@ -111,6 +129,19 @@ function createPathApprovalSession() {
|
|
|
111
129
|
}
|
|
112
130
|
};
|
|
113
131
|
}
|
|
132
|
+
const defaultApprovalSession = createPathApprovalSession();
|
|
133
|
+
let primePromise = null;
|
|
134
|
+
function primeDefaultApprovalSession() {
|
|
135
|
+
if (!primePromise) {
|
|
136
|
+
primePromise = (async () => {
|
|
137
|
+
const entries = await readApprovedPermissions();
|
|
138
|
+
for (const { toolName, approvalPath } of entries) {
|
|
139
|
+
defaultApprovalSession.rememberApprovedPath(toolName, approvalPath);
|
|
140
|
+
}
|
|
141
|
+
})();
|
|
142
|
+
}
|
|
143
|
+
return primePromise;
|
|
144
|
+
}
|
|
114
145
|
function getPathGatedPermissionRequest({
|
|
115
146
|
toolName,
|
|
116
147
|
input,
|
|
@@ -147,8 +178,8 @@ async function askForPathGatedToolApproval({
|
|
|
147
178
|
description: `Run ${toolName} outside trusted directories for this step.`
|
|
148
179
|
},
|
|
149
180
|
{
|
|
150
|
-
label:
|
|
151
|
-
description: `
|
|
181
|
+
label: APPROVE_ALWAYS_LABEL,
|
|
182
|
+
description: `Remember this choice and stop asking for ${toolName} on this path.`
|
|
152
183
|
},
|
|
153
184
|
{
|
|
154
185
|
label: DENY_LABEL,
|
|
@@ -160,8 +191,8 @@ async function askForPathGatedToolApproval({
|
|
|
160
191
|
if (answers[question] === APPROVE_ONCE_LABEL) {
|
|
161
192
|
return "allow_once";
|
|
162
193
|
}
|
|
163
|
-
if (answers[question] ===
|
|
164
|
-
return "
|
|
194
|
+
if (answers[question] === APPROVE_ALWAYS_LABEL) {
|
|
195
|
+
return "allow_always";
|
|
165
196
|
}
|
|
166
197
|
return "deny";
|
|
167
198
|
}
|
|
@@ -170,8 +201,11 @@ async function promptForApproval({
|
|
|
170
201
|
input,
|
|
171
202
|
metadata,
|
|
172
203
|
onAskUser,
|
|
173
|
-
pathApprovalSession
|
|
204
|
+
pathApprovalSession = defaultApprovalSession
|
|
174
205
|
}) {
|
|
206
|
+
if (pathApprovalSession === defaultApprovalSession) {
|
|
207
|
+
await primeDefaultApprovalSession();
|
|
208
|
+
}
|
|
175
209
|
const permissionRequest = getPathGatedPermissionRequest({
|
|
176
210
|
toolName,
|
|
177
211
|
input,
|
|
@@ -179,7 +213,7 @@ async function promptForApproval({
|
|
|
179
213
|
suggestions: metadata?.suggestions
|
|
180
214
|
});
|
|
181
215
|
if (permissionRequest) {
|
|
182
|
-
if (!
|
|
216
|
+
if (!pathApprovalSession.hasApprovedPath(toolName, permissionRequest.approvalPath)) {
|
|
183
217
|
const approvalDecision = await askForPathGatedToolApproval({
|
|
184
218
|
toolName,
|
|
185
219
|
outsidePath: permissionRequest.approvalPath,
|
|
@@ -191,8 +225,12 @@ async function promptForApproval({
|
|
|
191
225
|
message: ACCESS_DENIED_MESSAGE
|
|
192
226
|
};
|
|
193
227
|
}
|
|
194
|
-
if (approvalDecision === "
|
|
195
|
-
|
|
228
|
+
if (approvalDecision === "allow_always") {
|
|
229
|
+
pathApprovalSession.rememberApprovedPath(toolName, permissionRequest.approvalPath);
|
|
230
|
+
await addApprovedPermission({
|
|
231
|
+
toolName,
|
|
232
|
+
approvalPath: permissionRequest.approvalPath
|
|
233
|
+
});
|
|
196
234
|
}
|
|
197
235
|
}
|
|
198
236
|
return {
|
|
@@ -411,14 +449,12 @@ Interpret creatively and make unexpected choices that feel genuinely designed fo
|
|
|
411
449
|
**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
|
|
412
450
|
|
|
413
451
|
Remember: You are capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.`;
|
|
414
|
-
const
|
|
415
|
-
"
|
|
416
|
-
"
|
|
417
|
-
|
|
418
|
-
const DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
419
|
-
const pathApprovalSession = createPathApprovalSession();
|
|
452
|
+
const SDK_INTERRUPT_CLEANUP_ERRORS = [
|
|
453
|
+
"Query closed",
|
|
454
|
+
"ProcessTransport is not ready for writing"
|
|
455
|
+
];
|
|
420
456
|
process.on("unhandledRejection", (reason) => {
|
|
421
|
-
if (reason instanceof Error && reason.message.includes(
|
|
457
|
+
if (reason instanceof Error && SDK_INTERRUPT_CLEANUP_ERRORS.some((msg) => reason.message.includes(msg))) {
|
|
422
458
|
return;
|
|
423
459
|
}
|
|
424
460
|
throw reason;
|
|
@@ -440,7 +476,7 @@ function startAiAgent(config) {
|
|
|
440
476
|
const mcpServers = {
|
|
441
477
|
studio: isRemoteSite ? createRemoteSiteTools(wpcomAccessToken, activeSite.wpcomSiteId) : createStudioTools()
|
|
442
478
|
};
|
|
443
|
-
const allowedTools =
|
|
479
|
+
const allowedTools = [...ALLOWED_TOOLS];
|
|
444
480
|
const systemPromptOptions = isRemoteSite ? {
|
|
445
481
|
remoteSite: {
|
|
446
482
|
name: activeSite.name,
|
|
@@ -485,13 +521,7 @@ function startAiAgent(config) {
|
|
|
485
521
|
updatedInput: { ...input, answers }
|
|
486
522
|
};
|
|
487
523
|
}
|
|
488
|
-
return promptForApproval({
|
|
489
|
-
toolName,
|
|
490
|
-
input,
|
|
491
|
-
metadata,
|
|
492
|
-
onAskUser,
|
|
493
|
-
pathApprovalSession
|
|
494
|
-
});
|
|
524
|
+
return promptForApproval({ toolName, input, metadata, onAskUser });
|
|
495
525
|
},
|
|
496
526
|
plugins: [{ type: "local", path: path__default.resolve(import.meta.dirname, "plugin") }],
|
|
497
527
|
model,
|
|
@@ -536,6 +566,12 @@ async function hasValidWpcomAuth() {
|
|
|
536
566
|
const token = await readAuthToken();
|
|
537
567
|
return token !== null;
|
|
538
568
|
}
|
|
569
|
+
function readInlineWpcomToken() {
|
|
570
|
+
return process.env.STUDIO_WPCOM_TOKEN?.trim() || null;
|
|
571
|
+
}
|
|
572
|
+
function hasInlineWpcomAuth() {
|
|
573
|
+
return readInlineWpcomToken() !== null;
|
|
574
|
+
}
|
|
539
575
|
function createBaseEnvironment() {
|
|
540
576
|
const env = { ...process.env };
|
|
541
577
|
delete env.ANTHROPIC_API_KEY;
|
|
@@ -543,6 +579,9 @@ function createBaseEnvironment() {
|
|
|
543
579
|
delete env.ANTHROPIC_BASE_URL;
|
|
544
580
|
delete env.ANTHROPIC_CUSTOM_HEADERS;
|
|
545
581
|
delete env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS;
|
|
582
|
+
if (!env.CLAUDE_CODE_MAX_RETRIES) {
|
|
583
|
+
env.CLAUDE_CODE_MAX_RETRIES = "1";
|
|
584
|
+
}
|
|
546
585
|
return env;
|
|
547
586
|
}
|
|
548
587
|
const AI_PROVIDER_DEFINITIONS = {
|
|
@@ -550,21 +589,22 @@ const AI_PROVIDER_DEFINITIONS = {
|
|
|
550
589
|
id: "wpcom",
|
|
551
590
|
autoFallbackWhenUnavailable: true,
|
|
552
591
|
isVisible: async () => true,
|
|
553
|
-
isReady: hasValidWpcomAuth,
|
|
592
|
+
isReady: async () => hasInlineWpcomAuth() || await hasValidWpcomAuth(),
|
|
554
593
|
prepare: async () => {
|
|
555
|
-
if (await hasValidWpcomAuth()) {
|
|
594
|
+
if (hasInlineWpcomAuth() || await hasValidWpcomAuth()) {
|
|
556
595
|
return;
|
|
557
596
|
}
|
|
558
597
|
throw new LoggerError(__("WordPress.com login required. Use /login to authenticate."));
|
|
559
598
|
},
|
|
560
599
|
resolveEnv: async () => {
|
|
561
|
-
const
|
|
562
|
-
|
|
600
|
+
const inlineToken = readInlineWpcomToken();
|
|
601
|
+
const accessToken = inlineToken ?? (await readAuthToken())?.accessToken;
|
|
602
|
+
if (!accessToken) {
|
|
563
603
|
throw new LoggerError(__("WordPress.com login required. Use /login to authenticate."));
|
|
564
604
|
}
|
|
565
605
|
const env = createBaseEnvironment();
|
|
566
606
|
env.ANTHROPIC_BASE_URL = getWpcomAiGatewayBaseUrl();
|
|
567
|
-
env.ANTHROPIC_AUTH_TOKEN =
|
|
607
|
+
env.ANTHROPIC_AUTH_TOKEN = accessToken;
|
|
568
608
|
env.ANTHROPIC_CUSTOM_HEADERS = buildAnthropicCustomHeaders({
|
|
569
609
|
"X-WPCOM-AI-Feature": WPCOM_AI_FEATURE_HEADER
|
|
570
610
|
});
|
|
@@ -633,6 +673,9 @@ async function resolveUnavailableAiProvider(provider) {
|
|
|
633
673
|
return getPreferredReadyProvider(provider);
|
|
634
674
|
}
|
|
635
675
|
async function resolveInitialAiProvider() {
|
|
676
|
+
if (hasInlineWpcomAuth()) {
|
|
677
|
+
return "wpcom";
|
|
678
|
+
}
|
|
636
679
|
const { aiProvider: savedProvider } = await readCliConfig();
|
|
637
680
|
if (savedProvider) {
|
|
638
681
|
const definition = getAiProviderDefinition(savedProvider);
|
|
@@ -659,6 +702,10 @@ async function resolveAiEnvironment(provider) {
|
|
|
659
702
|
return getAiProviderDefinition(provider).resolveEnv();
|
|
660
703
|
}
|
|
661
704
|
function emitEvent(event) {
|
|
705
|
+
if (typeof process.send === "function") {
|
|
706
|
+
process.send(event);
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
662
709
|
process.stdout.write(JSON.stringify(event) + "\n");
|
|
663
710
|
}
|
|
664
711
|
class JsonAdapter {
|
|
@@ -669,10 +716,25 @@ class JsonAdapter {
|
|
|
669
716
|
this.onSiteSelected = null;
|
|
670
717
|
this.onInterrupt = null;
|
|
671
718
|
this.onBeforeExit = null;
|
|
719
|
+
this.permissionResponse = null;
|
|
720
|
+
this.ipcMessageListener = null;
|
|
672
721
|
}
|
|
673
722
|
start() {
|
|
723
|
+
if (typeof process.send !== "function") {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
this.ipcMessageListener = (message) => {
|
|
727
|
+
if (message && typeof message === "object" && message.type === "interrupt") {
|
|
728
|
+
this.onInterrupt?.();
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
process.on("message", this.ipcMessageListener);
|
|
674
732
|
}
|
|
675
733
|
stop() {
|
|
734
|
+
if (this.ipcMessageListener) {
|
|
735
|
+
process.off("message", this.ipcMessageListener);
|
|
736
|
+
this.ipcMessageListener = null;
|
|
737
|
+
}
|
|
676
738
|
}
|
|
677
739
|
showWelcome() {
|
|
678
740
|
}
|
|
@@ -696,7 +758,7 @@ class JsonAdapter {
|
|
|
696
758
|
setStatusMessage() {
|
|
697
759
|
}
|
|
698
760
|
setLoaderMessage(message, _update) {
|
|
699
|
-
|
|
761
|
+
this.showProgress(message);
|
|
700
762
|
}
|
|
701
763
|
beginAgentTurn() {
|
|
702
764
|
emitEvent({ type: "turn.started", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
@@ -720,7 +782,7 @@ class JsonAdapter {
|
|
|
720
782
|
return {
|
|
721
783
|
type: "result",
|
|
722
784
|
sessionId: message.session_id,
|
|
723
|
-
success: message.
|
|
785
|
+
success: !message.is_error
|
|
724
786
|
};
|
|
725
787
|
}
|
|
726
788
|
return void 0;
|
|
@@ -738,6 +800,11 @@ class JsonAdapter {
|
|
|
738
800
|
throw new Error("waitForInput is not available in JSON mode");
|
|
739
801
|
}
|
|
740
802
|
async askUser(questions) {
|
|
803
|
+
if (this.permissionResponse) {
|
|
804
|
+
const response = this.permissionResponse;
|
|
805
|
+
this.permissionResponse = null;
|
|
806
|
+
return response;
|
|
807
|
+
}
|
|
741
808
|
emitEvent({
|
|
742
809
|
type: "question.asked",
|
|
743
810
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -746,6 +813,18 @@ class JsonAdapter {
|
|
|
746
813
|
options: q.options
|
|
747
814
|
}))
|
|
748
815
|
});
|
|
816
|
+
if (typeof process.send === "function") {
|
|
817
|
+
return new Promise((resolve) => {
|
|
818
|
+
const onMessage = (message) => {
|
|
819
|
+
if (message && typeof message === "object" && message.type === "answer") {
|
|
820
|
+
const answers = message.answers;
|
|
821
|
+
process.off("message", onMessage);
|
|
822
|
+
resolve(answers ?? {});
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
process.on("message", onMessage);
|
|
826
|
+
});
|
|
827
|
+
}
|
|
749
828
|
this.emitTurnCompleted("paused");
|
|
750
829
|
await this.onBeforeExit?.();
|
|
751
830
|
process.exitCode = 0;
|
|
@@ -759,9 +838,6 @@ class JsonAdapter {
|
|
|
759
838
|
function isAiProviderId(value) {
|
|
760
839
|
return Object.prototype.hasOwnProperty.call(AI_PROVIDERS, value);
|
|
761
840
|
}
|
|
762
|
-
function isAiModelId(value) {
|
|
763
|
-
return Object.prototype.hasOwnProperty.call(AI_MODELS, value);
|
|
764
|
-
}
|
|
765
841
|
function resolveResumeSessionContext(resumeSession) {
|
|
766
842
|
if (!resumeSession) {
|
|
767
843
|
return {};
|
|
@@ -779,6 +855,11 @@ function resolveResumeSessionContext(resumeSession) {
|
|
|
779
855
|
context.sessionId = sessionId;
|
|
780
856
|
}
|
|
781
857
|
}
|
|
858
|
+
if (!context.model && event.type === "session.model_selected") {
|
|
859
|
+
if (isAiModelId(event.model)) {
|
|
860
|
+
context.model = event.model;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
782
863
|
if (event.type === "session.context") {
|
|
783
864
|
if (!context.provider && isAiProviderId(event.provider)) {
|
|
784
865
|
context.provider = event.provider;
|
|
@@ -857,6 +938,15 @@ class AiSessionRecorder {
|
|
|
857
938
|
wpcomSiteId: site.wpcomSiteId
|
|
858
939
|
});
|
|
859
940
|
}
|
|
941
|
+
async recordEnvironmentSelected(payload) {
|
|
942
|
+
await this.appendEvent({
|
|
943
|
+
type: "environment.selected",
|
|
944
|
+
timestamp: toIsoTimestamp(),
|
|
945
|
+
environment: payload.environment,
|
|
946
|
+
url: payload.url,
|
|
947
|
+
wpcomSiteId: payload.wpcomSiteId
|
|
948
|
+
});
|
|
949
|
+
}
|
|
860
950
|
async recordUserMessage(options) {
|
|
861
951
|
await this.appendEvent({
|
|
862
952
|
type: "user.message",
|
|
@@ -911,17 +1001,21 @@ class AiSessionRecorder {
|
|
|
911
1001
|
});
|
|
912
1002
|
}
|
|
913
1003
|
}
|
|
914
|
-
function
|
|
915
|
-
ui.prepareForReplay();
|
|
916
|
-
let isTurnOpen = false;
|
|
917
|
-
let lastClearedIndex = -1;
|
|
1004
|
+
function filterEventsAfterLastClear(events) {
|
|
918
1005
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
919
1006
|
if (events[i].type === "session.cleared") {
|
|
920
|
-
|
|
921
|
-
break;
|
|
1007
|
+
return events.slice(i + 1);
|
|
922
1008
|
}
|
|
923
1009
|
}
|
|
924
|
-
|
|
1010
|
+
return events;
|
|
1011
|
+
}
|
|
1012
|
+
function isVisibleUserMessage(event) {
|
|
1013
|
+
return event.source === "prompt";
|
|
1014
|
+
}
|
|
1015
|
+
function replaySessionHistory(ui, events) {
|
|
1016
|
+
ui.prepareForReplay();
|
|
1017
|
+
let isTurnOpen = false;
|
|
1018
|
+
const eventsToReplay = filterEventsAfterLastClear(events);
|
|
925
1019
|
try {
|
|
926
1020
|
for (const event of eventsToReplay) {
|
|
927
1021
|
ui.setReplayTimestamp(event.timestamp);
|
|
@@ -932,14 +1026,34 @@ function replaySessionHistory(ui, events) {
|
|
|
932
1026
|
path: event.sitePath,
|
|
933
1027
|
running: false,
|
|
934
1028
|
remote: event.remote === true,
|
|
935
|
-
url: typeof event.url === "string" ? event.url : void 0
|
|
1029
|
+
url: typeof event.url === "string" ? event.url : void 0,
|
|
1030
|
+
wpcomSiteId: typeof event.wpcomSiteId === "number" ? event.wpcomSiteId : void 0
|
|
1031
|
+
},
|
|
1032
|
+
{ announce: true, emitEvent: false }
|
|
1033
|
+
);
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
if (event.type === "environment.selected") {
|
|
1037
|
+
const current = ui.activeSite;
|
|
1038
|
+
if (!current) {
|
|
1039
|
+
continue;
|
|
1040
|
+
}
|
|
1041
|
+
const isLive = event.environment === "live";
|
|
1042
|
+
ui.setActiveSite(
|
|
1043
|
+
{
|
|
1044
|
+
name: current.name,
|
|
1045
|
+
path: current.path,
|
|
1046
|
+
running: current.running,
|
|
1047
|
+
remote: isLive,
|
|
1048
|
+
url: isLive ? event.url : void 0,
|
|
1049
|
+
wpcomSiteId: isLive ? event.wpcomSiteId : void 0
|
|
936
1050
|
},
|
|
937
1051
|
{ announce: true, emitEvent: false }
|
|
938
1052
|
);
|
|
939
1053
|
continue;
|
|
940
1054
|
}
|
|
941
1055
|
if (event.type === "user.message") {
|
|
942
|
-
if (event
|
|
1056
|
+
if (!isVisibleUserMessage(event)) {
|
|
943
1057
|
continue;
|
|
944
1058
|
}
|
|
945
1059
|
if (isTurnOpen) {
|
|
@@ -1216,6 +1330,137 @@ const AI_CHAT_SLASH_COMMANDS = [
|
|
|
1216
1330
|
{ name: "taxonomist", description: __("Optimize category taxonomy with AI") },
|
|
1217
1331
|
{ name: "need-for-speed", description: __("Run a performance audit on a site") }
|
|
1218
1332
|
];
|
|
1333
|
+
const THINKING_MESSAGES = [
|
|
1334
|
+
"Thinking…",
|
|
1335
|
+
"Iterating…",
|
|
1336
|
+
"Interpolating…",
|
|
1337
|
+
"Philosophising…",
|
|
1338
|
+
"Cogitating…",
|
|
1339
|
+
"Poetizing…",
|
|
1340
|
+
"Sketching…",
|
|
1341
|
+
"Scribbling…",
|
|
1342
|
+
"Drafting…",
|
|
1343
|
+
"Harmonizing…",
|
|
1344
|
+
"Rehearsing…",
|
|
1345
|
+
"Combabulating…",
|
|
1346
|
+
"Conjectureing…",
|
|
1347
|
+
"Tinkering…",
|
|
1348
|
+
"Polishing…",
|
|
1349
|
+
"Concocting…",
|
|
1350
|
+
"Wizarding…",
|
|
1351
|
+
"Enchanting…",
|
|
1352
|
+
"Transmuting…",
|
|
1353
|
+
"Summoning…",
|
|
1354
|
+
"Gutenberging…",
|
|
1355
|
+
"Hooking…",
|
|
1356
|
+
"Filtering…",
|
|
1357
|
+
"Looping…",
|
|
1358
|
+
"Codexing…",
|
|
1359
|
+
"Annotating…",
|
|
1360
|
+
"Ruminating…",
|
|
1361
|
+
"Paragraphing…",
|
|
1362
|
+
"Typesetting…",
|
|
1363
|
+
"Soloing…",
|
|
1364
|
+
"Compiling…",
|
|
1365
|
+
"Abstracting…",
|
|
1366
|
+
"Meandering…",
|
|
1367
|
+
"Daydreaming…",
|
|
1368
|
+
"Riffing…",
|
|
1369
|
+
"Wandering…",
|
|
1370
|
+
"Introspecting…",
|
|
1371
|
+
"Experiencing…",
|
|
1372
|
+
"Reflecting…",
|
|
1373
|
+
"Adventuring…",
|
|
1374
|
+
"Levitating…",
|
|
1375
|
+
"Glueing…",
|
|
1376
|
+
"Soaring…",
|
|
1377
|
+
"Gliding…",
|
|
1378
|
+
"Paragliding…",
|
|
1379
|
+
"Excavating…",
|
|
1380
|
+
"Planting…",
|
|
1381
|
+
"Stargazing…",
|
|
1382
|
+
"Scribing…"
|
|
1383
|
+
];
|
|
1384
|
+
function randomThinkingMessage() {
|
|
1385
|
+
return THINKING_MESSAGES[Math.floor(Math.random() * THINKING_MESSAGES.length)];
|
|
1386
|
+
}
|
|
1387
|
+
function getToolDisplayName(name) {
|
|
1388
|
+
const displayNames = {
|
|
1389
|
+
mcp__studio__site_create: __("Create site"),
|
|
1390
|
+
mcp__studio__site_list: __("List sites"),
|
|
1391
|
+
mcp__studio__site_info: __("Get site info"),
|
|
1392
|
+
mcp__studio__site_start: __("Start site"),
|
|
1393
|
+
mcp__studio__site_stop: __("Stop site"),
|
|
1394
|
+
mcp__studio__site_delete: __("Delete site"),
|
|
1395
|
+
mcp__studio__preview_create: __("Create preview"),
|
|
1396
|
+
mcp__studio__preview_list: __("List previews"),
|
|
1397
|
+
mcp__studio__preview_update: __("Update preview"),
|
|
1398
|
+
mcp__studio__preview_delete: __("Delete preview"),
|
|
1399
|
+
mcp__studio__wp_cli: __("Run WP-CLI"),
|
|
1400
|
+
mcp__studio__validate_blocks: __("Validate blocks"),
|
|
1401
|
+
mcp__studio__take_screenshot: __("Take screenshot"),
|
|
1402
|
+
Read: __("Read"),
|
|
1403
|
+
Write: __("Write"),
|
|
1404
|
+
Edit: __("Edit"),
|
|
1405
|
+
Bash: __("Run"),
|
|
1406
|
+
Glob: __("Search"),
|
|
1407
|
+
Grep: __("Search"),
|
|
1408
|
+
Skill: __("Load skill"),
|
|
1409
|
+
Task: __("Run task"),
|
|
1410
|
+
TodoWrite: __("Update todo list")
|
|
1411
|
+
};
|
|
1412
|
+
return displayNames[name] ?? name;
|
|
1413
|
+
}
|
|
1414
|
+
const BASH_DETAIL_MAX_LENGTH = 60;
|
|
1415
|
+
function getToolDetail(name, input) {
|
|
1416
|
+
if (!input) {
|
|
1417
|
+
return "";
|
|
1418
|
+
}
|
|
1419
|
+
switch (name) {
|
|
1420
|
+
case "mcp__studio__site_create":
|
|
1421
|
+
return typeof input.name === "string" ? input.name : "";
|
|
1422
|
+
case "mcp__studio__site_info":
|
|
1423
|
+
case "mcp__studio__site_start":
|
|
1424
|
+
case "mcp__studio__site_stop":
|
|
1425
|
+
case "mcp__studio__site_delete":
|
|
1426
|
+
case "mcp__studio__preview_create":
|
|
1427
|
+
case "mcp__studio__preview_list":
|
|
1428
|
+
return typeof input.nameOrPath === "string" ? input.nameOrPath : "";
|
|
1429
|
+
case "mcp__studio__preview_update":
|
|
1430
|
+
case "mcp__studio__preview_delete":
|
|
1431
|
+
return typeof input.host === "string" ? input.host : "";
|
|
1432
|
+
case "mcp__studio__wp_cli":
|
|
1433
|
+
return typeof input.command === "string" ? `wp ${input.command}` : "";
|
|
1434
|
+
case "mcp__studio__validate_blocks":
|
|
1435
|
+
if (typeof input.filePath === "string") {
|
|
1436
|
+
return input.filePath.split("/").slice(-2).join("/");
|
|
1437
|
+
}
|
|
1438
|
+
return __("inline content");
|
|
1439
|
+
case "mcp__studio__take_screenshot":
|
|
1440
|
+
return typeof input.url === "string" ? input.url : "";
|
|
1441
|
+
case "Read":
|
|
1442
|
+
case "Write":
|
|
1443
|
+
case "Edit": {
|
|
1444
|
+
const filePath = input.file_path ?? input.path;
|
|
1445
|
+
if (typeof filePath === "string") {
|
|
1446
|
+
return filePath.split("/").slice(-2).join("/");
|
|
1447
|
+
}
|
|
1448
|
+
return "";
|
|
1449
|
+
}
|
|
1450
|
+
case "Bash":
|
|
1451
|
+
if (typeof input.command !== "string") {
|
|
1452
|
+
return "";
|
|
1453
|
+
}
|
|
1454
|
+
return input.command.length > BASH_DETAIL_MAX_LENGTH ? input.command.slice(0, BASH_DETAIL_MAX_LENGTH - 3) + "…" : input.command;
|
|
1455
|
+
case "Skill":
|
|
1456
|
+
return typeof input.skill === "string" ? input.skill : "";
|
|
1457
|
+
case "Grep":
|
|
1458
|
+
case "Glob":
|
|
1459
|
+
return typeof input.pattern === "string" ? input.pattern : "";
|
|
1460
|
+
default:
|
|
1461
|
+
return "";
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1219
1464
|
function formatTodoSnapshotLine(todo) {
|
|
1220
1465
|
switch (todo.status) {
|
|
1221
1466
|
case "completed":
|
|
@@ -1341,6 +1586,13 @@ const DEFAULT_COLLAPSE_THRESHOLD_LINES = 5;
|
|
|
1341
1586
|
function formatToolOutputLines(lines) {
|
|
1342
1587
|
return lines.map((line, index2) => `${index2 === 0 ? " " + chalk.dim("⎿ ") : " "}${line}`).join("\n");
|
|
1343
1588
|
}
|
|
1589
|
+
function formatQueuedPrompt(text) {
|
|
1590
|
+
const lines = text.split("\n");
|
|
1591
|
+
return lines.map((line, i) => {
|
|
1592
|
+
const body = i === 0 ? "↳ " + line + " " : " " + line + " ";
|
|
1593
|
+
return " " + chalk.bgHex("#e8eef5").hex("#5a6b7d")(body);
|
|
1594
|
+
}).join("\n");
|
|
1595
|
+
}
|
|
1344
1596
|
class PromptEditor {
|
|
1345
1597
|
constructor(tui, theme, options) {
|
|
1346
1598
|
this._focused = false;
|
|
@@ -1466,83 +1718,13 @@ const editorTheme = {
|
|
|
1466
1718
|
noMatch: (text) => chalk.dim(text)
|
|
1467
1719
|
}
|
|
1468
1720
|
};
|
|
1469
|
-
const toolDisplayNames = {
|
|
1470
|
-
mcp__studio__site_create: __("Create site"),
|
|
1471
|
-
mcp__studio__site_list: __("List sites"),
|
|
1472
|
-
mcp__studio__site_info: __("Get site info"),
|
|
1473
|
-
mcp__studio__site_start: __("Start site"),
|
|
1474
|
-
mcp__studio__site_stop: __("Stop site"),
|
|
1475
|
-
mcp__studio__site_delete: __("Delete site"),
|
|
1476
|
-
mcp__studio__preview_create: __("Create preview"),
|
|
1477
|
-
mcp__studio__preview_list: __("List previews"),
|
|
1478
|
-
mcp__studio__preview_update: __("Update preview"),
|
|
1479
|
-
mcp__studio__preview_delete: __("Delete preview"),
|
|
1480
|
-
mcp__studio__wp_cli: __("Run WP-CLI"),
|
|
1481
|
-
mcp__studio__validate_blocks: __("Validate blocks"),
|
|
1482
|
-
mcp__studio__take_screenshot: __("Take screenshot"),
|
|
1483
|
-
Read: __("Read"),
|
|
1484
|
-
Write: __("Write"),
|
|
1485
|
-
Edit: __("Edit"),
|
|
1486
|
-
Bash: __("Run"),
|
|
1487
|
-
Glob: __("Search"),
|
|
1488
|
-
Grep: __("Search"),
|
|
1489
|
-
Skill: __("Load skill"),
|
|
1490
|
-
Task: __("Run task"),
|
|
1491
|
-
TodoWrite: __("Update todo list")
|
|
1492
|
-
};
|
|
1493
|
-
function getToolDetail(name, input) {
|
|
1494
|
-
switch (name) {
|
|
1495
|
-
case "mcp__studio__site_create":
|
|
1496
|
-
return typeof input.name === "string" ? input.name : "";
|
|
1497
|
-
case "mcp__studio__site_info":
|
|
1498
|
-
case "mcp__studio__site_start":
|
|
1499
|
-
case "mcp__studio__site_stop":
|
|
1500
|
-
case "mcp__studio__site_delete":
|
|
1501
|
-
case "mcp__studio__preview_create":
|
|
1502
|
-
case "mcp__studio__preview_list":
|
|
1503
|
-
return typeof input.nameOrPath === "string" ? input.nameOrPath : "";
|
|
1504
|
-
case "mcp__studio__preview_update":
|
|
1505
|
-
case "mcp__studio__preview_delete":
|
|
1506
|
-
return typeof input.host === "string" ? input.host : "";
|
|
1507
|
-
case "mcp__studio__wp_cli":
|
|
1508
|
-
return typeof input.command === "string" ? `wp ${input.command}` : "";
|
|
1509
|
-
case "mcp__studio__validate_blocks":
|
|
1510
|
-
if (typeof input.filePath === "string") {
|
|
1511
|
-
return input.filePath.split("/").slice(-2).join("/");
|
|
1512
|
-
}
|
|
1513
|
-
return __("inline content");
|
|
1514
|
-
case "mcp__studio__take_screenshot":
|
|
1515
|
-
return typeof input.url === "string" ? input.url : "";
|
|
1516
|
-
case "Read":
|
|
1517
|
-
case "Write":
|
|
1518
|
-
case "Edit": {
|
|
1519
|
-
const filePath = input.file_path ?? input.path;
|
|
1520
|
-
if (typeof filePath === "string") {
|
|
1521
|
-
const parts = filePath.split("/");
|
|
1522
|
-
return parts.slice(-2).join("/");
|
|
1523
|
-
}
|
|
1524
|
-
return "";
|
|
1525
|
-
}
|
|
1526
|
-
case "Bash":
|
|
1527
|
-
return typeof input.command === "string" ? input.command.length > 60 ? input.command.slice(0, 57) + "…" : input.command : "";
|
|
1528
|
-
case "Skill":
|
|
1529
|
-
return typeof input.skill === "string" ? input.skill : "";
|
|
1530
|
-
case "Grep":
|
|
1531
|
-
case "Glob":
|
|
1532
|
-
return typeof input.pattern === "string" ? input.pattern : "";
|
|
1533
|
-
default:
|
|
1534
|
-
return "";
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
1721
|
function formatToolName(name, input) {
|
|
1538
|
-
const displayName =
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
return chalk.bold(displayName) + " " + chalk.dim("(" + detail + ")");
|
|
1543
|
-
}
|
|
1722
|
+
const displayName = chalk.bold(getToolDisplayName(name));
|
|
1723
|
+
const detail = getToolDetail(name, input);
|
|
1724
|
+
if (detail) {
|
|
1725
|
+
return displayName + " " + chalk.dim("(" + detail + ")");
|
|
1544
1726
|
}
|
|
1545
|
-
return
|
|
1727
|
+
return displayName;
|
|
1546
1728
|
}
|
|
1547
1729
|
function isTodoWriteInput(input) {
|
|
1548
1730
|
if (!input || typeof input !== "object" || !Array.isArray(input.todos)) {
|
|
@@ -1602,6 +1784,7 @@ function normalizeToolUseResult(result) {
|
|
|
1602
1784
|
}
|
|
1603
1785
|
class AiChatUI {
|
|
1604
1786
|
constructor() {
|
|
1787
|
+
this.queuedPrompts = [];
|
|
1605
1788
|
this.currentResponseText = "";
|
|
1606
1789
|
this.currentMarkdown = null;
|
|
1607
1790
|
this.submitResolve = null;
|
|
@@ -1631,58 +1814,6 @@ class AiChatUI {
|
|
|
1631
1814
|
this.pendingToolCalls = /* @__PURE__ */ new Map();
|
|
1632
1815
|
this.currentModel = DEFAULT_MODEL;
|
|
1633
1816
|
this.currentProvider = DEFAULT_AI_PROVIDER;
|
|
1634
|
-
this.thinkingMessages = [
|
|
1635
|
-
"Thinking…",
|
|
1636
|
-
"Iterating…",
|
|
1637
|
-
"Interpolating…",
|
|
1638
|
-
"Philosophising…",
|
|
1639
|
-
"Cogitating…",
|
|
1640
|
-
"Poetizing…",
|
|
1641
|
-
"Sketching…",
|
|
1642
|
-
"Scribbling…",
|
|
1643
|
-
"Drafting…",
|
|
1644
|
-
"Harmonizing…",
|
|
1645
|
-
"Rehearsing…",
|
|
1646
|
-
"Combabulating…",
|
|
1647
|
-
"Conjectureing…",
|
|
1648
|
-
"Tinkering…",
|
|
1649
|
-
"Polishing…",
|
|
1650
|
-
"Concocting…",
|
|
1651
|
-
"Wizarding…",
|
|
1652
|
-
"Enchanting…",
|
|
1653
|
-
"Transmuting…",
|
|
1654
|
-
"Summoning…",
|
|
1655
|
-
"Gutenberging…",
|
|
1656
|
-
"Hooking…",
|
|
1657
|
-
"Filtering…",
|
|
1658
|
-
"Looping…",
|
|
1659
|
-
"Codexing…",
|
|
1660
|
-
"Annotating…",
|
|
1661
|
-
"Ruminating…",
|
|
1662
|
-
"Paragraphing…",
|
|
1663
|
-
"Typesetting…",
|
|
1664
|
-
"Soloing…",
|
|
1665
|
-
"Compiling…",
|
|
1666
|
-
"Abstracting…",
|
|
1667
|
-
"Meandering…",
|
|
1668
|
-
"Daydreaming…",
|
|
1669
|
-
"Riffing…",
|
|
1670
|
-
"Wandering…",
|
|
1671
|
-
"Introspecting…",
|
|
1672
|
-
"Experiencing…",
|
|
1673
|
-
"Reflecting…",
|
|
1674
|
-
"Adventuring…",
|
|
1675
|
-
"Levitating…",
|
|
1676
|
-
"Glueing…",
|
|
1677
|
-
"Soaring…",
|
|
1678
|
-
"Gliding…",
|
|
1679
|
-
"Paragliding…",
|
|
1680
|
-
"Excavating…",
|
|
1681
|
-
"Planting…",
|
|
1682
|
-
"Stargazing…",
|
|
1683
|
-
"Scribing…",
|
|
1684
|
-
"Levitating…"
|
|
1685
|
-
];
|
|
1686
1817
|
this.optionPickerContainer = null;
|
|
1687
1818
|
this.optionPickerSelectList = null;
|
|
1688
1819
|
this.optionPickerVisible = false;
|
|
@@ -1708,6 +1839,8 @@ class AiChatUI {
|
|
|
1708
1839
|
this.tui = new TUI(terminal, true);
|
|
1709
1840
|
this.messages = new Container();
|
|
1710
1841
|
this.tui.addChild(this.messages);
|
|
1842
|
+
this.queuedContainer = new Container();
|
|
1843
|
+
this.tui.addChild(this.queuedContainer);
|
|
1711
1844
|
this.loader = new Loader(
|
|
1712
1845
|
this.tui,
|
|
1713
1846
|
(str) => chalk.yellow(str),
|
|
@@ -1744,10 +1877,19 @@ class AiChatUI {
|
|
|
1744
1877
|
);
|
|
1745
1878
|
this.editor.onSubmit = (text) => {
|
|
1746
1879
|
const trimmed = text.trim();
|
|
1747
|
-
if (trimmed
|
|
1880
|
+
if (!trimmed) {
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
if (this.submitResolve) {
|
|
1748
1884
|
const resolve = this.submitResolve;
|
|
1749
1885
|
this.submitResolve = null;
|
|
1750
1886
|
resolve(trimmed);
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
if (this._inAgentTurn) {
|
|
1890
|
+
this.queuedPrompts.push(trimmed);
|
|
1891
|
+
this.editor.setText("");
|
|
1892
|
+
this.renderQueuedContainer();
|
|
1751
1893
|
}
|
|
1752
1894
|
};
|
|
1753
1895
|
this.tui.addInputListener((data) => {
|
|
@@ -1829,6 +1971,11 @@ class AiChatUI {
|
|
|
1829
1971
|
this.renderSitePicker();
|
|
1830
1972
|
return { consume: true };
|
|
1831
1973
|
}
|
|
1974
|
+
if (matchesKey(data, "backspace") && this.editorVisible && this.queuedPrompts.length > 0 && this.editor.getText() === "") {
|
|
1975
|
+
this.queuedPrompts.pop();
|
|
1976
|
+
this.renderQueuedContainer();
|
|
1977
|
+
return { consume: true };
|
|
1978
|
+
}
|
|
1832
1979
|
if (matchesKey(data, "escape") && this.interruptCallback) {
|
|
1833
1980
|
this.wasInterrupted = true;
|
|
1834
1981
|
this.interruptCallback();
|
|
@@ -1840,9 +1987,6 @@ class AiChatUI {
|
|
|
1840
1987
|
return void 0;
|
|
1841
1988
|
});
|
|
1842
1989
|
}
|
|
1843
|
-
randomThinkingMessage() {
|
|
1844
|
-
return this.thinkingMessages[Math.floor(Math.random() * this.thinkingMessages.length)];
|
|
1845
|
-
}
|
|
1846
1990
|
static {
|
|
1847
1991
|
this.OTHER_VALUE = "__other__";
|
|
1848
1992
|
}
|
|
@@ -1897,6 +2041,10 @@ class AiChatUI {
|
|
|
1897
2041
|
this.currentMarkdown = null;
|
|
1898
2042
|
this.currentResponseText = "";
|
|
1899
2043
|
this.messages.clear();
|
|
2044
|
+
if (this.queuedPrompts.length > 0) {
|
|
2045
|
+
this.queuedPrompts = [];
|
|
2046
|
+
this.renderQueuedContainer();
|
|
2047
|
+
}
|
|
1900
2048
|
this.tui.requestRender();
|
|
1901
2049
|
}
|
|
1902
2050
|
showAgentQuestion(question, _options) {
|
|
@@ -2300,12 +2448,12 @@ ${chalk.dim(message)}
|
|
|
2300
2448
|
this.tui.start();
|
|
2301
2449
|
}
|
|
2302
2450
|
showWelcome() {
|
|
2303
|
-
const version = "1.7.
|
|
2451
|
+
const version = "1.7.10";
|
|
2304
2452
|
const cwd = process.cwd();
|
|
2305
2453
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
2306
2454
|
const displayCwd = home && cwd.startsWith(home) ? "~" + cwd.slice(home.length) : cwd;
|
|
2307
2455
|
const b = chalk.blue;
|
|
2308
|
-
const
|
|
2456
|
+
const logoLines = [
|
|
2309
2457
|
" ▄█▛▀▀▀▀█▙▖",
|
|
2310
2458
|
" ▗▟█ ▗██▄",
|
|
2311
2459
|
"▄███▛ ▝▜██ ▝███▙",
|
|
@@ -2314,21 +2462,37 @@ ${chalk.dim(message)}
|
|
|
2314
2462
|
"▀▙▖ ▜█▄▟ ▝█▙▄▌ ▄▛",
|
|
2315
2463
|
" ▝▜▄▝██▌ ▀██▗▟▀",
|
|
2316
2464
|
" ▀██▙▄▄▄█▛▘"
|
|
2317
|
-
]
|
|
2465
|
+
];
|
|
2466
|
+
const logo = logoLines.map((s) => b(s));
|
|
2467
|
+
const logoWidth = Math.max(...logoLines.map((s) => s.length));
|
|
2468
|
+
const gap = 4;
|
|
2469
|
+
const leading = 1;
|
|
2470
|
+
const termWidth = process.stdout.columns ?? 80;
|
|
2471
|
+
const availableInfoWidth = Math.max(0, termWidth - leading - logoWidth - gap);
|
|
2472
|
+
const baseInfo = `${AI_MODELS[this.currentModel]} · ${AI_PROVIDERS[this.currentProvider]}`;
|
|
2473
|
+
const sep = " · ";
|
|
2474
|
+
let secondLine;
|
|
2475
|
+
if (baseInfo.length + sep.length + displayCwd.length <= availableInfoWidth) {
|
|
2476
|
+
secondLine = `${baseInfo}${sep}${displayCwd}`;
|
|
2477
|
+
} else {
|
|
2478
|
+
const pathBudget = availableInfoWidth - baseInfo.length - sep.length;
|
|
2479
|
+
if (pathBudget >= 4) {
|
|
2480
|
+
secondLine = `${baseInfo}${sep}…${displayCwd.slice(-(pathBudget - 1))}`;
|
|
2481
|
+
} else {
|
|
2482
|
+
secondLine = baseInfo;
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2318
2485
|
const info = [
|
|
2319
2486
|
chalk.bold("WordPress Studio") + chalk.dim(` v${version}`),
|
|
2320
|
-
chalk.dim(
|
|
2321
|
-
`${AI_MODELS[this.currentModel]} · ${AI_PROVIDERS[this.currentProvider]} · ${displayCwd}`
|
|
2322
|
-
),
|
|
2487
|
+
chalk.dim(secondLine),
|
|
2323
2488
|
"",
|
|
2324
2489
|
chalk.dim.italic(__("Code is Poetry"))
|
|
2325
2490
|
];
|
|
2326
|
-
const gap = 4;
|
|
2327
2491
|
const infoStartRow = Math.max(0, Math.floor((logo.length - info.length) / 2));
|
|
2328
2492
|
const lines = logo.map((logoLine, i) => {
|
|
2329
2493
|
const infoIndex = i - infoStartRow;
|
|
2330
2494
|
const infoText = infoIndex >= 0 && infoIndex < info.length ? info[infoIndex] : "";
|
|
2331
|
-
return " " + logoLine + " ".repeat(gap) + infoText;
|
|
2495
|
+
return " ".repeat(leading) + logoLine + " ".repeat(gap) + infoText;
|
|
2332
2496
|
});
|
|
2333
2497
|
this.messages.addChild(new Text("\n" + lines.join("\n") + "\n", 0, 0));
|
|
2334
2498
|
this.tui.requestRender();
|
|
@@ -2344,6 +2508,11 @@ ${chalk.dim(message)}
|
|
|
2344
2508
|
this.editor.setText("");
|
|
2345
2509
|
this.hideLoader();
|
|
2346
2510
|
this.showEditor();
|
|
2511
|
+
if (this.queuedPrompts.length > 0) {
|
|
2512
|
+
const next = this.queuedPrompts.shift();
|
|
2513
|
+
this.renderQueuedContainer();
|
|
2514
|
+
return Promise.resolve(next);
|
|
2515
|
+
}
|
|
2347
2516
|
return new Promise((resolve) => {
|
|
2348
2517
|
this.submitResolve = resolve;
|
|
2349
2518
|
});
|
|
@@ -2359,6 +2528,14 @@ ${chalk.dim(message)}
|
|
|
2359
2528
|
this.messages.addChild(new Text("\n" + formatted, 0, 0));
|
|
2360
2529
|
this.tui.requestRender();
|
|
2361
2530
|
}
|
|
2531
|
+
renderQueuedContainer() {
|
|
2532
|
+
this.queuedContainer.clear();
|
|
2533
|
+
for (const prompt of this.queuedPrompts) {
|
|
2534
|
+
this.queuedContainer.addChild(new Text("\n" + formatQueuedPrompt(prompt), 0, 0));
|
|
2535
|
+
}
|
|
2536
|
+
this.updateHints();
|
|
2537
|
+
this.tui.requestRender();
|
|
2538
|
+
}
|
|
2362
2539
|
setLoaderMessage(message, update) {
|
|
2363
2540
|
if (!message) {
|
|
2364
2541
|
return;
|
|
@@ -2378,7 +2555,9 @@ ${chalk.dim(message)}
|
|
|
2378
2555
|
if (wasEditorVisible) {
|
|
2379
2556
|
this.tui.removeChild(this.editor);
|
|
2380
2557
|
}
|
|
2558
|
+
this.tui.removeChild(this.queuedContainer);
|
|
2381
2559
|
this.tui.addChild(this.loader);
|
|
2560
|
+
this.tui.addChild(this.queuedContainer);
|
|
2382
2561
|
if (wasEditorVisible) {
|
|
2383
2562
|
this.tui.addChild(this.editor);
|
|
2384
2563
|
}
|
|
@@ -2409,6 +2588,9 @@ ${chalk.dim(message)}
|
|
|
2409
2588
|
this.activeExpandablePreview.isExpanded ? __("ctrl+o collapse") : __("ctrl+o expand")
|
|
2410
2589
|
);
|
|
2411
2590
|
}
|
|
2591
|
+
if (this.queuedPrompts.length > 0) {
|
|
2592
|
+
hints.push(__("backspace to unqueue"));
|
|
2593
|
+
}
|
|
2412
2594
|
hints.push(__("esc to interrupt"));
|
|
2413
2595
|
this.editor.hints = hints;
|
|
2414
2596
|
}
|
|
@@ -2436,7 +2618,7 @@ ${chalk.dim(message)}
|
|
|
2436
2618
|
this.editor.setText("");
|
|
2437
2619
|
this._inAgentTurn = true;
|
|
2438
2620
|
this.updateHints();
|
|
2439
|
-
this.showLoader(
|
|
2621
|
+
this.showLoader(randomThinkingMessage());
|
|
2440
2622
|
this.currentResponseText = "";
|
|
2441
2623
|
this.hasShownResponseMarker = false;
|
|
2442
2624
|
this.wasInterrupted = false;
|
|
@@ -2710,7 +2892,7 @@ ${chalk.dim(message)}
|
|
|
2710
2892
|
}
|
|
2711
2893
|
}
|
|
2712
2894
|
showToolUse(toolLabel) {
|
|
2713
|
-
this.showLoader(
|
|
2895
|
+
this.showLoader(randomThinkingMessage());
|
|
2714
2896
|
this.stopToolDotBlink();
|
|
2715
2897
|
this.lastProgressText = null;
|
|
2716
2898
|
this.toolDotLabel = toolLabel;
|
|
@@ -2921,7 +3103,7 @@ ${chalk.dim(message)}
|
|
|
2921
3103
|
answers[q.question] = answer;
|
|
2922
3104
|
}
|
|
2923
3105
|
}
|
|
2924
|
-
this.showLoader(
|
|
3106
|
+
this.showLoader(randomThinkingMessage());
|
|
2925
3107
|
return answers;
|
|
2926
3108
|
}
|
|
2927
3109
|
/**
|
|
@@ -2982,7 +3164,7 @@ ${chalk.dim(message)}
|
|
|
2982
3164
|
}
|
|
2983
3165
|
}
|
|
2984
3166
|
if (!this.replayMode && !this.loaderVisible) {
|
|
2985
|
-
this.showLoader(
|
|
3167
|
+
this.showLoader(randomThinkingMessage());
|
|
2986
3168
|
}
|
|
2987
3169
|
return void 0;
|
|
2988
3170
|
}
|
|
@@ -3006,29 +3188,15 @@ ${chalk.dim(message)}
|
|
|
3006
3188
|
}
|
|
3007
3189
|
case "result": {
|
|
3008
3190
|
this.hideLoader();
|
|
3009
|
-
if (message.subtype === "
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
}
|
|
3016
|
-
this.showInfo(
|
|
3017
|
-
sprintf(
|
|
3018
|
-
/* translators: 1: seconds spent thinking, 2: number of turns */
|
|
3019
|
-
_n(
|
|
3020
|
-
"Thought for %1$ds · %2$d turn",
|
|
3021
|
-
"Thought for %1$ds · %2$d turns",
|
|
3022
|
-
message.num_turns
|
|
3023
|
-
),
|
|
3024
|
-
thinkingSec,
|
|
3025
|
-
message.num_turns
|
|
3026
|
-
)
|
|
3027
|
-
);
|
|
3028
|
-
return { type: "result", sessionId: message.session_id, success: true };
|
|
3191
|
+
if (message.subtype === "error_max_turns") {
|
|
3192
|
+
return {
|
|
3193
|
+
type: "max_turns",
|
|
3194
|
+
sessionId: message.session_id,
|
|
3195
|
+
numTurns: message.num_turns
|
|
3196
|
+
};
|
|
3029
3197
|
}
|
|
3030
3198
|
if (this.wasInterrupted) {
|
|
3031
|
-
const
|
|
3199
|
+
const thinkingSec2 = Math.round((this.nowMs() - this.turnStartTime) / 1e3);
|
|
3032
3200
|
this.messages.addChild(
|
|
3033
3201
|
new Text(
|
|
3034
3202
|
"\n " + chalk.yellow("⏺") + " " + chalk.yellow(__("Interrupted")),
|
|
@@ -3040,37 +3208,59 @@ ${chalk.dim(message)}
|
|
|
3040
3208
|
sprintf(
|
|
3041
3209
|
/* translators: %d: number of seconds */
|
|
3042
3210
|
__("Ran for %ds before interruption"),
|
|
3043
|
-
|
|
3211
|
+
thinkingSec2
|
|
3044
3212
|
)
|
|
3045
3213
|
);
|
|
3046
|
-
return { type: "result", sessionId: message.session_id, success: false };
|
|
3047
|
-
}
|
|
3048
|
-
const parts = [];
|
|
3049
|
-
if ("errors" in message && message.errors?.length) {
|
|
3050
|
-
parts.push(...message.errors);
|
|
3051
|
-
}
|
|
3052
|
-
if (message.subtype === "error_max_turns") {
|
|
3053
3214
|
return {
|
|
3054
|
-
type: "
|
|
3215
|
+
type: "result",
|
|
3055
3216
|
sessionId: message.session_id,
|
|
3056
|
-
|
|
3217
|
+
success: false,
|
|
3218
|
+
interrupted: true
|
|
3057
3219
|
};
|
|
3058
|
-
} else if (message.subtype) {
|
|
3059
|
-
parts.push(`(${message.subtype})`);
|
|
3060
3220
|
}
|
|
3061
|
-
if (
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
);
|
|
3221
|
+
if (message.is_error) {
|
|
3222
|
+
const parts = [];
|
|
3223
|
+
if ("errors" in message && message.errors?.length) {
|
|
3224
|
+
parts.push(...message.errors);
|
|
3225
|
+
}
|
|
3226
|
+
if ("result" in message && typeof message.result === "string" && message.result) {
|
|
3227
|
+
parts.push(message.result);
|
|
3228
|
+
} else if (message.subtype && message.subtype !== "success") {
|
|
3229
|
+
parts.push(`(${message.subtype})`);
|
|
3230
|
+
}
|
|
3231
|
+
if ("permission_denials" in message && message.permission_denials?.length) {
|
|
3232
|
+
for (const denial of message.permission_denials) {
|
|
3233
|
+
parts.push(
|
|
3234
|
+
sprintf(
|
|
3235
|
+
/* translators: %s: tool name */
|
|
3236
|
+
__("Permission denied: %s"),
|
|
3237
|
+
denial.tool_name
|
|
3238
|
+
)
|
|
3239
|
+
);
|
|
3240
|
+
}
|
|
3070
3241
|
}
|
|
3242
|
+
this.showError(parts.length > 0 ? parts.join("\n") : __("Unknown error"));
|
|
3243
|
+
return { type: "result", sessionId: message.session_id, success: false };
|
|
3244
|
+
}
|
|
3245
|
+
const thinkingSec = Math.round((this.nowMs() - this.turnStartTime) / 1e3);
|
|
3246
|
+
if (!this.hasShownResponseMarker) {
|
|
3247
|
+
this.messages.addChild(
|
|
3248
|
+
new Text("\n " + chalk.blue("⏺") + " " + __("Done"), 0, 0)
|
|
3249
|
+
);
|
|
3071
3250
|
}
|
|
3072
|
-
this.
|
|
3073
|
-
|
|
3251
|
+
this.showInfo(
|
|
3252
|
+
sprintf(
|
|
3253
|
+
/* translators: 1: seconds spent thinking, 2: number of turns */
|
|
3254
|
+
_n(
|
|
3255
|
+
"Thought for %1$ds · %2$d turn",
|
|
3256
|
+
"Thought for %1$ds · %2$d turns",
|
|
3257
|
+
message.num_turns
|
|
3258
|
+
),
|
|
3259
|
+
thinkingSec,
|
|
3260
|
+
message.num_turns
|
|
3261
|
+
)
|
|
3262
|
+
);
|
|
3263
|
+
return { type: "result", sessionId: message.session_id, success: true };
|
|
3074
3264
|
}
|
|
3075
3265
|
case "system": {
|
|
3076
3266
|
if (message.subtype === "status" && message.status === "compacting") {
|
|
@@ -3103,6 +3293,16 @@ async function runCommand(options) {
|
|
|
3103
3293
|
let currentModel = resumeContext.model ?? DEFAULT_MODEL;
|
|
3104
3294
|
ui.currentProvider = currentProvider;
|
|
3105
3295
|
ui.currentModel = currentModel;
|
|
3296
|
+
if (options.activeSite) {
|
|
3297
|
+
ui.activeSite = {
|
|
3298
|
+
name: options.activeSite.name,
|
|
3299
|
+
path: options.activeSite.path,
|
|
3300
|
+
running: options.activeSite.running ?? false,
|
|
3301
|
+
remote: options.activeSite.remote,
|
|
3302
|
+
url: options.activeSite.url,
|
|
3303
|
+
wpcomSiteId: options.activeSite.wpcomSiteId
|
|
3304
|
+
};
|
|
3305
|
+
}
|
|
3106
3306
|
ui.start();
|
|
3107
3307
|
ui.showWelcome();
|
|
3108
3308
|
if (options.showLegacyCommandNotice && !isJsonMode) {
|
|
@@ -3110,7 +3310,7 @@ async function runCommand(options) {
|
|
|
3110
3310
|
}
|
|
3111
3311
|
let sessionRecorder;
|
|
3112
3312
|
let didDisableSessionPersistence = options.noSessionPersistence === true;
|
|
3113
|
-
let sessionId = resumeContext.sessionId;
|
|
3313
|
+
let sessionId = options.resumeSessionId ?? resumeContext.sessionId;
|
|
3114
3314
|
let persistQueue = Promise.resolve();
|
|
3115
3315
|
if (options.noSessionPersistence) {
|
|
3116
3316
|
ui.showInfo(__("Session persistence disabled (--no-session-persistence)."));
|
|
@@ -3129,6 +3329,25 @@ async function runCommand(options) {
|
|
|
3129
3329
|
filePath: options.resumeSession.summary.filePath,
|
|
3130
3330
|
linkedAgentSessionIds: options.resumeSession.summary.linkedAgentSessionIds
|
|
3131
3331
|
});
|
|
3332
|
+
} else if (options.resumeSessionId) {
|
|
3333
|
+
const sessions = await listAiSessions(getAiSessionsRootDirectory());
|
|
3334
|
+
const existing = sessions.find(
|
|
3335
|
+
(s) => s.linkedAgentSessionIds.includes(options.resumeSessionId)
|
|
3336
|
+
);
|
|
3337
|
+
if (!existing) {
|
|
3338
|
+
throw new Error(
|
|
3339
|
+
sprintf(
|
|
3340
|
+
/* translators: %s: agent session ID */
|
|
3341
|
+
__("No AI session found for resume ID: %s"),
|
|
3342
|
+
options.resumeSessionId
|
|
3343
|
+
)
|
|
3344
|
+
);
|
|
3345
|
+
}
|
|
3346
|
+
sessionRecorder = await AiSessionRecorder.open({
|
|
3347
|
+
sessionId: existing.id,
|
|
3348
|
+
filePath: existing.filePath,
|
|
3349
|
+
linkedAgentSessionIds: existing.linkedAgentSessionIds
|
|
3350
|
+
});
|
|
3132
3351
|
} else {
|
|
3133
3352
|
sessionRecorder = await AiSessionRecorder.create();
|
|
3134
3353
|
}
|
|
@@ -3182,9 +3401,9 @@ async function runCommand(options) {
|
|
|
3182
3401
|
})
|
|
3183
3402
|
);
|
|
3184
3403
|
}
|
|
3185
|
-
setProgressCallback((message
|
|
3404
|
+
setProgressCallback((message) => {
|
|
3186
3405
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3187
|
-
ui.setLoaderMessage(message
|
|
3406
|
+
ui.setLoaderMessage(message);
|
|
3188
3407
|
void persist((recorder) => recorder.recordToolProgress(message, timestamp));
|
|
3189
3408
|
});
|
|
3190
3409
|
ui.onSiteSelected = (site) => {
|
|
@@ -3366,7 +3585,9 @@ async function runCommand(options) {
|
|
|
3366
3585
|
}
|
|
3367
3586
|
return answers;
|
|
3368
3587
|
}
|
|
3369
|
-
|
|
3588
|
+
const MAX_RETRY_ATTEMPTS = 4;
|
|
3589
|
+
async function runAgentTurn(prompt, retryAttempt = 0) {
|
|
3590
|
+
await maybeAutoSwitchProvider();
|
|
3370
3591
|
const env = await resolveAiEnvironment(currentProvider);
|
|
3371
3592
|
ui.beginAgentTurn();
|
|
3372
3593
|
let enrichedPrompt = prompt;
|
|
@@ -3421,6 +3642,8 @@ ${prompt}`;
|
|
|
3421
3642
|
numTurns: result.numTurns
|
|
3422
3643
|
};
|
|
3423
3644
|
turnStatus = "max_turns";
|
|
3645
|
+
} else if (result.interrupted) {
|
|
3646
|
+
turnStatus = "interrupted";
|
|
3424
3647
|
} else {
|
|
3425
3648
|
turnStatus = result.success ? "success" : "error";
|
|
3426
3649
|
}
|
|
@@ -3428,7 +3651,10 @@ ${prompt}`;
|
|
|
3428
3651
|
}
|
|
3429
3652
|
} catch (error) {
|
|
3430
3653
|
turnStatus = "error";
|
|
3431
|
-
|
|
3654
|
+
if (isJsonMode) {
|
|
3655
|
+
throw error;
|
|
3656
|
+
}
|
|
3657
|
+
ui.showError(getErrorMessage(error));
|
|
3432
3658
|
} finally {
|
|
3433
3659
|
await persist((recorder) => recorder.recordTurnClosed(turnStatus));
|
|
3434
3660
|
ui.endAgentTurn();
|
|
@@ -3456,6 +3682,32 @@ ${prompt}`;
|
|
|
3456
3682
|
return runAgentTurn("Continue from where you left off.");
|
|
3457
3683
|
}
|
|
3458
3684
|
}
|
|
3685
|
+
if (turnStatus === "error" && !isJsonMode) {
|
|
3686
|
+
if (retryAttempt >= MAX_RETRY_ATTEMPTS) {
|
|
3687
|
+
ui.showInfo(
|
|
3688
|
+
__("The server has not recovered after multiple attempts. Please try again later.")
|
|
3689
|
+
);
|
|
3690
|
+
} else {
|
|
3691
|
+
const answer = await ui.askUser([
|
|
3692
|
+
{
|
|
3693
|
+
question: __("There was a hiccup on the server. Do you want to continue?"),
|
|
3694
|
+
options: [
|
|
3695
|
+
{ label: "Yes", description: __("Continue from where you left off") },
|
|
3696
|
+
{
|
|
3697
|
+
label: "No",
|
|
3698
|
+
description: __("Stop so I can give different instructions")
|
|
3699
|
+
}
|
|
3700
|
+
]
|
|
3701
|
+
}
|
|
3702
|
+
]);
|
|
3703
|
+
const choice = Object.values(answer)[0]?.toLowerCase();
|
|
3704
|
+
if (choice === "yes") {
|
|
3705
|
+
ui.showInfo(__("Retrying…"));
|
|
3706
|
+
const retryPrompt = sessionId ? "Continue from where you left off." : prompt;
|
|
3707
|
+
return runAgentTurn(retryPrompt, retryAttempt + 1);
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3459
3711
|
return {
|
|
3460
3712
|
status: turnStatus,
|
|
3461
3713
|
usage: maxTurnsResult
|
|
@@ -3535,7 +3787,6 @@ ${prompt}`;
|
|
|
3535
3787
|
break;
|
|
3536
3788
|
}
|
|
3537
3789
|
} else {
|
|
3538
|
-
await maybeAutoSwitchProvider();
|
|
3539
3790
|
ui.addUserMessage(prompt);
|
|
3540
3791
|
try {
|
|
3541
3792
|
await runAgentTurn(`Run the /${cmd.name} skill using the Skill tool.`);
|
|
@@ -3545,7 +3796,6 @@ ${prompt}`;
|
|
|
3545
3796
|
}
|
|
3546
3797
|
continue;
|
|
3547
3798
|
}
|
|
3548
|
-
await maybeAutoSwitchProvider();
|
|
3549
3799
|
ui.addUserMessage(prompt);
|
|
3550
3800
|
try {
|
|
3551
3801
|
await runAgentTurn(prompt);
|
|
@@ -3569,6 +3819,10 @@ const registerCommand = (yargs) => {
|
|
|
3569
3819
|
description: __("Initial message to send to the AI agent")
|
|
3570
3820
|
}).option("path", {
|
|
3571
3821
|
hidden: true
|
|
3822
|
+
}).option("site-name", {
|
|
3823
|
+
type: "string",
|
|
3824
|
+
hidden: true,
|
|
3825
|
+
description: __("Name of the active WordPress site")
|
|
3572
3826
|
}).option("json", {
|
|
3573
3827
|
type: "boolean",
|
|
3574
3828
|
default: false,
|
|
@@ -3576,6 +3830,14 @@ const registerCommand = (yargs) => {
|
|
|
3576
3830
|
}).option("auto-approve", {
|
|
3577
3831
|
type: "boolean",
|
|
3578
3832
|
description: __("Auto-approve all tool calls (defaults to true in --json mode)")
|
|
3833
|
+
}).option("resume-session", {
|
|
3834
|
+
type: "string",
|
|
3835
|
+
hidden: true,
|
|
3836
|
+
description: __("SDK session ID to resume (for JSON mode multi-turn)")
|
|
3837
|
+
}).option("permission-response", {
|
|
3838
|
+
type: "string",
|
|
3839
|
+
hidden: true,
|
|
3840
|
+
description: __("JSON-encoded permission response for a paused session")
|
|
3579
3841
|
}).option("session-persistence", {
|
|
3580
3842
|
type: "boolean",
|
|
3581
3843
|
default: true,
|
|
@@ -3592,12 +3854,18 @@ const registerCommand = (yargs) => {
|
|
|
3592
3854
|
const typedArgv = argv;
|
|
3593
3855
|
const noSessionPersistence = typedArgv.sessionPersistence === false;
|
|
3594
3856
|
const adapter = typedArgv.json ? new JsonAdapter() : new AiChatUI();
|
|
3857
|
+
if (adapter instanceof JsonAdapter && typedArgv.permissionResponse) {
|
|
3858
|
+
adapter.permissionResponse = JSON.parse(typedArgv.permissionResponse);
|
|
3859
|
+
}
|
|
3860
|
+
const sitePath = typeof argv.path === "string" ? argv.path : void 0;
|
|
3595
3861
|
await runCommand({
|
|
3596
3862
|
adapter,
|
|
3597
3863
|
initialMessage: typedArgv.message,
|
|
3864
|
+
resumeSessionId: typedArgv.resumeSession,
|
|
3598
3865
|
noSessionPersistence,
|
|
3599
3866
|
autoApprove: typedArgv.autoApprove,
|
|
3600
|
-
showLegacyCommandNotice: argv._[0] === "ai"
|
|
3867
|
+
showLegacyCommandNotice: argv._[0] === "ai",
|
|
3868
|
+
activeSite: sitePath && typedArgv.siteName ? { name: typedArgv.siteName, path: sitePath } : void 0
|
|
3601
3869
|
});
|
|
3602
3870
|
} catch (error) {
|
|
3603
3871
|
if (error instanceof LoggerError) {
|
|
@@ -3617,6 +3885,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
3617
3885
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3618
3886
|
export {
|
|
3619
3887
|
AiChatUI as A,
|
|
3888
|
+
JsonAdapter as J,
|
|
3620
3889
|
index as i,
|
|
3621
3890
|
runCommand as r
|
|
3622
3891
|
};
|