pinokiod 6.0.41 → 6.0.43
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/kernel/bin/cli.js +1 -1
- package/package.json +1 -1
- package/server/index.js +25 -7
- package/server/lib/terminal_session_helpers.js +64 -0
- package/server/views/terminals.ejs +268 -37
package/kernel/bin/cli.js
CHANGED
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -6397,6 +6397,8 @@ class Server {
|
|
|
6397
6397
|
})
|
|
6398
6398
|
const {
|
|
6399
6399
|
getTerminalStarterProviders,
|
|
6400
|
+
normalizeTerminalLaunchMode,
|
|
6401
|
+
buildTerminalStartCommand,
|
|
6400
6402
|
getTerminalWorkspacesRoot,
|
|
6401
6403
|
isValidTerminalWorkspaceName,
|
|
6402
6404
|
listTerminalWorkspaceFolders,
|
|
@@ -7526,6 +7528,16 @@ class Server {
|
|
|
7526
7528
|
}
|
|
7527
7529
|
|
|
7528
7530
|
const provider = providerMap.get(providerKey)
|
|
7531
|
+
const launchMode = normalizeTerminalLaunchMode(
|
|
7532
|
+
body && typeof body === "object"
|
|
7533
|
+
? (body.launchMode || body.launch_mode)
|
|
7534
|
+
: "",
|
|
7535
|
+
provider && provider.defaultLaunchMode ? provider.defaultLaunchMode : "guarded"
|
|
7536
|
+
)
|
|
7537
|
+
const startCommand = buildTerminalStartCommand(provider, launchMode) || provider.startCommand || provider.command
|
|
7538
|
+
if (typeof startCommand !== "string" || startCommand.trim().length === 0) {
|
|
7539
|
+
failStart(500, `No start command configured for ${provider.label || provider.key || "provider"}.`)
|
|
7540
|
+
}
|
|
7529
7541
|
const now = new Date()
|
|
7530
7542
|
const pad = (value) => String(value).padStart(2, "0")
|
|
7531
7543
|
const timestamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`
|
|
@@ -7692,7 +7704,8 @@ class Server {
|
|
|
7692
7704
|
label: provider.label,
|
|
7693
7705
|
terminal_id: terminalId,
|
|
7694
7706
|
created_at: now.toISOString(),
|
|
7695
|
-
|
|
7707
|
+
launch_mode: launchMode,
|
|
7708
|
+
command: startCommand,
|
|
7696
7709
|
skill_context: skillContext && skillContext.activePath ? skillContext.activePath : null,
|
|
7697
7710
|
skills: skillContext && Array.isArray(skillContext.selected) ? skillContext.selected : [],
|
|
7698
7711
|
uploaded_files: copiedUploads
|
|
@@ -7709,7 +7722,7 @@ class Server {
|
|
|
7709
7722
|
params.set("path", sessionCwd)
|
|
7710
7723
|
params.set("cwd", sessionCwd)
|
|
7711
7724
|
params.set("terminal_id", terminalId)
|
|
7712
|
-
params.set("message",
|
|
7725
|
+
params.set("message", startCommand)
|
|
7713
7726
|
params.set("input", "1")
|
|
7714
7727
|
const safeWorkspaceName = workspaceFolderName && workspaceFolderName.trim().length > 0
|
|
7715
7728
|
? workspaceFolderName.replace(/[^A-Za-z0-9._-]+/g, "-")
|
|
@@ -7739,7 +7752,9 @@ class Server {
|
|
|
7739
7752
|
workspace_path: sessionCwd || "",
|
|
7740
7753
|
summary: null,
|
|
7741
7754
|
timestamp: now.toISOString(),
|
|
7742
|
-
terminal_id: terminalId
|
|
7755
|
+
terminal_id: terminalId,
|
|
7756
|
+
launch_mode: launchMode,
|
|
7757
|
+
command: startCommand
|
|
7743
7758
|
}
|
|
7744
7759
|
await upsertTerminalSessionRegistryEntry(optimisticEntry)
|
|
7745
7760
|
return {
|
|
@@ -7754,6 +7769,7 @@ class Server {
|
|
|
7754
7769
|
index: `launch:${terminalId}`,
|
|
7755
7770
|
uri: `${provider.key}:launch:${terminalId}`,
|
|
7756
7771
|
timestamp: now.toISOString(),
|
|
7772
|
+
launch_mode: launchMode,
|
|
7757
7773
|
url,
|
|
7758
7774
|
skills: skillContext && Array.isArray(skillContext.selected)
|
|
7759
7775
|
? skillContext.selected.map((skill) => ({ id: skill.id, label: skill.label }))
|
|
@@ -8747,12 +8763,14 @@ class Server {
|
|
|
8747
8763
|
}
|
|
8748
8764
|
let restartMessage = message
|
|
8749
8765
|
const routeProviderKey = extractProviderFromRouteId(decodedRouteId)
|
|
8750
|
-
|
|
8766
|
+
const hasExplicitRestartMessage = typeof restartMessage === "string" && restartMessage.trim().length > 0
|
|
8767
|
+
if (routeProviderKey && !hasExplicitRestartMessage) {
|
|
8751
8768
|
const restartProvider = getTerminalStarterProviders().find((provider) => normalizeProviderKey(provider && provider.key) === routeProviderKey)
|
|
8752
8769
|
if (restartProvider) {
|
|
8753
|
-
const restartCandidate =
|
|
8754
|
-
|
|
8755
|
-
|
|
8770
|
+
const restartCandidate = buildTerminalStartCommand(
|
|
8771
|
+
restartProvider,
|
|
8772
|
+
restartProvider && restartProvider.defaultLaunchMode ? restartProvider.defaultLaunchMode : "guarded"
|
|
8773
|
+
)
|
|
8756
8774
|
if (restartCandidate) {
|
|
8757
8775
|
restartMessage = restartCandidate
|
|
8758
8776
|
}
|
|
@@ -3,21 +3,83 @@
|
|
|
3
3
|
const { createTerminalSessionRegistry } = require("./terminal_session_registry")
|
|
4
4
|
|
|
5
5
|
const createTerminalSessionHelpers = ({ kernel, fs, path, os, crypto }) => {
|
|
6
|
+
const TERMINAL_LAUNCH_MODE_GUARDED = "guarded"
|
|
7
|
+
const TERMINAL_LAUNCH_MODE_YOLO = "yolo"
|
|
8
|
+
const normalizeTerminalLaunchMode = (value, fallback = TERMINAL_LAUNCH_MODE_GUARDED) => {
|
|
9
|
+
const normalizedFallback = typeof fallback === "string" && fallback.trim().toLowerCase() === TERMINAL_LAUNCH_MODE_YOLO
|
|
10
|
+
? TERMINAL_LAUNCH_MODE_YOLO
|
|
11
|
+
: TERMINAL_LAUNCH_MODE_GUARDED
|
|
12
|
+
const normalized = typeof value === "string" ? value.trim().toLowerCase() : ""
|
|
13
|
+
if (!normalized) {
|
|
14
|
+
return normalizedFallback
|
|
15
|
+
}
|
|
16
|
+
if (
|
|
17
|
+
normalized === TERMINAL_LAUNCH_MODE_YOLO
|
|
18
|
+
|| normalized === "danger"
|
|
19
|
+
|| normalized === "dangerous"
|
|
20
|
+
|| normalized === "true-yolo"
|
|
21
|
+
) {
|
|
22
|
+
return TERMINAL_LAUNCH_MODE_YOLO
|
|
23
|
+
}
|
|
24
|
+
if (
|
|
25
|
+
normalized === TERMINAL_LAUNCH_MODE_GUARDED
|
|
26
|
+
|| normalized === "default"
|
|
27
|
+
|| normalized === "safe"
|
|
28
|
+
|| normalized === "standard"
|
|
29
|
+
) {
|
|
30
|
+
return TERMINAL_LAUNCH_MODE_GUARDED
|
|
31
|
+
}
|
|
32
|
+
return normalizedFallback
|
|
33
|
+
}
|
|
34
|
+
const buildTerminalStartCommand = (provider, launchMode = TERMINAL_LAUNCH_MODE_GUARDED) => {
|
|
35
|
+
if (!provider || typeof provider !== "object") {
|
|
36
|
+
return ""
|
|
37
|
+
}
|
|
38
|
+
const mode = normalizeTerminalLaunchMode(launchMode, provider.defaultLaunchMode || TERMINAL_LAUNCH_MODE_GUARDED)
|
|
39
|
+
const startCommands = provider.startCommands && typeof provider.startCommands === "object"
|
|
40
|
+
? provider.startCommands
|
|
41
|
+
: null
|
|
42
|
+
if (startCommands && typeof startCommands[mode] === "string" && startCommands[mode].trim().length > 0) {
|
|
43
|
+
return startCommands[mode].trim()
|
|
44
|
+
}
|
|
45
|
+
if (typeof provider.startCommand === "string" && provider.startCommand.trim().length > 0) {
|
|
46
|
+
return provider.startCommand.trim()
|
|
47
|
+
}
|
|
48
|
+
if (typeof provider.command === "string" && provider.command.trim().length > 0) {
|
|
49
|
+
return provider.command.trim()
|
|
50
|
+
}
|
|
51
|
+
return ""
|
|
52
|
+
}
|
|
6
53
|
const getTerminalStarterProviders = () => {
|
|
7
54
|
return [{
|
|
8
55
|
key: "codex",
|
|
9
56
|
label: "Codex",
|
|
10
57
|
command: "npx -y @openai/codex@latest",
|
|
58
|
+
defaultLaunchMode: TERMINAL_LAUNCH_MODE_GUARDED,
|
|
59
|
+
startCommands: {
|
|
60
|
+
[TERMINAL_LAUNCH_MODE_GUARDED]: 'npx -y @openai/codex@latest -c shell_environment_policy.inherit="all" --sandbox workspace-write --full-auto --ask-for-approval never',
|
|
61
|
+
[TERMINAL_LAUNCH_MODE_YOLO]: "npx -y @openai/codex@latest --dangerously-bypass-approvals-and-sandbox"
|
|
62
|
+
},
|
|
11
63
|
startCommand: 'npx -y @openai/codex@latest -c shell_environment_policy.inherit="all" --sandbox workspace-write --full-auto --ask-for-approval never'
|
|
12
64
|
}, {
|
|
13
65
|
key: "claude",
|
|
14
66
|
label: "Claude",
|
|
15
67
|
command: "npx -y @anthropic-ai/claude-code@latest",
|
|
68
|
+
defaultLaunchMode: TERMINAL_LAUNCH_MODE_GUARDED,
|
|
69
|
+
startCommands: {
|
|
70
|
+
[TERMINAL_LAUNCH_MODE_GUARDED]: "npx -y @anthropic-ai/claude-code@latest",
|
|
71
|
+
[TERMINAL_LAUNCH_MODE_YOLO]: "npx -y @anthropic-ai/claude-code@latest --dangerously-skip-permissions"
|
|
72
|
+
},
|
|
16
73
|
startCommand: "npx -y @anthropic-ai/claude-code@latest"
|
|
17
74
|
}, {
|
|
18
75
|
key: "gemini",
|
|
19
76
|
label: "Gemini",
|
|
20
77
|
command: "npx -y @google/gemini-cli@latest",
|
|
78
|
+
defaultLaunchMode: TERMINAL_LAUNCH_MODE_GUARDED,
|
|
79
|
+
startCommands: {
|
|
80
|
+
[TERMINAL_LAUNCH_MODE_GUARDED]: "npx -y @google/gemini-cli@latest",
|
|
81
|
+
[TERMINAL_LAUNCH_MODE_YOLO]: "npx -y @google/gemini-cli@latest --approval-mode yolo --no-sandbox"
|
|
82
|
+
},
|
|
21
83
|
startCommand: "npx -y @google/gemini-cli@latest"
|
|
22
84
|
}]
|
|
23
85
|
}
|
|
@@ -2524,6 +2586,8 @@ const createTerminalSessionHelpers = ({ kernel, fs, path, os, crypto }) => {
|
|
|
2524
2586
|
|
|
2525
2587
|
return {
|
|
2526
2588
|
getTerminalStarterProviders,
|
|
2589
|
+
normalizeTerminalLaunchMode,
|
|
2590
|
+
buildTerminalStartCommand,
|
|
2527
2591
|
getTerminalWorkspacesRoot,
|
|
2528
2592
|
isValidTerminalWorkspaceName,
|
|
2529
2593
|
listTerminalWorkspaceFolders,
|
|
@@ -1428,6 +1428,66 @@ body.dark .terminals-launcher-search {
|
|
|
1428
1428
|
flex-wrap: nowrap;
|
|
1429
1429
|
}
|
|
1430
1430
|
|
|
1431
|
+
.terminals-launcher-mode-options {
|
|
1432
|
+
display: inline-flex;
|
|
1433
|
+
gap: 6px;
|
|
1434
|
+
align-items: center;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
.terminals-launcher-mode {
|
|
1438
|
+
display: inline-flex;
|
|
1439
|
+
align-items: center;
|
|
1440
|
+
justify-content: center;
|
|
1441
|
+
gap: 6px;
|
|
1442
|
+
height: var(--terminals-launcher-control-height);
|
|
1443
|
+
min-width: 90px;
|
|
1444
|
+
padding: 0 12px;
|
|
1445
|
+
border-radius: 7px;
|
|
1446
|
+
border: 1px solid rgba(15, 23, 42, 0.16);
|
|
1447
|
+
background: transparent;
|
|
1448
|
+
color: inherit;
|
|
1449
|
+
cursor: pointer;
|
|
1450
|
+
font-size: 12px;
|
|
1451
|
+
font-weight: 700;
|
|
1452
|
+
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
body.dark .terminals-launcher-mode {
|
|
1456
|
+
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
.terminals-launcher-mode.active {
|
|
1460
|
+
border-color: rgba(65, 105, 225, 0.72);
|
|
1461
|
+
background: rgba(65, 105, 225, 0.12);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.terminals-launcher-mode:not(.active):hover {
|
|
1465
|
+
border-color: rgba(65, 105, 225, 0.68);
|
|
1466
|
+
background: rgba(65, 105, 225, 0.06);
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
.terminals-launcher-mode.is-danger.active {
|
|
1470
|
+
border-color: rgba(220, 38, 38, 0.72);
|
|
1471
|
+
background: rgba(220, 38, 38, 0.13);
|
|
1472
|
+
color: rgba(127, 29, 29, 0.96);
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
.terminals-launcher-mode.is-danger:not(.active):hover {
|
|
1476
|
+
border-color: rgba(220, 38, 38, 0.68);
|
|
1477
|
+
background: rgba(220, 38, 38, 0.08);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
body.dark .terminals-launcher-mode.active {
|
|
1481
|
+
border-color: rgba(95, 130, 235, 0.75);
|
|
1482
|
+
background: rgba(95, 130, 235, 0.14);
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
body.dark .terminals-launcher-mode.is-danger.active {
|
|
1486
|
+
border-color: rgba(248, 113, 113, 0.74);
|
|
1487
|
+
background: rgba(248, 113, 113, 0.16);
|
|
1488
|
+
color: rgba(254, 226, 226, 0.95);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1431
1491
|
.terminals-launcher-provider {
|
|
1432
1492
|
display: inline-flex;
|
|
1433
1493
|
align-items: center;
|
|
@@ -2899,6 +2959,23 @@ body.dark .terminals-workspace-create-input.swal2-input {
|
|
|
2899
2959
|
padding: 0 !important;
|
|
2900
2960
|
}
|
|
2901
2961
|
|
|
2962
|
+
.terminals-workspace-create-actions.swal2-actions.swal2-loading {
|
|
2963
|
+
justify-content: flex-end !important;
|
|
2964
|
+
gap: 8px !important;
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
.terminals-workspace-create-actions.swal2-actions .swal2-loader {
|
|
2968
|
+
width: 18px !important;
|
|
2969
|
+
height: 18px !important;
|
|
2970
|
+
margin: 0 !important;
|
|
2971
|
+
border-width: 2px !important;
|
|
2972
|
+
border-color: #3b82f6 rgba(0, 0, 0, 0) #3b82f6 rgba(0, 0, 0, 0) !important;
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
body.dark .terminals-workspace-create-actions.swal2-actions .swal2-loader {
|
|
2976
|
+
border-color: #60a5fa rgba(0, 0, 0, 0) #60a5fa rgba(0, 0, 0, 0) !important;
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2902
2979
|
.terminals-workspace-create-validation.swal2-validation-message {
|
|
2903
2980
|
margin-top: 8px !important;
|
|
2904
2981
|
border-radius: 4px !important;
|
|
@@ -4273,6 +4350,19 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
4273
4350
|
<div class="terminals-launcher-provider-options" role="group" aria-label="CLI providers"></div>
|
|
4274
4351
|
</div>
|
|
4275
4352
|
</div>
|
|
4353
|
+
<div class="terminals-launcher-main-row">
|
|
4354
|
+
<div class="terminals-launcher-main-label">
|
|
4355
|
+
<div class="terminals-launcher-main-label-title">Mode</div>
|
|
4356
|
+
<div class="terminals-launcher-main-label-subtitle">Execution policy</div>
|
|
4357
|
+
</div>
|
|
4358
|
+
<div class="terminals-launcher-main-value">
|
|
4359
|
+
<div class="terminals-launcher-mode-options" role="group" aria-label="Launch mode">
|
|
4360
|
+
<button class="terminals-launcher-mode" type="button" data-launch-mode="guarded">Guarded</button>
|
|
4361
|
+
<button class="terminals-launcher-mode is-danger" type="button" data-launch-mode="yolo">YOLO</button>
|
|
4362
|
+
</div>
|
|
4363
|
+
<span class="terminals-launcher-row-meta terminals-launcher-mode-meta"></span>
|
|
4364
|
+
</div>
|
|
4365
|
+
</div>
|
|
4276
4366
|
<div class="terminals-launcher-main-row">
|
|
4277
4367
|
<div class="terminals-launcher-main-label">
|
|
4278
4368
|
<div class="terminals-launcher-main-label-title">Skills</div>
|
|
@@ -4374,6 +4464,8 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
4374
4464
|
const launcherSearchForm = launcherModal ? launcherModal.querySelector(".terminals-launcher-search-form") : null
|
|
4375
4465
|
const launcherSearchInput = launcherModal ? launcherModal.querySelector(".terminals-launcher-search") : null
|
|
4376
4466
|
const launcherProviderOptions = launcherModal ? launcherModal.querySelector(".terminals-launcher-provider-options") : null
|
|
4467
|
+
const launcherModeOptions = launcherModal ? launcherModal.querySelector(".terminals-launcher-mode-options") : null
|
|
4468
|
+
const launcherModeMeta = launcherModal ? launcherModal.querySelector(".terminals-launcher-mode-meta") : null
|
|
4377
4469
|
const launcherAddSkillsButton = launcherModal ? launcherModal.querySelector(".terminals-launcher-add-skills") : null
|
|
4378
4470
|
const launcherAddFilesButton = launcherModal ? launcherModal.querySelector(".terminals-launcher-add-files") : null
|
|
4379
4471
|
const launcherBackButton = launcherModal ? launcherModal.querySelector(".terminals-launcher-back") : null
|
|
@@ -4387,12 +4479,15 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
4387
4479
|
const launcherCloseButton = launcherModal ? launcherModal.querySelector(".terminals-launcher-close") : null
|
|
4388
4480
|
const launcherFooter = launcherModal ? launcherModal.querySelector(".terminals-launcher-footer") : null
|
|
4389
4481
|
const launcherStartButton = launcherModal ? launcherModal.querySelector(".terminals-launcher-start") : null
|
|
4482
|
+
const LAUNCH_MODE_GUARDED = "guarded"
|
|
4483
|
+
const LAUNCH_MODE_YOLO = "yolo"
|
|
4390
4484
|
const launcherState = {
|
|
4391
4485
|
open: false,
|
|
4392
4486
|
busy: false,
|
|
4393
4487
|
column: null,
|
|
4394
4488
|
workspaceCwd: "",
|
|
4395
4489
|
provider: String(startProviders && startProviders[0] && startProviders[0].key ? startProviders[0].key : "codex").trim().toLowerCase(),
|
|
4490
|
+
launchMode: LAUNCH_MODE_GUARDED,
|
|
4396
4491
|
view: "main",
|
|
4397
4492
|
query: "",
|
|
4398
4493
|
selectedSkills: new Set(),
|
|
@@ -4432,6 +4527,9 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
4432
4527
|
let sessionNextCursor = 0
|
|
4433
4528
|
let sessionAppendInProgress = false
|
|
4434
4529
|
let currentSessionQuery = ""
|
|
4530
|
+
let lastSessionRefreshWorkspaceKey = ""
|
|
4531
|
+
let lastSessionRefreshQuery = ""
|
|
4532
|
+
let autoLauncherPromptedWorkspaceKey = ""
|
|
4435
4533
|
let sessionSnapshotVersion = 0
|
|
4436
4534
|
let sessionSearchDebounceTimer = null
|
|
4437
4535
|
let sessionFetchAbortController = null
|
|
@@ -4993,6 +5091,16 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
4993
5091
|
const normalizeProviderKey = (value) => {
|
|
4994
5092
|
return String(value || "").trim().toLowerCase()
|
|
4995
5093
|
}
|
|
5094
|
+
const normalizeLaunchMode = (value, fallback = LAUNCH_MODE_GUARDED) => {
|
|
5095
|
+
const normalized = String(value || "").trim().toLowerCase()
|
|
5096
|
+
if (normalized === LAUNCH_MODE_YOLO || normalized === "danger" || normalized === "dangerous" || normalized === "true-yolo") {
|
|
5097
|
+
return LAUNCH_MODE_YOLO
|
|
5098
|
+
}
|
|
5099
|
+
if (normalized === LAUNCH_MODE_GUARDED || normalized === "default" || normalized === "safe" || normalized === "standard") {
|
|
5100
|
+
return LAUNCH_MODE_GUARDED
|
|
5101
|
+
}
|
|
5102
|
+
return fallback === LAUNCH_MODE_YOLO ? LAUNCH_MODE_YOLO : LAUNCH_MODE_GUARDED
|
|
5103
|
+
}
|
|
4996
5104
|
const removeTemporarySessionByTerminalId = (terminalId) => {
|
|
4997
5105
|
const normalizedTerminalId = normalizeTerminalId(terminalId)
|
|
4998
5106
|
if (!normalizedTerminalId) {
|
|
@@ -5198,8 +5306,12 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5198
5306
|
}
|
|
5199
5307
|
const setWorkspaceViewMode = (mode, workspaceKey = "") => {
|
|
5200
5308
|
const normalizedMode = mode === "sessions" ? "sessions" : "workspaces"
|
|
5309
|
+
const normalizedWorkspaceKey = normalizedMode === "sessions" ? normalizeCwdKey(workspaceKey) : ""
|
|
5201
5310
|
workspaceViewState.mode = normalizedMode
|
|
5202
|
-
workspaceViewState.key =
|
|
5311
|
+
workspaceViewState.key = normalizedWorkspaceKey
|
|
5312
|
+
if (autoLauncherPromptedWorkspaceKey && (normalizedMode !== "sessions" || normalizedWorkspaceKey !== autoLauncherPromptedWorkspaceKey)) {
|
|
5313
|
+
autoLauncherPromptedWorkspaceKey = ""
|
|
5314
|
+
}
|
|
5203
5315
|
if (sessionSearchInput) {
|
|
5204
5316
|
sessionSearchInput.placeholder = normalizedMode === "sessions" ? "Search sessions" : "Search workspaces"
|
|
5205
5317
|
}
|
|
@@ -5240,12 +5352,18 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5240
5352
|
const renderLauncherSummary = () => {
|
|
5241
5353
|
const skillCount = launcherState.selectedSkills.size
|
|
5242
5354
|
const fileCount = launcherState.pendingFiles.length
|
|
5355
|
+
const launchMode = normalizeLaunchMode(launcherState.launchMode, LAUNCH_MODE_GUARDED)
|
|
5243
5356
|
if (launcherSummarySkills) {
|
|
5244
5357
|
launcherSummarySkills.textContent = `Skills: ${skillCount}`
|
|
5245
5358
|
}
|
|
5246
5359
|
if (launcherSummaryFiles) {
|
|
5247
5360
|
launcherSummaryFiles.textContent = `Files: ${fileCount}`
|
|
5248
5361
|
}
|
|
5362
|
+
if (launcherModeMeta) {
|
|
5363
|
+
launcherModeMeta.textContent = launchMode === LAUNCH_MODE_YOLO
|
|
5364
|
+
? "YOLO: run without approvals"
|
|
5365
|
+
: "Guarded: provider default approval/sandbox."
|
|
5366
|
+
}
|
|
5249
5367
|
}
|
|
5250
5368
|
|
|
5251
5369
|
const setLauncherBusy = (busy) => {
|
|
@@ -5280,6 +5398,12 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5280
5398
|
button.disabled = launcherState.busy
|
|
5281
5399
|
})
|
|
5282
5400
|
}
|
|
5401
|
+
if (launcherModeOptions) {
|
|
5402
|
+
const modeButtons = launcherModeOptions.querySelectorAll(".terminals-launcher-mode")
|
|
5403
|
+
modeButtons.forEach((button) => {
|
|
5404
|
+
button.disabled = launcherState.busy
|
|
5405
|
+
})
|
|
5406
|
+
}
|
|
5283
5407
|
if (launcherSkillList) {
|
|
5284
5408
|
const skillButtons = launcherSkillList.querySelectorAll(".terminals-launcher-skill-row")
|
|
5285
5409
|
skillButtons.forEach((button) => {
|
|
@@ -5447,6 +5571,29 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5447
5571
|
}
|
|
5448
5572
|
}
|
|
5449
5573
|
|
|
5574
|
+
const renderLauncherModeOptions = () => {
|
|
5575
|
+
if (!launcherModeOptions) {
|
|
5576
|
+
return
|
|
5577
|
+
}
|
|
5578
|
+
launcherState.launchMode = normalizeLaunchMode(launcherState.launchMode, LAUNCH_MODE_GUARDED)
|
|
5579
|
+
const modeButtons = launcherModeOptions.querySelectorAll(".terminals-launcher-mode")
|
|
5580
|
+
modeButtons.forEach((button) => {
|
|
5581
|
+
const mode = normalizeLaunchMode(button && button.dataset ? button.dataset.launchMode : "", LAUNCH_MODE_GUARDED)
|
|
5582
|
+
const isActive = mode === launcherState.launchMode
|
|
5583
|
+
button.classList.toggle("active", isActive)
|
|
5584
|
+
button.setAttribute("aria-pressed", isActive ? "true" : "false")
|
|
5585
|
+
button.disabled = launcherState.busy
|
|
5586
|
+
button.onclick = () => {
|
|
5587
|
+
if (launcherState.busy) {
|
|
5588
|
+
return
|
|
5589
|
+
}
|
|
5590
|
+
launcherState.launchMode = mode
|
|
5591
|
+
renderLauncherModeOptions()
|
|
5592
|
+
}
|
|
5593
|
+
})
|
|
5594
|
+
renderLauncherSummary()
|
|
5595
|
+
}
|
|
5596
|
+
|
|
5450
5597
|
const renderLauncherSkillList = () => {
|
|
5451
5598
|
if (!launcherSkillList) {
|
|
5452
5599
|
return
|
|
@@ -5606,6 +5753,7 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5606
5753
|
}
|
|
5607
5754
|
setLauncherView("main")
|
|
5608
5755
|
renderLauncherProviderOptions()
|
|
5756
|
+
renderLauncherModeOptions()
|
|
5609
5757
|
renderLauncherSelectedChips()
|
|
5610
5758
|
renderLauncherSkillList()
|
|
5611
5759
|
renderLauncherFiles()
|
|
@@ -5634,6 +5782,7 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5634
5782
|
if (!workspaceCwd) {
|
|
5635
5783
|
return
|
|
5636
5784
|
}
|
|
5785
|
+
const launchMode = normalizeLaunchMode(launcherState.launchMode, LAUNCH_MODE_GUARDED)
|
|
5637
5786
|
const selectedSkillIds = Array.from(launcherState.selectedSkills)
|
|
5638
5787
|
setLauncherBusy(true)
|
|
5639
5788
|
let shouldClose = false
|
|
@@ -5643,7 +5792,7 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
5643
5792
|
const uploaded = await uploadLauncherFiles()
|
|
5644
5793
|
uploadToken = uploaded && uploaded.uploadToken ? uploaded.uploadToken : ""
|
|
5645
5794
|
}
|
|
5646
|
-
const started = await startProviderSession(column, provider, launcherStartButton, null, selectedSkillIds, uploadToken, workspaceCwd)
|
|
5795
|
+
const started = await startProviderSession(column, provider, launchMode, launcherStartButton, null, selectedSkillIds, uploadToken, workspaceCwd)
|
|
5647
5796
|
if (started) {
|
|
5648
5797
|
launcherState.pendingFiles = []
|
|
5649
5798
|
renderLauncherFiles()
|
|
@@ -8043,6 +8192,8 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
8043
8192
|
if (incomingSnapshotVersion > sessionSnapshotVersion) {
|
|
8044
8193
|
sessionSnapshotVersion = incomingSnapshotVersion
|
|
8045
8194
|
}
|
|
8195
|
+
lastSessionRefreshWorkspaceKey = workspaceScopeKey
|
|
8196
|
+
lastSessionRefreshQuery = currentSessionQuery
|
|
8046
8197
|
requestSucceeded = true
|
|
8047
8198
|
return true
|
|
8048
8199
|
} catch (error) {
|
|
@@ -8112,8 +8263,9 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
8112
8263
|
}
|
|
8113
8264
|
void loadMoreSessionItems()
|
|
8114
8265
|
}
|
|
8115
|
-
const startProviderSession = async (column, providerKey, startButton, providerSelect, selectedSkillIds = [], uploadToken = "", workspacePath = "") => {
|
|
8266
|
+
const startProviderSession = async (column, providerKey, launchMode = LAUNCH_MODE_GUARDED, startButton, providerSelect, selectedSkillIds = [], uploadToken = "", workspacePath = "") => {
|
|
8116
8267
|
const normalizedProvider = normalizeIndex(providerKey).toLowerCase()
|
|
8268
|
+
const normalizedLaunchMode = normalizeLaunchMode(launchMode, LAUNCH_MODE_GUARDED)
|
|
8117
8269
|
if (!normalizedProvider) {
|
|
8118
8270
|
return false
|
|
8119
8271
|
}
|
|
@@ -8131,6 +8283,7 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
8131
8283
|
},
|
|
8132
8284
|
body: JSON.stringify({
|
|
8133
8285
|
provider: normalizedProvider,
|
|
8286
|
+
launchMode: normalizedLaunchMode,
|
|
8134
8287
|
skills: Array.isArray(selectedSkillIds) ? selectedSkillIds : [],
|
|
8135
8288
|
uploadToken: typeof uploadToken === "string" ? uploadToken : "",
|
|
8136
8289
|
workspacePath: typeof workspacePath === "string" ? workspacePath : ""
|
|
@@ -8794,6 +8947,56 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
8794
8947
|
}
|
|
8795
8948
|
}
|
|
8796
8949
|
|
|
8950
|
+
const maybeAutoOpenLauncherForEmptyWorkspace = () => {
|
|
8951
|
+
if (launcherState.open || launcherState.busy) {
|
|
8952
|
+
return false
|
|
8953
|
+
}
|
|
8954
|
+
if (workspaceViewState.mode !== "sessions") {
|
|
8955
|
+
return false
|
|
8956
|
+
}
|
|
8957
|
+
if (!hasAttemptedSessionLoad || lastSessionLoadFailed) {
|
|
8958
|
+
return false
|
|
8959
|
+
}
|
|
8960
|
+
const workspaceKey = normalizeCwdKey(workspaceViewState.key)
|
|
8961
|
+
if (!workspaceKey) {
|
|
8962
|
+
return false
|
|
8963
|
+
}
|
|
8964
|
+
if (autoLauncherPromptedWorkspaceKey === workspaceKey) {
|
|
8965
|
+
return false
|
|
8966
|
+
}
|
|
8967
|
+
if (normalizeCwdKey(lastSessionRefreshWorkspaceKey) !== workspaceKey) {
|
|
8968
|
+
return false
|
|
8969
|
+
}
|
|
8970
|
+
if (normalizeIndex(lastSessionRefreshQuery).trim().length > 0) {
|
|
8971
|
+
return false
|
|
8972
|
+
}
|
|
8973
|
+
const workspace = getCurrentWorkspaceItem()
|
|
8974
|
+
const workspaceSessions = workspace && Array.isArray(workspace.sessions) ? workspace.sessions : []
|
|
8975
|
+
if (!workspace || workspaceSessions.length > 0) {
|
|
8976
|
+
return false
|
|
8977
|
+
}
|
|
8978
|
+
const chooser = getOrCreateChooserColumn()
|
|
8979
|
+
if (!chooser) {
|
|
8980
|
+
return false
|
|
8981
|
+
}
|
|
8982
|
+
const workspacePath = workspace && workspace.cwd ? workspace.cwd : workspaceKey
|
|
8983
|
+
autoLauncherPromptedWorkspaceKey = workspaceKey
|
|
8984
|
+
requestAnimationFrame(() => {
|
|
8985
|
+
if (launcherState.open || launcherState.busy) {
|
|
8986
|
+
return
|
|
8987
|
+
}
|
|
8988
|
+
if (workspaceViewState.mode !== "sessions" || normalizeCwdKey(workspaceViewState.key) !== workspaceKey) {
|
|
8989
|
+
return
|
|
8990
|
+
}
|
|
8991
|
+
const liveChooser = getOrCreateChooserColumn()
|
|
8992
|
+
if (!liveChooser || !liveChooser.isConnected || liveChooser.dataset.state !== "chooser") {
|
|
8993
|
+
return
|
|
8994
|
+
}
|
|
8995
|
+
openLauncherModal(liveChooser, workspacePath)
|
|
8996
|
+
})
|
|
8997
|
+
return true
|
|
8998
|
+
}
|
|
8999
|
+
|
|
8797
9000
|
const refreshChooserRows = (options = {}) => {
|
|
8798
9001
|
renderChooserTopBar()
|
|
8799
9002
|
const query = getSessionSearchQuery()
|
|
@@ -8805,6 +9008,7 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
8805
9008
|
maybeLoadMoreSessionsForColumn(chooserColumn)
|
|
8806
9009
|
}
|
|
8807
9010
|
})
|
|
9011
|
+
maybeAutoOpenLauncherForEmptyWorkspace()
|
|
8808
9012
|
}
|
|
8809
9013
|
|
|
8810
9014
|
const setupChooserColumn = (column, showClose = false, refreshOptions = null) => {
|
|
@@ -9189,6 +9393,55 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
9189
9393
|
workspaceFolders = next
|
|
9190
9394
|
}
|
|
9191
9395
|
|
|
9396
|
+
const finalizeCreatedWorkspace = (createdWorkspace, fallbackName) => {
|
|
9397
|
+
const workspaceCwd = createdWorkspace && typeof createdWorkspace.cwd === "string"
|
|
9398
|
+
? String(createdWorkspace.cwd)
|
|
9399
|
+
: ""
|
|
9400
|
+
const workspaceKey = normalizeCwdKey(workspaceCwd)
|
|
9401
|
+
if (!workspaceKey) {
|
|
9402
|
+
return false
|
|
9403
|
+
}
|
|
9404
|
+
addWorkspaceToLocalList({
|
|
9405
|
+
name: createdWorkspace && createdWorkspace.folder ? createdWorkspace.folder : fallbackName,
|
|
9406
|
+
cwd: workspaceCwd
|
|
9407
|
+
})
|
|
9408
|
+
if (sessionSearchInput) {
|
|
9409
|
+
sessionSearchInput.value = ""
|
|
9410
|
+
}
|
|
9411
|
+
setWorkspaceViewMode("sessions", workspaceKey)
|
|
9412
|
+
refreshChooserRows()
|
|
9413
|
+
const workspacePath = workspaceCwd || workspaceKey
|
|
9414
|
+
if (!launcherState.open && !launcherState.busy) {
|
|
9415
|
+
autoLauncherPromptedWorkspaceKey = workspaceKey
|
|
9416
|
+
requestAnimationFrame(() => {
|
|
9417
|
+
if (launcherState.open || launcherState.busy) {
|
|
9418
|
+
return
|
|
9419
|
+
}
|
|
9420
|
+
if (workspaceViewState.mode !== "sessions" || normalizeCwdKey(workspaceViewState.key) !== workspaceKey) {
|
|
9421
|
+
return
|
|
9422
|
+
}
|
|
9423
|
+
const liveChooser = getOrCreateChooserColumn()
|
|
9424
|
+
if (!liveChooser || !liveChooser.isConnected || liveChooser.dataset.state !== "chooser") {
|
|
9425
|
+
return
|
|
9426
|
+
}
|
|
9427
|
+
openLauncherModal(liveChooser, workspacePath)
|
|
9428
|
+
})
|
|
9429
|
+
}
|
|
9430
|
+
const refreshPromise = refreshSessionItems({
|
|
9431
|
+
sync: true,
|
|
9432
|
+
query: "",
|
|
9433
|
+
workspaceKey
|
|
9434
|
+
}).then((loaded) => {
|
|
9435
|
+
refreshChooserRows()
|
|
9436
|
+
return Boolean(loaded)
|
|
9437
|
+
}).catch(() => {
|
|
9438
|
+
refreshChooserRows()
|
|
9439
|
+
return false
|
|
9440
|
+
})
|
|
9441
|
+
void refreshPromise
|
|
9442
|
+
return true
|
|
9443
|
+
}
|
|
9444
|
+
|
|
9192
9445
|
const openCreateWorkspaceModal = async () => {
|
|
9193
9446
|
const suggested = await suggestWorkspaceName()
|
|
9194
9447
|
let defaultName = suggested || `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`
|
|
@@ -9211,25 +9464,14 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
9211
9464
|
if (!folderName) {
|
|
9212
9465
|
return false
|
|
9213
9466
|
}
|
|
9467
|
+
if (folderName.includes(" ")) {
|
|
9468
|
+
window.alert("Workspace name cannot contain spaces.")
|
|
9469
|
+
return false
|
|
9470
|
+
}
|
|
9214
9471
|
try {
|
|
9215
9472
|
const payload = await createWorkspace(folderName)
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
cwd: payload.cwd || ""
|
|
9219
|
-
})
|
|
9220
|
-
if (sessionSearchInput) {
|
|
9221
|
-
sessionSearchInput.value = ""
|
|
9222
|
-
}
|
|
9223
|
-
setWorkspaceViewMode("sessions", normalizeCwdKey(payload.cwd || ""))
|
|
9224
|
-
refreshChooserRows()
|
|
9225
|
-
void refreshSessionItems({
|
|
9226
|
-
sync: true,
|
|
9227
|
-
query: "",
|
|
9228
|
-
workspaceKey: normalizeCwdKey(payload.cwd || "")
|
|
9229
|
-
}).then(() => {
|
|
9230
|
-
refreshChooserRows()
|
|
9231
|
-
})
|
|
9232
|
-
return true
|
|
9473
|
+
const finalized = finalizeCreatedWorkspace(payload, folderName)
|
|
9474
|
+
return finalized
|
|
9233
9475
|
} catch (error) {
|
|
9234
9476
|
window.alert(error && error.message ? error.message : "Failed to create workspace.")
|
|
9235
9477
|
return false
|
|
@@ -9262,6 +9504,10 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
9262
9504
|
Swal.showValidationMessage("Enter a workspace folder name.")
|
|
9263
9505
|
return false
|
|
9264
9506
|
}
|
|
9507
|
+
if (folderName.includes(" ")) {
|
|
9508
|
+
Swal.showValidationMessage("Workspace name cannot contain spaces.")
|
|
9509
|
+
return false
|
|
9510
|
+
}
|
|
9265
9511
|
try {
|
|
9266
9512
|
const payload = await createWorkspace(folderName)
|
|
9267
9513
|
return payload
|
|
@@ -9286,23 +9532,8 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
|
|
|
9286
9532
|
return false
|
|
9287
9533
|
}
|
|
9288
9534
|
const created = result.value
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
cwd: created.cwd || ""
|
|
9292
|
-
})
|
|
9293
|
-
if (sessionSearchInput) {
|
|
9294
|
-
sessionSearchInput.value = ""
|
|
9295
|
-
}
|
|
9296
|
-
setWorkspaceViewMode("sessions", normalizeCwdKey(created.cwd || ""))
|
|
9297
|
-
refreshChooserRows()
|
|
9298
|
-
void refreshSessionItems({
|
|
9299
|
-
sync: true,
|
|
9300
|
-
query: "",
|
|
9301
|
-
workspaceKey: normalizeCwdKey(created.cwd || "")
|
|
9302
|
-
}).then(() => {
|
|
9303
|
-
refreshChooserRows()
|
|
9304
|
-
})
|
|
9305
|
-
return true
|
|
9535
|
+
const finalized = finalizeCreatedWorkspace(created, defaultName)
|
|
9536
|
+
return finalized
|
|
9306
9537
|
}
|
|
9307
9538
|
|
|
9308
9539
|
const openCreateWorkspaceFromTopAction = async () => {
|