pinokiod 5.1.10 → 5.1.11
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/api/fs/download_worker.js +158 -0
- package/kernel/api/fs/index.js +95 -91
- package/kernel/api/index.js +3 -0
- package/kernel/bin/index.js +5 -2
- package/kernel/environment.js +19 -2
- package/kernel/git.js +972 -1
- package/kernel/index.js +65 -30
- package/kernel/peer.js +1 -2
- package/kernel/plugin.js +0 -8
- package/kernel/procs.js +92 -36
- package/kernel/prototype.js +45 -22
- package/kernel/shells.js +30 -6
- package/kernel/sysinfo.js +33 -13
- package/kernel/util.js +61 -24
- package/kernel/workspace_status.js +131 -7
- package/package.json +1 -1
- package/pipe/index.js +1 -1
- package/server/index.js +1169 -350
- package/server/public/create-launcher.js +157 -2
- package/server/public/install.js +135 -41
- package/server/public/style.css +32 -1
- package/server/public/tab-link-popover.js +45 -14
- package/server/public/terminal-settings.js +51 -35
- package/server/public/urldropdown.css +89 -3
- package/server/socket.js +12 -7
- package/server/views/agents.ejs +4 -3
- package/server/views/app.ejs +798 -30
- package/server/views/bootstrap.ejs +2 -1
- package/server/views/checkpoints.ejs +1014 -0
- package/server/views/checkpoints_registry_beta.ejs +260 -0
- package/server/views/columns.ejs +4 -4
- package/server/views/connect.ejs +1 -0
- package/server/views/d.ejs +74 -4
- package/server/views/download.ejs +28 -28
- package/server/views/editor.ejs +4 -5
- package/server/views/env_editor.ejs +1 -1
- package/server/views/file_explorer.ejs +1 -1
- package/server/views/index.ejs +3 -1
- package/server/views/init/index.ejs +2 -1
- package/server/views/install.ejs +2 -1
- package/server/views/net.ejs +9 -7
- package/server/views/network.ejs +15 -14
- package/server/views/pro.ejs +5 -2
- package/server/views/prototype/index.ejs +2 -1
- package/server/views/registry_link.ejs +76 -0
- package/server/views/rows.ejs +4 -4
- package/server/views/screenshots.ejs +1 -0
- package/server/views/settings.ejs +1 -0
- package/server/views/shell.ejs +4 -6
- package/server/views/terminal.ejs +528 -38
- package/server/views/tools.ejs +1 -0
- package/undefined/logs/dev/plugin/cursor-agent.git/pinokio.js/1764297248545 +0 -45
- package/undefined/logs/dev/plugin/cursor-agent.git/pinokio.js/1764335557118 +0 -45
- package/undefined/logs/dev/plugin/cursor-agent.git/pinokio.js/1764335834126 +0 -45
- package/undefined/logs/dev/plugin/cursor-agent.git/pinokio.js/events +0 -12
- package/undefined/logs/dev/plugin/cursor-agent.git/pinokio.js/latest +0 -45
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8" />
|
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
5
|
+
<style>
|
|
6
|
+
:root {
|
|
7
|
+
--bg: #f5f5f5;
|
|
8
|
+
--card: #ffffff;
|
|
9
|
+
--text: #0f172a;
|
|
10
|
+
--muted: #64748b;
|
|
11
|
+
--border: rgba(15, 23, 42, 0.08);
|
|
12
|
+
--btn: #111827;
|
|
13
|
+
--btn-text: #ffffff;
|
|
14
|
+
--btn-secondary: #e2e8f0;
|
|
15
|
+
--btn-secondary-text: #0f172a;
|
|
16
|
+
--badge-on: #16a34a;
|
|
17
|
+
--badge-off: #dc2626;
|
|
18
|
+
}
|
|
19
|
+
body.dark {
|
|
20
|
+
--bg: #0b1120;
|
|
21
|
+
--card: #111827;
|
|
22
|
+
--text: #e2e8f0;
|
|
23
|
+
--muted: #94a3b8;
|
|
24
|
+
--border: rgba(148, 163, 184, 0.2);
|
|
25
|
+
--btn: #e2e8f0;
|
|
26
|
+
--btn-text: #0b1120;
|
|
27
|
+
--btn-secondary: #1f2937;
|
|
28
|
+
--btn-secondary-text: #e2e8f0;
|
|
29
|
+
--badge-on: #22c55e;
|
|
30
|
+
--badge-off: #f87171;
|
|
31
|
+
}
|
|
32
|
+
body {
|
|
33
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
34
|
+
background: var(--bg);
|
|
35
|
+
color: var(--text);
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
min-height: 100vh;
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: 24px;
|
|
42
|
+
}
|
|
43
|
+
.card {
|
|
44
|
+
background: var(--card);
|
|
45
|
+
border: 1px solid var(--border);
|
|
46
|
+
border-radius: 16px;
|
|
47
|
+
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.08);
|
|
48
|
+
padding: 28px;
|
|
49
|
+
max-width: 520px;
|
|
50
|
+
width: 100%;
|
|
51
|
+
}
|
|
52
|
+
.title {
|
|
53
|
+
font-size: 22px;
|
|
54
|
+
font-weight: 700;
|
|
55
|
+
margin: 0 0 6px 0;
|
|
56
|
+
}
|
|
57
|
+
.subtitle {
|
|
58
|
+
margin: 0 0 18px 0;
|
|
59
|
+
color: var(--muted);
|
|
60
|
+
font-size: 14px;
|
|
61
|
+
}
|
|
62
|
+
.status-row {
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 12px;
|
|
66
|
+
margin-bottom: 18px;
|
|
67
|
+
}
|
|
68
|
+
.field {
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
gap: 6px;
|
|
72
|
+
margin-bottom: 18px;
|
|
73
|
+
}
|
|
74
|
+
.field label {
|
|
75
|
+
font-size: 13px;
|
|
76
|
+
color: var(--muted);
|
|
77
|
+
text-transform: uppercase;
|
|
78
|
+
letter-spacing: 0.08em;
|
|
79
|
+
}
|
|
80
|
+
.field input {
|
|
81
|
+
border: 1px solid var(--border);
|
|
82
|
+
background: transparent;
|
|
83
|
+
color: var(--text);
|
|
84
|
+
padding: 10px 12px;
|
|
85
|
+
border-radius: 10px;
|
|
86
|
+
font-size: 14px;
|
|
87
|
+
}
|
|
88
|
+
.field-hint {
|
|
89
|
+
font-size: 12px;
|
|
90
|
+
color: var(--muted);
|
|
91
|
+
}
|
|
92
|
+
.status-label {
|
|
93
|
+
font-size: 13px;
|
|
94
|
+
color: var(--muted);
|
|
95
|
+
text-transform: uppercase;
|
|
96
|
+
letter-spacing: 0.08em;
|
|
97
|
+
}
|
|
98
|
+
.status-badge {
|
|
99
|
+
padding: 6px 12px;
|
|
100
|
+
border-radius: 999px;
|
|
101
|
+
font-weight: 600;
|
|
102
|
+
font-size: 12px;
|
|
103
|
+
border: 1px solid transparent;
|
|
104
|
+
}
|
|
105
|
+
.status-badge.enabled {
|
|
106
|
+
color: var(--badge-on);
|
|
107
|
+
border-color: rgba(22, 163, 74, 0.3);
|
|
108
|
+
background: rgba(22, 163, 74, 0.12);
|
|
109
|
+
}
|
|
110
|
+
.status-badge.disabled {
|
|
111
|
+
color: var(--badge-off);
|
|
112
|
+
border-color: rgba(220, 38, 38, 0.3);
|
|
113
|
+
background: rgba(220, 38, 38, 0.12);
|
|
114
|
+
}
|
|
115
|
+
.actions {
|
|
116
|
+
display: flex;
|
|
117
|
+
gap: 10px;
|
|
118
|
+
flex-wrap: wrap;
|
|
119
|
+
}
|
|
120
|
+
.btn {
|
|
121
|
+
border: none;
|
|
122
|
+
border-radius: 10px;
|
|
123
|
+
padding: 10px 16px;
|
|
124
|
+
font-weight: 600;
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
transition: transform 0.05s ease, opacity 0.15s ease;
|
|
127
|
+
}
|
|
128
|
+
.btn:disabled {
|
|
129
|
+
opacity: 0.6;
|
|
130
|
+
cursor: not-allowed;
|
|
131
|
+
}
|
|
132
|
+
.btn:active {
|
|
133
|
+
transform: translateY(1px);
|
|
134
|
+
}
|
|
135
|
+
.btn-primary {
|
|
136
|
+
background: var(--btn);
|
|
137
|
+
color: var(--btn-text);
|
|
138
|
+
}
|
|
139
|
+
.btn-secondary {
|
|
140
|
+
background: var(--btn-secondary);
|
|
141
|
+
color: var(--btn-secondary-text);
|
|
142
|
+
}
|
|
143
|
+
.note {
|
|
144
|
+
margin-top: 16px;
|
|
145
|
+
font-size: 13px;
|
|
146
|
+
color: var(--muted);
|
|
147
|
+
}
|
|
148
|
+
.message {
|
|
149
|
+
margin-top: 10px;
|
|
150
|
+
font-size: 13px;
|
|
151
|
+
min-height: 18px;
|
|
152
|
+
}
|
|
153
|
+
.message.success {
|
|
154
|
+
color: var(--badge-on);
|
|
155
|
+
}
|
|
156
|
+
.message.error {
|
|
157
|
+
color: var(--badge-off);
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
160
|
+
</head>
|
|
161
|
+
<body class="<%= theme %>" data-agent="<%= agent %>">
|
|
162
|
+
<div class="card">
|
|
163
|
+
<div class="title">Registry Beta</div>
|
|
164
|
+
<div class="subtitle">Enable or disable registry publish features for this Pinokio install.</div>
|
|
165
|
+
<div class="status-row">
|
|
166
|
+
<div class="status-label">Status</div>
|
|
167
|
+
<div
|
|
168
|
+
id="registry-beta-status"
|
|
169
|
+
class="status-badge <%= registryBetaEnabled ? 'enabled' : 'disabled' %>"
|
|
170
|
+
data-enabled="<%= registryBetaEnabled ? '1' : '0' %>"
|
|
171
|
+
>
|
|
172
|
+
<%= registryBetaEnabled ? 'Enabled' : 'Disabled' %>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="field">
|
|
176
|
+
<label for="registry-connect-url">Registry connect URL</label>
|
|
177
|
+
<input
|
|
178
|
+
id="registry-connect-url"
|
|
179
|
+
type="url"
|
|
180
|
+
placeholder="http://localhost:3000/connect/pinokio"
|
|
181
|
+
value="<%= registryUrlPrefill || registryConnectUrl || '' %>"
|
|
182
|
+
autocomplete="off"
|
|
183
|
+
/>
|
|
184
|
+
<div class="field-hint">Used for connect prompts and published links.</div>
|
|
185
|
+
</div>
|
|
186
|
+
<div class="actions">
|
|
187
|
+
<button id="registry-beta-enable" class="btn btn-primary" type="button">Enable</button>
|
|
188
|
+
<button id="registry-beta-disable" class="btn btn-secondary" type="button">Disable</button>
|
|
189
|
+
</div>
|
|
190
|
+
<div class="note">Writes PINOKIO_REGISTRY_BETA and PINOKIO_REGISTRY_CONNECT_URL in ENVIRONMENT. Reload other pages to see changes.</div>
|
|
191
|
+
<div id="registry-beta-message" class="message" aria-live="polite"></div>
|
|
192
|
+
</div>
|
|
193
|
+
<script>
|
|
194
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
195
|
+
const statusEl = document.getElementById("registry-beta-status")
|
|
196
|
+
const messageEl = document.getElementById("registry-beta-message")
|
|
197
|
+
const enableBtn = document.getElementById("registry-beta-enable")
|
|
198
|
+
const disableBtn = document.getElementById("registry-beta-disable")
|
|
199
|
+
const connectInput = document.getElementById("registry-connect-url")
|
|
200
|
+
if (!statusEl || !enableBtn || !disableBtn) return
|
|
201
|
+
|
|
202
|
+
let enabled = statusEl.getAttribute("data-enabled") === "1"
|
|
203
|
+
|
|
204
|
+
const setMessage = (text, isError) => {
|
|
205
|
+
if (!messageEl) return
|
|
206
|
+
messageEl.textContent = text || ""
|
|
207
|
+
messageEl.classList.toggle("error", !!isError)
|
|
208
|
+
messageEl.classList.toggle("success", !isError && !!text)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const setState = (next) => {
|
|
212
|
+
enabled = !!next
|
|
213
|
+
statusEl.textContent = enabled ? "Enabled" : "Disabled"
|
|
214
|
+
statusEl.setAttribute("data-enabled", enabled ? "1" : "0")
|
|
215
|
+
statusEl.classList.toggle("enabled", enabled)
|
|
216
|
+
statusEl.classList.toggle("disabled", !enabled)
|
|
217
|
+
enableBtn.textContent = enabled ? "Save" : "Enable"
|
|
218
|
+
enableBtn.disabled = false
|
|
219
|
+
disableBtn.disabled = !enabled
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const update = async (next, includeEndpoint) => {
|
|
223
|
+
setMessage("")
|
|
224
|
+
enableBtn.disabled = true
|
|
225
|
+
disableBtn.disabled = true
|
|
226
|
+
try {
|
|
227
|
+
const connectUrl = connectInput ? String(connectInput.value || "").trim() : ""
|
|
228
|
+
const res = await fetch("/checkpoints/registry_beta", {
|
|
229
|
+
method: "POST",
|
|
230
|
+
headers: {
|
|
231
|
+
"Content-Type": "application/json",
|
|
232
|
+
"Accept": "application/json"
|
|
233
|
+
},
|
|
234
|
+
body: JSON.stringify({
|
|
235
|
+
enabled: next ? "1" : "0",
|
|
236
|
+
...(includeEndpoint ? { connectUrl } : {})
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
const payload = res.ok ? await res.json().catch(() => null) : null
|
|
240
|
+
if (!payload || !payload.ok) {
|
|
241
|
+
throw new Error("Update failed")
|
|
242
|
+
}
|
|
243
|
+
setState(!!payload.enabled)
|
|
244
|
+
setMessage("Updated.")
|
|
245
|
+
} catch (_) {
|
|
246
|
+
setState(enabled)
|
|
247
|
+
setMessage("Could not update setting.", true)
|
|
248
|
+
} finally {
|
|
249
|
+
enableBtn.disabled = enabled
|
|
250
|
+
disableBtn.disabled = !enabled
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
setState(enabled)
|
|
255
|
+
enableBtn.addEventListener("click", () => update(true, true))
|
|
256
|
+
disableBtn.addEventListener("click", () => update(false, true))
|
|
257
|
+
})
|
|
258
|
+
</script>
|
|
259
|
+
</body>
|
|
260
|
+
</html>
|
package/server/views/columns.ejs
CHANGED
|
@@ -62,9 +62,9 @@ body[data-agent='electron'] {
|
|
|
62
62
|
<script src="/window_storage.js"></script>
|
|
63
63
|
</head>
|
|
64
64
|
<body class='<%=theme%>' data-agent="<%=agent%>">
|
|
65
|
-
<iframe id='col0' data-src="<%= originSrc || '/' %>"></iframe>
|
|
65
|
+
<iframe id='col0' data-src="<%= originSrc || '/home' %>"></iframe>
|
|
66
66
|
<div id="gutter" class="gutter" tabindex="0" role="separator" aria-orientation="vertical" aria-label="Resize panels" aria-valuemin="120" aria-valuemax="0" aria-valuenow="0"></div>
|
|
67
|
-
<iframe id='col1' data-src="<%= targetSrc || originSrc || '/' %>"></iframe>
|
|
67
|
+
<iframe id='col1' data-src="<%= targetSrc || originSrc || '/home' %>"></iframe>
|
|
68
68
|
|
|
69
69
|
<script>
|
|
70
70
|
if (window !== window.top) {
|
|
@@ -201,7 +201,7 @@ body[data-agent='electron'] {
|
|
|
201
201
|
}, "*")
|
|
202
202
|
} else {
|
|
203
203
|
// if this is the top window, everything has been removed, so just redirect to home
|
|
204
|
-
location.href = "/"
|
|
204
|
+
location.href = "/home"
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
}
|
|
@@ -325,7 +325,7 @@ body[data-agent='electron'] {
|
|
|
325
325
|
|
|
326
326
|
if (!sourceFrameId) {
|
|
327
327
|
windowStorage.removeItem(splitKey)
|
|
328
|
-
location.href = "/"
|
|
328
|
+
location.href = "/home"
|
|
329
329
|
return
|
|
330
330
|
}
|
|
331
331
|
|
package/server/views/connect.ejs
CHANGED
|
@@ -926,6 +926,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
926
926
|
<a href="/connect" class='tab selected'><i class="fa-solid fa-plug"></i><div class='caption'>Login</div></a>
|
|
927
927
|
<a class='tab' href="<%=portal%>" target="_blank"><i class="fa-solid fa-question"></i><div class='caption'>Help</div></a>
|
|
928
928
|
<a class='tab' id='genlog' href="/logs"><i class="fa-solid fa-laptop-code"></i><div class='caption'>Logs</div></a>
|
|
929
|
+
<a class='tab' href="/checkpoints"><i class="fa-solid fa-clock-rotate-left"></i><div class='caption'>Checkpoints</div></a>
|
|
929
930
|
<a class='tab' href="/screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
|
|
930
931
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
931
932
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
package/server/views/d.ejs
CHANGED
|
@@ -131,6 +131,27 @@ body.dark .tab:hover .disclosure-indicator,
|
|
|
131
131
|
body.dark .tab:focus-visible .disclosure-indicator {
|
|
132
132
|
color: rgba(255, 255, 255, 0.9);
|
|
133
133
|
}
|
|
134
|
+
.ai-perm-link {
|
|
135
|
+
border: none;
|
|
136
|
+
background: none;
|
|
137
|
+
color: rgba(0, 0, 0, 0.55);
|
|
138
|
+
padding: 6px;
|
|
139
|
+
border-radius: 8px;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
}
|
|
142
|
+
.ai-perm-link:hover,
|
|
143
|
+
.ai-perm-link:focus-visible {
|
|
144
|
+
background: rgba(0, 0, 0, 0.08);
|
|
145
|
+
color: rgba(0, 0, 0, 0.85);
|
|
146
|
+
}
|
|
147
|
+
body.dark .ai-perm-link {
|
|
148
|
+
color: rgba(255, 255, 255, 0.75);
|
|
149
|
+
}
|
|
150
|
+
body.dark .ai-perm-link:hover,
|
|
151
|
+
body.dark .ai-perm-link:focus-visible {
|
|
152
|
+
background: rgba(255, 255, 255, 0.12);
|
|
153
|
+
color: rgba(255, 255, 255, 0.95);
|
|
154
|
+
}
|
|
134
155
|
/*
|
|
135
156
|
body.dark .tab i {
|
|
136
157
|
background: rgba(0,0,0,0.1);
|
|
@@ -444,8 +465,11 @@ body.dark #update-spec {
|
|
|
444
465
|
<% } %>
|
|
445
466
|
<div class='flexible'></div>
|
|
446
467
|
<% if (i.link) { %>
|
|
447
|
-
<div target="_blank" data-href="<%= i.link %>"><i class="fa-solid fa-circle-info"></i></div>
|
|
468
|
+
<div target="_blank" data-href="<%= i.link %>" title="Open docs" data-tippy-content="Open docs"><i class="fa-solid fa-circle-info"></i></div>
|
|
448
469
|
<% } %>
|
|
470
|
+
<button class="ai-perm-link" type="button" data-ai-consent="<%= i.href %>" title="AI permissions" data-tippy-content="AI permissions">
|
|
471
|
+
<i class="fa-solid fa-shield-halved"></i>
|
|
472
|
+
</button>
|
|
449
473
|
<div class='disclosure-indicator' aria-hidden="true">
|
|
450
474
|
<i class="fa-solid fa-chevron-right"></i>
|
|
451
475
|
</div>
|
|
@@ -477,8 +501,11 @@ body.dark #update-spec {
|
|
|
477
501
|
<% } %>
|
|
478
502
|
<div class='flexible'></div>
|
|
479
503
|
<% if (i.link) { %>
|
|
480
|
-
<div target="_blank" data-href="<%= i.link %>"><i class="fa-solid fa-circle-info"></i></div>
|
|
504
|
+
<div target="_blank" data-href="<%= i.link %>" title="Open docs" data-tippy-content="Open docs"><i class="fa-solid fa-circle-info"></i></div>
|
|
481
505
|
<% } %>
|
|
506
|
+
<button class="ai-perm-link" type="button" data-ai-consent="<%= i.href %>" title="AI permissions" data-tippy-content="AI permissions">
|
|
507
|
+
<i class="fa-solid fa-shield-halved"></i>
|
|
508
|
+
</button>
|
|
482
509
|
<div class='disclosure-indicator' aria-hidden="true">
|
|
483
510
|
<i class="fa-solid fa-chevron-right"></i>
|
|
484
511
|
</div>
|
|
@@ -510,8 +537,11 @@ body.dark #update-spec {
|
|
|
510
537
|
<% } %>
|
|
511
538
|
<div class='flexible'></div>
|
|
512
539
|
<% if (i.link) { %>
|
|
513
|
-
<div target="_blank" data-href="<%= i.link %>"><i class="fa-solid fa-circle-info"></i></div>
|
|
540
|
+
<div target="_blank" data-href="<%= i.link %>" title="Open docs" data-tippy-content="Open docs"><i class="fa-solid fa-circle-info"></i></div>
|
|
514
541
|
<% } %>
|
|
542
|
+
<button class="ai-perm-link" type="button" data-ai-consent="<%= i.href %>" title="AI permissions" data-tippy-content="AI permissions">
|
|
543
|
+
<i class="fa-solid fa-shield-halved"></i>
|
|
544
|
+
</button>
|
|
515
545
|
<div class='disclosure-indicator' aria-hidden="true">
|
|
516
546
|
<i class="fa-solid fa-chevron-right"></i>
|
|
517
547
|
</div>
|
|
@@ -542,8 +572,11 @@ body.dark #update-spec {
|
|
|
542
572
|
<% } %>
|
|
543
573
|
<div class='flexible'></div>
|
|
544
574
|
<% if (i.link) { %>
|
|
545
|
-
<div target="_blank" data-href="<%= i.link %>"><i class="fa-solid fa-circle-info"></i></div>
|
|
575
|
+
<div target="_blank" data-href="<%= i.link %>" title="Open docs" data-tippy-content="Open docs"><i class="fa-solid fa-circle-info"></i></div>
|
|
546
576
|
<% } %>
|
|
577
|
+
<button class="ai-perm-link" type="button" data-ai-consent="<%= i.href %>" title="AI permissions" data-tippy-content="AI permissions">
|
|
578
|
+
<i class="fa-solid fa-shield-halved"></i>
|
|
579
|
+
</button>
|
|
547
580
|
<div class='disclosure-indicator' aria-hidden="true">
|
|
548
581
|
<i class="fa-solid fa-chevron-right"></i>
|
|
549
582
|
</div>
|
|
@@ -709,6 +742,28 @@ const appendSessionParam = (value, session) => {
|
|
|
709
742
|
const delimiter = value.includes('?') ? '&' : '?'
|
|
710
743
|
return `${value}${delimiter}session=${session}`
|
|
711
744
|
}
|
|
745
|
+
const normalizeConsentSource = (value) => {
|
|
746
|
+
if (!value || typeof value !== "string") return ""
|
|
747
|
+
return value.trim().replace(/\\/g, "/").replace(/\/+$/, "")
|
|
748
|
+
}
|
|
749
|
+
const revokeConsentForHref = (href) => {
|
|
750
|
+
try {
|
|
751
|
+
if (!href || typeof href !== "string") return { ok: false }
|
|
752
|
+
const store = window.localStorage
|
|
753
|
+
if (!store) return { ok: false }
|
|
754
|
+
const url = new URL(href, window.location.origin)
|
|
755
|
+
const cwd = url.searchParams.get("cwd")
|
|
756
|
+
if (!cwd) return { ok: false }
|
|
757
|
+
const folder = normalizeConsentSource(cwd)
|
|
758
|
+
if (!folder) return { ok: false }
|
|
759
|
+
const key = `pinokio:ai-consent:${encodeURIComponent(folder)}`
|
|
760
|
+
const existed = store.getItem(key) !== null
|
|
761
|
+
store.removeItem(key)
|
|
762
|
+
return { ok: true, folder, existed }
|
|
763
|
+
} catch (_) {
|
|
764
|
+
return { ok: false }
|
|
765
|
+
}
|
|
766
|
+
}
|
|
712
767
|
const START_ICON_HTML = '<i class="fa-solid fa-chevron-right"></i>'
|
|
713
768
|
const STARTING_ICON_HTML = '<i class="fa-solid fa-circle-notch fa-spin"></i>'
|
|
714
769
|
const setTabLaunchState = (tab, state) => {
|
|
@@ -770,6 +825,21 @@ document.querySelector("form input[type=search]").addEventListener("input", (e)
|
|
|
770
825
|
})
|
|
771
826
|
document.querySelector("form input[type=search]").focus()
|
|
772
827
|
document.addEventListener("click", (e) => {
|
|
828
|
+
const permTarget = e.target.closest('[data-ai-consent]')
|
|
829
|
+
if (permTarget) {
|
|
830
|
+
e.preventDefault()
|
|
831
|
+
e.stopPropagation()
|
|
832
|
+
const href = permTarget.getAttribute('data-ai-consent') || ''
|
|
833
|
+
const result = revokeConsentForHref(href)
|
|
834
|
+
if (result && result.ok) {
|
|
835
|
+
const folderLabel = result.folder || 'this folder'
|
|
836
|
+
alert(`Cleared AI permission for ${folderLabel}. You will be prompted again next time.`)
|
|
837
|
+
} else {
|
|
838
|
+
alert('Unable to change AI permission for this item.')
|
|
839
|
+
}
|
|
840
|
+
return
|
|
841
|
+
}
|
|
842
|
+
|
|
773
843
|
const infoTarget = e.target.closest('[data-href][target="_blank"]')
|
|
774
844
|
if (infoTarget) {
|
|
775
845
|
e.preventDefault()
|
|
@@ -217,34 +217,34 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
217
217
|
location.href = location.href
|
|
218
218
|
<% } else { %>
|
|
219
219
|
<% if (!install_required) { %>
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
220
|
+
let term
|
|
221
|
+
const n = new N()
|
|
222
|
+
let socket = new Socket()
|
|
223
|
+
let url = "<%=query.uri%>"
|
|
224
|
+
let params = new URLSearchParams(location.search)
|
|
225
|
+
let entries = [...params.entries()]
|
|
226
|
+
let options;
|
|
227
|
+
if (entries.length > 0) {
|
|
228
|
+
options = {}
|
|
229
|
+
for(const [key, value] of entries) {
|
|
230
|
+
options[key] = value;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// let name = "0x" + url.split("").map(c => c.charCodeAt(0).toString(16).padStart(2, "0")).join("");
|
|
234
|
+
let name = await installname(url, null, options)
|
|
235
|
+
if (name) {
|
|
236
|
+
if (!term) {
|
|
237
|
+
<% if (theme === "dark") { %>
|
|
238
|
+
term = await createTerm(xtermTheme.FrontEndDelight)
|
|
239
|
+
<% } else { %>
|
|
240
|
+
term = await createTerm(xtermTheme.Tomorrow)
|
|
241
|
+
<% } %>
|
|
242
|
+
}
|
|
243
|
+
await install(name, url, term, socket, options)
|
|
244
|
+
} else {
|
|
245
|
+
alert("something went wrong")
|
|
246
|
+
}
|
|
247
|
+
<% } %>
|
|
248
248
|
<% } %>
|
|
249
249
|
if (document.querySelector("#del-bin")) {
|
|
250
250
|
document.querySelector("#del-bin").addEventListener("click", async (e) => {
|
package/server/views/editor.ejs
CHANGED
|
@@ -295,10 +295,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
295
295
|
})
|
|
296
296
|
})
|
|
297
297
|
}
|
|
298
|
-
start(mode) {
|
|
299
|
-
return new Promise(async (resolve, reject) => {
|
|
298
|
+
async start(mode) {
|
|
300
299
|
// await this.save()
|
|
301
|
-
|
|
300
|
+
this.socket.close()
|
|
302
301
|
// document.querySelector(".terminal-container").classList.add("hidden")
|
|
303
302
|
let query = Object.fromEntries(new URLSearchParams(location.search))
|
|
304
303
|
// document.querySelector(".containers").classList.add("running")
|
|
@@ -669,7 +668,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
669
668
|
}
|
|
670
669
|
}
|
|
671
670
|
})
|
|
672
|
-
})
|
|
673
671
|
}
|
|
674
672
|
async run (mode) {
|
|
675
673
|
this.mode = (mode ? mode : "run")
|
|
@@ -696,7 +694,8 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
696
694
|
})
|
|
697
695
|
let config = {
|
|
698
696
|
scrollback: 9999999,
|
|
699
|
-
fontSize:
|
|
697
|
+
fontSize: 14,
|
|
698
|
+
fontFamily: 'monospace',
|
|
700
699
|
theme,
|
|
701
700
|
}
|
|
702
701
|
let res = await fetch("/xterm_config").then((res) => {
|
|
@@ -311,7 +311,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
311
311
|
}).then((response) => response.json())
|
|
312
312
|
Swal.close()
|
|
313
313
|
if (res && res.success) {
|
|
314
|
-
location.href = "/"
|
|
314
|
+
location.href = "/home"
|
|
315
315
|
} else if (res && res.error) {
|
|
316
316
|
alert(res.error)
|
|
317
317
|
} else {
|
package/server/views/index.ejs
CHANGED
|
@@ -744,6 +744,7 @@ body.dark aside .current.selected {
|
|
|
744
744
|
<a href="/connect" class='tab'><i class="fa-solid fa-plug"></i><div class='caption'>Login</div></a>
|
|
745
745
|
<a class='tab' href="<%=portal%>" target="_blank"><i class="fa-solid fa-question"></i><div class='caption'>Help</div></a>
|
|
746
746
|
<a class='tab' id='genlog' href="/logs"><i class="fa-solid fa-laptop-code"></i><div class='caption'>Logs</div></a>
|
|
747
|
+
<a class='tab' href="/checkpoints"><i class="fa-solid fa-clock-rotate-left"></i><div class='caption'>Checkpoints</div></a>
|
|
747
748
|
<a class='tab' href="/screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
|
|
748
749
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
749
750
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
@@ -1488,8 +1489,9 @@ document.addEventListener("click", async (e) => {
|
|
|
1488
1489
|
console.log("res", res)
|
|
1489
1490
|
Swal.close()
|
|
1490
1491
|
if (res) {
|
|
1492
|
+
debugger
|
|
1491
1493
|
if (res.success) {
|
|
1492
|
-
location.href = "/"
|
|
1494
|
+
location.href = "/home"
|
|
1493
1495
|
} else if (res.error) {
|
|
1494
1496
|
alert(res.error)
|
|
1495
1497
|
}
|
|
@@ -2647,7 +2647,8 @@ const createTerm = async (_theme) => {
|
|
|
2647
2647
|
<% } %>
|
|
2648
2648
|
let config = {
|
|
2649
2649
|
scrollback: 9999999,
|
|
2650
|
-
fontSize:
|
|
2650
|
+
fontSize: 14,
|
|
2651
|
+
fontFamily: 'monospace',
|
|
2651
2652
|
theme,
|
|
2652
2653
|
}
|
|
2653
2654
|
let res = await fetch("/xterm_config").then((res) => {
|
package/server/views/install.ejs
CHANGED
package/server/views/net.ejs
CHANGED
|
@@ -708,7 +708,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
708
708
|
</div>
|
|
709
709
|
<% } else { %>
|
|
710
710
|
<div class='placeholder-icon'>
|
|
711
|
-
<i class="fa-solid fa-
|
|
711
|
+
<i class="fa-solid fa-clock-rotate-left"></i>
|
|
712
712
|
</div>
|
|
713
713
|
<% } %>
|
|
714
714
|
</div>
|
|
@@ -811,7 +811,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
811
811
|
<h3>
|
|
812
812
|
<div class='item-icon'>
|
|
813
813
|
<div class='placeholder-icon'>
|
|
814
|
-
<i class="fa-solid fa-
|
|
814
|
+
<i class="fa-solid fa-clock-rotate-left"></i>
|
|
815
815
|
</div>
|
|
816
816
|
</div>
|
|
817
817
|
<div class='col'>
|
|
@@ -866,7 +866,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
866
866
|
<img src="<%=item[`${protocol}_icon`]%>" onerror="this.src='/pinokio-black.png'"/>
|
|
867
867
|
<% } else { %>
|
|
868
868
|
<div class='placeholder-icon'>
|
|
869
|
-
<i class="fa-solid fa-
|
|
869
|
+
<i class="fa-solid fa-clock-rotate-left"></i>
|
|
870
870
|
</div>
|
|
871
871
|
<% } %>
|
|
872
872
|
</div>
|
|
@@ -909,7 +909,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
909
909
|
<img src="<%=item[`${protocol}_icon`]%>" onerror="this.src='/pinokio-black.png'"/>
|
|
910
910
|
<% } else { %>
|
|
911
911
|
<div class='placeholder-icon'>
|
|
912
|
-
<i class="fa-solid fa-
|
|
912
|
+
<i class="fa-solid fa-clock-rotate-left"></i>
|
|
913
913
|
</div>
|
|
914
914
|
<% } %>
|
|
915
915
|
</div>
|
|
@@ -949,7 +949,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
949
949
|
<h3>
|
|
950
950
|
<div class='item-icon'>
|
|
951
951
|
<div class='placeholder-icon'>
|
|
952
|
-
<i class="fa-solid fa-
|
|
952
|
+
<i class="fa-solid fa-clock-rotate-left"></i>
|
|
953
953
|
</div>
|
|
954
954
|
</div>
|
|
955
955
|
<div class='col'>
|
|
@@ -1005,6 +1005,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1005
1005
|
<a href="/connect" class='tab'><i class="fa-solid fa-plug"></i><div class='caption'>Login</div></a>
|
|
1006
1006
|
<a class='tab' href="<%=portal%>" target="_blank"><i class="fa-solid fa-question"></i><div class='caption'>Help</div></a>
|
|
1007
1007
|
<a class='tab' id='genlog' href="/logs"><i class="fa-solid fa-laptop-code"></i><div class='caption'>Logs</div></a>
|
|
1008
|
+
<a class='tab' href="/checkpoints"><i class="fa-solid fa-clock-rotate-left"></i><div class='caption'>Checkpoints</div></a>
|
|
1008
1009
|
<a class='tab' href="/screenshots"><i class="fa-solid fa-camera"></i><div class='caption'>Screenshots</div></a>
|
|
1009
1010
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
1010
1011
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
@@ -1167,7 +1168,8 @@ const createDnsTerminal = async (container) => {
|
|
|
1167
1168
|
}
|
|
1168
1169
|
let config = {
|
|
1169
1170
|
scrollback: 9999999,
|
|
1170
|
-
fontSize:
|
|
1171
|
+
fontSize: 14,
|
|
1172
|
+
fontFamily: 'monospace',
|
|
1171
1173
|
theme: document.body.classList.contains('dark') ? xtermTheme.FrontEndDelight : xtermTheme.Tomorrow,
|
|
1172
1174
|
}
|
|
1173
1175
|
try {
|
|
@@ -1702,7 +1704,7 @@ document.addEventListener("click", async (e) => {
|
|
|
1702
1704
|
Swal.close()
|
|
1703
1705
|
if (res) {
|
|
1704
1706
|
if (res.success) {
|
|
1705
|
-
location.href = "/"
|
|
1707
|
+
location.href = "/home"
|
|
1706
1708
|
} else if (res.error) {
|
|
1707
1709
|
alert(res.error)
|
|
1708
1710
|
}
|