pinokiod 7.2.11 → 7.2.13
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/Dockerfile +0 -2
- package/kernel/api/index.js +14 -1
- package/kernel/api/process/index.js +99 -44
- package/kernel/api/uri/index.js +51 -0
- package/kernel/environment.js +22 -3
- package/kernel/git.js +0 -13
- package/kernel/index.js +61 -1
- package/kernel/plugin.js +6 -58
- package/kernel/plugin_sources.js +236 -0
- package/kernel/util.js +60 -0
- package/package.json +1 -1
- package/server/features/drafts/public/drafts.js +35 -12
- package/server/index.js +120 -142
- package/server/lib/content_validation.js +28 -25
- package/server/public/common.js +95 -29
- package/server/public/create-launcher.js +4 -31
- package/server/public/electron.css +1 -1
- package/server/public/style.css +337 -0
- package/server/public/task-launcher.js +5 -32
- package/server/public/universal-launcher.js +3 -26
- package/server/views/app.ejs +8 -29
- package/server/views/d.ejs +0 -33
- package/server/views/editor.ejs +25 -4
- package/server/views/shell.ejs +11 -3
- package/server/views/terminal.ejs +15 -3
- package/spec/INSTRUCTION_SYNC.md +5 -5
- package/system/plugin/antigravity/antigravity.png +0 -0
- package/system/plugin/antigravity/pinokio.js +37 -0
- package/system/plugin/claude/claude.png +0 -0
- package/system/plugin/claude/pinokio.js +63 -0
- package/system/plugin/claude-auto/claude.png +0 -0
- package/system/plugin/claude-auto/pinokio.js +74 -0
- package/system/plugin/claude-desktop/icon.jpeg +0 -0
- package/system/plugin/claude-desktop/pinokio.js +39 -0
- package/system/plugin/codex/openai.webp +0 -0
- package/system/plugin/codex/pinokio.js +58 -0
- package/system/plugin/codex-auto/openai.webp +0 -0
- package/system/plugin/codex-auto/pinokio.js +65 -0
- package/system/plugin/codex-desktop/icon.png +0 -0
- package/system/plugin/codex-desktop/pinokio.js +39 -0
- package/system/plugin/crush/crush.png +0 -0
- package/system/plugin/crush/pinokio.js +31 -0
- package/system/plugin/cursor/cursor.jpeg +0 -0
- package/system/plugin/cursor/pinokio.js +39 -0
- package/system/plugin/gemini/gemini.jpeg +0 -0
- package/system/plugin/gemini/pinokio.js +40 -0
- package/system/plugin/gemini-auto/gemini.jpeg +0 -0
- package/system/plugin/gemini-auto/pinokio.js +43 -0
- package/system/plugin/qwen/pinokio.js +50 -0
- package/system/plugin/qwen/qwen.png +0 -0
- package/system/plugin/vscode/pinokio.js +36 -0
- package/system/plugin/vscode/vscode.png +0 -0
- package/system/plugin/windsurf/pinokio.js +39 -0
- package/system/plugin/windsurf/windsurf.png +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
const fs = require("fs")
|
|
2
|
+
const path = require("path")
|
|
3
|
+
const { glob } = require("glob")
|
|
4
|
+
|
|
5
|
+
const LOCAL_RUN_PREFIX = "/run"
|
|
6
|
+
const LOCAL_ASSET_PREFIX = "/asset"
|
|
7
|
+
const SYSTEM_RUN_PREFIX = "/pinokio/run"
|
|
8
|
+
const SYSTEM_ASSET_PREFIX = "/pinokio/asset"
|
|
9
|
+
const LOCAL_PLUGIN_RUN_PREFIX = `${LOCAL_RUN_PREFIX}/plugin`
|
|
10
|
+
const LOCAL_PLUGIN_ASSET_PREFIX = `${LOCAL_ASSET_PREFIX}/plugin`
|
|
11
|
+
const SYSTEM_PLUGIN_RUN_PREFIX = `${SYSTEM_RUN_PREFIX}/plugin`
|
|
12
|
+
const SYSTEM_PLUGIN_ASSET_PREFIX = `${SYSTEM_ASSET_PREFIX}/plugin`
|
|
13
|
+
|
|
14
|
+
const toPathname = (value) => {
|
|
15
|
+
const raw = typeof value === "string" ? value.trim() : ""
|
|
16
|
+
if (!raw) return ""
|
|
17
|
+
try {
|
|
18
|
+
if (/^https?:\/\//i.test(raw)) return new URL(raw).pathname
|
|
19
|
+
if (raw.startsWith("/")) return new URL(`http://localhost${raw}`).pathname
|
|
20
|
+
} catch (_) {
|
|
21
|
+
}
|
|
22
|
+
return raw.split("?")[0].split("#")[0]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const normalizeSlashes = (value) => String(value || "").replace(/\\/g, "/").replace(/\/{2,}/g, "/")
|
|
26
|
+
|
|
27
|
+
const systemRoot = (kernel) => {
|
|
28
|
+
if (kernel && typeof kernel.systemPath === "function") {
|
|
29
|
+
return kernel.systemPath()
|
|
30
|
+
}
|
|
31
|
+
return path.resolve(__dirname, "..", "system")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const systemPluginRoot = (kernel) => {
|
|
35
|
+
if (kernel && typeof kernel.systemPath === "function") {
|
|
36
|
+
return kernel.systemPath("plugin")
|
|
37
|
+
}
|
|
38
|
+
return path.resolve(__dirname, "..", "system", "plugin")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const isSystemRunPath = (value) => toPathname(value).startsWith(`${SYSTEM_RUN_PREFIX}/`)
|
|
42
|
+
const isLocalRunPath = (value) => toPathname(value).startsWith(`${LOCAL_RUN_PREFIX}/`)
|
|
43
|
+
const isRunPath = (value) => isLocalRunPath(value) || isSystemRunPath(value)
|
|
44
|
+
const isSystemPluginPath = (value) => normalizeSlashes(value).startsWith(`${SYSTEM_PLUGIN_RUN_PREFIX}/`)
|
|
45
|
+
const isLegacyPluginCodePath = (value) => {
|
|
46
|
+
const normalized = normalizeSlashes(value).replace(/^\/+/, "")
|
|
47
|
+
return normalized.startsWith("plugin/code/") || normalized.startsWith("code/")
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const normalizePluginPath = (value) => {
|
|
51
|
+
let normalized = toPathname(value)
|
|
52
|
+
if (!normalized) return ""
|
|
53
|
+
normalized = normalizeSlashes(normalized)
|
|
54
|
+
if (!normalized.startsWith(`${SYSTEM_RUN_PREFIX}/`)) {
|
|
55
|
+
normalized = normalized.replace(/^\/run(?=\/)/, "")
|
|
56
|
+
}
|
|
57
|
+
if (!normalized.startsWith("/")) {
|
|
58
|
+
normalized = `/${normalized}`
|
|
59
|
+
}
|
|
60
|
+
normalized = normalized.replace(/\/+$/, "")
|
|
61
|
+
if (!normalized.endsWith("/pinokio.js")) {
|
|
62
|
+
normalized = `${normalized}/pinokio.js`
|
|
63
|
+
}
|
|
64
|
+
return normalized
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const pluginSelectionMatches = (src, selectedValue) => {
|
|
68
|
+
const selectedPlugin = normalizeSlashes(typeof selectedValue === "string" ? selectedValue.trim() : "")
|
|
69
|
+
if (!selectedPlugin || !src) return false
|
|
70
|
+
const selectedRunPath = selectedPlugin.startsWith(`${SYSTEM_RUN_PREFIX}/`)
|
|
71
|
+
? selectedPlugin
|
|
72
|
+
: `${LOCAL_RUN_PREFIX}${selectedPlugin}`
|
|
73
|
+
return src === selectedPlugin || src.startsWith(selectedRunPath)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const resolveRunPath = (kernel, value) => {
|
|
77
|
+
const pathname = toPathname(value)
|
|
78
|
+
if (isSystemRunPath(pathname)) {
|
|
79
|
+
const parts = pathname.split("/").filter(Boolean).slice(2)
|
|
80
|
+
return kernel.systemPath(...parts)
|
|
81
|
+
}
|
|
82
|
+
if (isLocalRunPath(pathname)) {
|
|
83
|
+
const parts = pathname.split("/").filter(Boolean).slice(1)
|
|
84
|
+
return kernel.path(...parts)
|
|
85
|
+
}
|
|
86
|
+
return ""
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const resolvePinokioPath = (kernel, value) => {
|
|
90
|
+
const runPath = resolveRunPath(kernel, value)
|
|
91
|
+
if (runPath) return runPath
|
|
92
|
+
const pathname = toPathname(value)
|
|
93
|
+
return pathname ? kernel.path(pathname.replace(/^\/+/, "")) : ""
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const systemRelativeFromPluginPath = (normalizedPath) => {
|
|
97
|
+
return normalizeSlashes(normalizedPath).replace(/^\/pinokio\/run\/+/, "")
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const pluginPathToAbsolute = (kernel, normalizedPath) => {
|
|
101
|
+
if (isSystemPluginPath(normalizedPath)) {
|
|
102
|
+
return kernel.systemPath(systemRelativeFromPluginPath(normalizedPath))
|
|
103
|
+
}
|
|
104
|
+
return kernel.path(normalizeSlashes(normalizedPath).replace(/^\/+/, ""))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const pluginRunHrefForPath = (normalizedPath) => {
|
|
108
|
+
if (typeof normalizedPath !== "string" || !normalizedPath) return ""
|
|
109
|
+
if (isSystemPluginPath(normalizedPath)) return normalizedPath
|
|
110
|
+
return `${LOCAL_RUN_PREFIX}${normalizedPath}`
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const pluginAssetHrefForIcon = (normalizedPath, icon) => {
|
|
114
|
+
const trimmedIcon = typeof icon === "string" ? icon.trim() : ""
|
|
115
|
+
if (!trimmedIcon) return ""
|
|
116
|
+
if (isSystemPluginPath(normalizedPath)) {
|
|
117
|
+
const relativeDir = path.posix.dirname(systemRelativeFromPluginPath(normalizedPath))
|
|
118
|
+
return `${SYSTEM_ASSET_PREFIX}/${relativeDir}/${trimmedIcon}`
|
|
119
|
+
}
|
|
120
|
+
if (normalizeSlashes(normalizedPath).startsWith("/plugin/")) {
|
|
121
|
+
const relativeDir = path.posix.dirname(normalizeSlashes(normalizedPath).slice(1))
|
|
122
|
+
return `${LOCAL_ASSET_PREFIX}/${relativeDir}/${trimmedIcon}`
|
|
123
|
+
}
|
|
124
|
+
return ""
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const normalizeLauncherTool = (toolValue) => {
|
|
128
|
+
let normalizedTool = typeof toolValue === "string" ? toolValue.trim() : ""
|
|
129
|
+
normalizedTool = normalizedTool.replace(/^https?:\/\/[^/]+/i, "")
|
|
130
|
+
normalizedTool = normalizedTool.replace(/^\/+|\/+$/g, "")
|
|
131
|
+
if (!normalizedTool || normalizedTool.includes("..") || !/^[A-Za-z0-9._/-]+$/.test(normalizedTool)) {
|
|
132
|
+
const error = new Error("Invalid plugin.")
|
|
133
|
+
error.status = 400
|
|
134
|
+
throw error
|
|
135
|
+
}
|
|
136
|
+
if (!normalizedTool.startsWith("pinokio/run/")) {
|
|
137
|
+
normalizedTool = normalizedTool.replace(/^run\//, "")
|
|
138
|
+
}
|
|
139
|
+
if (isLegacyPluginCodePath(normalizedTool)) {
|
|
140
|
+
const error = new Error("The managed plugin/code path is no longer used.")
|
|
141
|
+
error.status = 400
|
|
142
|
+
throw error
|
|
143
|
+
}
|
|
144
|
+
return normalizedTool
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const resolveLauncherPluginHref = (toolValue) => {
|
|
148
|
+
const normalizedTool = normalizeLauncherTool(toolValue)
|
|
149
|
+
if (normalizedTool.startsWith("pinokio/run/")) {
|
|
150
|
+
const scriptPath = normalizedTool.endsWith(".js")
|
|
151
|
+
? normalizedTool
|
|
152
|
+
: `${normalizedTool}/pinokio.js`
|
|
153
|
+
return `/${scriptPath}`
|
|
154
|
+
}
|
|
155
|
+
if (normalizedTool.startsWith("plugin/") || normalizedTool.startsWith("api/")) {
|
|
156
|
+
const scriptPath = normalizedTool.endsWith(".js")
|
|
157
|
+
? normalizedTool
|
|
158
|
+
: `${normalizedTool}/pinokio.js`
|
|
159
|
+
return `${LOCAL_RUN_PREFIX}/${scriptPath}`
|
|
160
|
+
}
|
|
161
|
+
return `${LOCAL_PLUGIN_RUN_PREFIX}/${normalizedTool}/pinokio.js`
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const loadPluginsFromRoot = async ({ kernel, root, runPrefix, assetPrefix, source, ignore = [] }) => {
|
|
165
|
+
const exists = await fs.promises.stat(root).then((stat) => stat.isDirectory()).catch(() => false)
|
|
166
|
+
if (!exists) return []
|
|
167
|
+
|
|
168
|
+
const pluginPaths = await glob("**/pinokio.js", { cwd: root, ignore })
|
|
169
|
+
const plugins = []
|
|
170
|
+
for (const pluginPath of pluginPaths) {
|
|
171
|
+
const normalizedPluginPath = normalizeSlashes(pluginPath)
|
|
172
|
+
const config = await kernel.require(path.resolve(root, pluginPath))
|
|
173
|
+
if (!config || !Array.isArray(config.run)) continue
|
|
174
|
+
const invalid = Object.keys(config).some((key) => typeof config[key] === "function")
|
|
175
|
+
if (invalid) continue
|
|
176
|
+
|
|
177
|
+
const cwd = normalizedPluginPath.split("/").slice(0, -1).join("/")
|
|
178
|
+
const href = `${runPrefix}/${normalizedPluginPath}`
|
|
179
|
+
const image = config.icon ? `${assetPrefix}/${cwd}/${config.icon}` : config.image
|
|
180
|
+
plugins.push({
|
|
181
|
+
...config,
|
|
182
|
+
href,
|
|
183
|
+
src: href,
|
|
184
|
+
image,
|
|
185
|
+
source,
|
|
186
|
+
system: source === "system",
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
return plugins
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const loadPluginMenu = async (kernel) => {
|
|
193
|
+
const systemPlugins = await loadPluginsFromRoot({
|
|
194
|
+
kernel,
|
|
195
|
+
root: systemPluginRoot(kernel),
|
|
196
|
+
runPrefix: SYSTEM_PLUGIN_RUN_PREFIX,
|
|
197
|
+
assetPrefix: SYSTEM_PLUGIN_ASSET_PREFIX,
|
|
198
|
+
source: "system",
|
|
199
|
+
})
|
|
200
|
+
const localPlugins = await loadPluginsFromRoot({
|
|
201
|
+
kernel,
|
|
202
|
+
root: path.resolve(kernel.homedir, "plugin"),
|
|
203
|
+
runPrefix: LOCAL_PLUGIN_RUN_PREFIX,
|
|
204
|
+
assetPrefix: LOCAL_PLUGIN_ASSET_PREFIX,
|
|
205
|
+
source: "local",
|
|
206
|
+
ignore: ["code/**"],
|
|
207
|
+
})
|
|
208
|
+
return systemPlugins.concat(localPlugins)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
module.exports = {
|
|
212
|
+
LOCAL_RUN_PREFIX,
|
|
213
|
+
LOCAL_ASSET_PREFIX,
|
|
214
|
+
SYSTEM_RUN_PREFIX,
|
|
215
|
+
SYSTEM_ASSET_PREFIX,
|
|
216
|
+
LOCAL_PLUGIN_RUN_PREFIX,
|
|
217
|
+
SYSTEM_PLUGIN_RUN_PREFIX,
|
|
218
|
+
SYSTEM_PLUGIN_ASSET_PREFIX,
|
|
219
|
+
systemRoot,
|
|
220
|
+
systemPluginRoot,
|
|
221
|
+
toPathname,
|
|
222
|
+
isSystemRunPath,
|
|
223
|
+
isLocalRunPath,
|
|
224
|
+
isRunPath,
|
|
225
|
+
isSystemPluginPath,
|
|
226
|
+
isLegacyPluginCodePath,
|
|
227
|
+
normalizePluginPath,
|
|
228
|
+
pluginSelectionMatches,
|
|
229
|
+
resolveRunPath,
|
|
230
|
+
resolvePinokioPath,
|
|
231
|
+
pluginPathToAbsolute,
|
|
232
|
+
pluginRunHrefForPath,
|
|
233
|
+
pluginAssetHrefForIcon,
|
|
234
|
+
resolveLauncherPluginHref,
|
|
235
|
+
loadPluginMenu,
|
|
236
|
+
}
|
package/kernel/util.js
CHANGED
|
@@ -434,6 +434,65 @@ const openURL = (url) => {
|
|
|
434
434
|
console.warn('[Util.openURL] exec failed:', err && err.message ? err.message : err)
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
|
+
const openURI = async (uri) => {
|
|
438
|
+
const platform = os.platform()
|
|
439
|
+
const launch = (command, args) => {
|
|
440
|
+
return new Promise((resolve, reject) => {
|
|
441
|
+
let settled = false
|
|
442
|
+
const settle = (fn, value) => {
|
|
443
|
+
if (settled) return
|
|
444
|
+
settled = true
|
|
445
|
+
clearTimeout(timer)
|
|
446
|
+
fn(value)
|
|
447
|
+
}
|
|
448
|
+
const timer = setTimeout(() => {
|
|
449
|
+
settle(resolve, {
|
|
450
|
+
ok: true,
|
|
451
|
+
command,
|
|
452
|
+
status: 'started'
|
|
453
|
+
})
|
|
454
|
+
}, 3000)
|
|
455
|
+
const child = spawn(command, args, {
|
|
456
|
+
detached: true,
|
|
457
|
+
stdio: 'ignore'
|
|
458
|
+
})
|
|
459
|
+
child.on('error', (error) => {
|
|
460
|
+
settle(reject, error)
|
|
461
|
+
})
|
|
462
|
+
child.on('close', (code) => {
|
|
463
|
+
if (code) {
|
|
464
|
+
settle(reject, new Error(`${command} exited with code ${code}`))
|
|
465
|
+
} else {
|
|
466
|
+
settle(resolve, {
|
|
467
|
+
ok: true,
|
|
468
|
+
command,
|
|
469
|
+
status: 'exited'
|
|
470
|
+
})
|
|
471
|
+
}
|
|
472
|
+
})
|
|
473
|
+
child.unref()
|
|
474
|
+
})
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
if (platform === 'darwin') {
|
|
478
|
+
return await launch('open', [uri])
|
|
479
|
+
} else if (platform === 'win32') {
|
|
480
|
+
try {
|
|
481
|
+
return await launch('rundll32.exe', ['url.dll,FileProtocolHandler', uri])
|
|
482
|
+
} catch (error) {
|
|
483
|
+
console.warn('[Util.openURI] rundll32 failed, falling back to explorer:', error && error.message ? error.message : error)
|
|
484
|
+
return await launch('explorer.exe', [uri])
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return await launch('xdg-open', [uri])
|
|
488
|
+
} catch (err) {
|
|
489
|
+
console.warn('[Util.openURI] spawn failed:', err && err.message ? err.message : err)
|
|
490
|
+
return {
|
|
491
|
+
ok: false,
|
|
492
|
+
error: err && err.message ? err.message : String(err)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
437
496
|
const openfs = (dirPath, options, kernel) => {
|
|
438
497
|
let command = '';
|
|
439
498
|
const platform = os.platform()
|
|
@@ -1197,6 +1256,7 @@ module.exports = {
|
|
|
1197
1256
|
find_venv,
|
|
1198
1257
|
fill_object,
|
|
1199
1258
|
run,
|
|
1259
|
+
openURI,
|
|
1200
1260
|
openURL,
|
|
1201
1261
|
u2p,
|
|
1202
1262
|
p2u,
|
package/package.json
CHANGED
|
@@ -269,10 +269,10 @@
|
|
|
269
269
|
justify-content: center;
|
|
270
270
|
gap: 6px;
|
|
271
271
|
min-height: 30px;
|
|
272
|
-
border: 1px solid
|
|
272
|
+
border: 1px solid var(--pinokio-chrome-accent-bg-light);
|
|
273
273
|
border-radius: 6px;
|
|
274
|
-
background:
|
|
275
|
-
color:
|
|
274
|
+
background: var(--pinokio-chrome-accent-bg-light);
|
|
275
|
+
color: var(--pinokio-chrome-accent-fg-light);
|
|
276
276
|
cursor: pointer;
|
|
277
277
|
font-size: 12px;
|
|
278
278
|
font-weight: 700;
|
|
@@ -282,37 +282,60 @@
|
|
|
282
282
|
}
|
|
283
283
|
.pinokio-draft-button:hover,
|
|
284
284
|
.pinokio-draft-button:focus {
|
|
285
|
-
border-color:
|
|
286
|
-
background:
|
|
285
|
+
border-color: color-mix(in srgb, var(--pinokio-chrome-accent-bg-light) 88%, #ffffff);
|
|
286
|
+
background: color-mix(in srgb, var(--pinokio-chrome-accent-bg-light) 88%, #ffffff);
|
|
287
287
|
}
|
|
288
288
|
body.dark .pinokio-draft-button {
|
|
289
|
-
border-color:
|
|
290
|
-
background:
|
|
291
|
-
color: #
|
|
289
|
+
border-color: #fbbf24;
|
|
290
|
+
background: #fbbf24;
|
|
291
|
+
color: var(--universal-launcher-surface-solid, #0a0a0b);
|
|
292
292
|
}
|
|
293
293
|
body.dark .pinokio-draft-button:hover,
|
|
294
294
|
body.dark .pinokio-draft-button:focus {
|
|
295
|
-
border-color:
|
|
296
|
-
background:
|
|
295
|
+
border-color: color-mix(in srgb, #fbbf24 90%, #ffffff);
|
|
296
|
+
background: color-mix(in srgb, #fbbf24 90%, #ffffff);
|
|
297
|
+
color: var(--universal-launcher-surface-solid, #0a0a0b);
|
|
297
298
|
}
|
|
298
299
|
.pinokio-draft-button.secondary {
|
|
300
|
+
border-color: rgba(15, 23, 42, 0.14);
|
|
299
301
|
color: #374151;
|
|
300
302
|
background: rgba(255, 255, 255, 0.72);
|
|
301
303
|
}
|
|
304
|
+
.pinokio-draft-button.secondary:hover,
|
|
305
|
+
.pinokio-draft-button.secondary:focus {
|
|
306
|
+
border-color: rgba(15, 23, 42, 0.24);
|
|
307
|
+
background: rgba(15, 23, 42, 0.04);
|
|
308
|
+
}
|
|
302
309
|
body.dark .pinokio-draft-button.secondary {
|
|
310
|
+
border-color: rgba(148, 163, 184, 0.28);
|
|
303
311
|
color: #dbeafe;
|
|
304
312
|
background: transparent;
|
|
305
313
|
}
|
|
314
|
+
body.dark .pinokio-draft-button.secondary:hover,
|
|
315
|
+
body.dark .pinokio-draft-button.secondary:focus {
|
|
316
|
+
border-color: rgba(148, 163, 184, 0.38);
|
|
317
|
+
background: rgba(255, 255, 255, 0.06);
|
|
318
|
+
}
|
|
306
319
|
.pinokio-draft-drawer .pinokio-draft-button.secondary {
|
|
307
320
|
border-color: rgba(15, 23, 42, 0.18);
|
|
308
321
|
color: #1f2937;
|
|
309
322
|
background: #ffffff;
|
|
310
323
|
}
|
|
324
|
+
.pinokio-draft-drawer .pinokio-draft-button.secondary:hover,
|
|
325
|
+
.pinokio-draft-drawer .pinokio-draft-button.secondary:focus {
|
|
326
|
+
border-color: rgba(15, 23, 42, 0.28);
|
|
327
|
+
background: rgba(15, 23, 42, 0.05);
|
|
328
|
+
}
|
|
311
329
|
body.dark .pinokio-draft-drawer .pinokio-draft-button.secondary {
|
|
312
330
|
border-color: rgba(148, 163, 184, 0.28);
|
|
313
331
|
color: #dbeafe;
|
|
314
332
|
background: transparent;
|
|
315
333
|
}
|
|
334
|
+
body.dark .pinokio-draft-drawer .pinokio-draft-button.secondary:hover,
|
|
335
|
+
body.dark .pinokio-draft-drawer .pinokio-draft-button.secondary:focus {
|
|
336
|
+
border-color: rgba(148, 163, 184, 0.38);
|
|
337
|
+
background: rgba(255, 255, 255, 0.06);
|
|
338
|
+
}
|
|
316
339
|
.pinokio-draft-button:disabled {
|
|
317
340
|
cursor: default;
|
|
318
341
|
opacity: 0.68;
|
|
@@ -1223,7 +1246,7 @@
|
|
|
1223
1246
|
} finally {
|
|
1224
1247
|
if (button) {
|
|
1225
1248
|
button.disabled = false;
|
|
1226
|
-
setActionButtonLabel(button, originalText || "
|
|
1249
|
+
setActionButtonLabel(button, originalText || "File explorer");
|
|
1227
1250
|
}
|
|
1228
1251
|
}
|
|
1229
1252
|
}
|
|
@@ -1361,7 +1384,7 @@
|
|
|
1361
1384
|
tabs.appendChild(createDrawerTab("Markdown", "markdown"));
|
|
1362
1385
|
tabs.appendChild(createDrawerTab("Media", "media"));
|
|
1363
1386
|
const actions = createElement("div", "pinokio-draft-drawer-actions");
|
|
1364
|
-
const openButton = createActionButton("pinokio-draft-button secondary", "
|
|
1387
|
+
const openButton = createActionButton("pinokio-draft-button secondary", "File explorer", "fa-solid fa-folder-open");
|
|
1365
1388
|
openButton.type = "button";
|
|
1366
1389
|
openButton.addEventListener("click", () => {
|
|
1367
1390
|
void openDraft(item, openButton);
|