pinokiod 8.0.19 → 8.0.21
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/index.js +3 -0
- package/package.json +1 -1
- package/server/index.js +6 -1
- package/server/public/common.js +26 -1
- package/server/public/logs.js +12 -2
- package/server/views/explore.ejs +2 -2
- package/system/plugin/opencode/icon.png +0 -0
- package/system/plugin/opencode/pinokio.js +57 -0
- package/system/plugin/opencode-auto/icon.png +0 -0
- package/system/plugin/opencode-auto/pinokio.js +14 -0
- package/test/explore-lan-install-navigation.test.js +145 -0
- package/test/opencode-plugin.test.js +45 -0
- package/test/plugin-action-functions.test.js +28 -0
- package/test/plugin-sources.test.js +1 -1
package/kernel/api/index.js
CHANGED
|
@@ -1887,6 +1887,9 @@ class Api {
|
|
|
1887
1887
|
}
|
|
1888
1888
|
} else {
|
|
1889
1889
|
let { cwd, script } = await this.resolveScript(request.path)
|
|
1890
|
+
if (!request.cwd && this.isPathInsideRoot(cwd, PluginSources.systemPluginRoot(this.kernel))) {
|
|
1891
|
+
request.cwd = this.kernel.path("bin")
|
|
1892
|
+
}
|
|
1890
1893
|
|
|
1891
1894
|
if (!script) {
|
|
1892
1895
|
this.ondata({
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -7632,7 +7632,7 @@ class Server {
|
|
|
7632
7632
|
const category = classifyPluginMenuItem(pluginItem)
|
|
7633
7633
|
const title = pluginItem?.title || pluginItem?.text || pluginItem?.name || "Plugin"
|
|
7634
7634
|
const hasInstalledCheck = PluginSources.isInstalledCheck(pluginItem?.installed)
|
|
7635
|
-
const installed =
|
|
7635
|
+
const installed = null
|
|
7636
7636
|
return {
|
|
7637
7637
|
index,
|
|
7638
7638
|
title,
|
|
@@ -8262,6 +8262,11 @@ class Server {
|
|
|
8262
8262
|
res.status(404).send("Plugin not found.")
|
|
8263
8263
|
return
|
|
8264
8264
|
}
|
|
8265
|
+
if (plugin.hasInstalledCheck) {
|
|
8266
|
+
const validation = await contentValidation.validatePluginByPath(plugin.pluginPath)
|
|
8267
|
+
const config = validation.valid && validation.context ? validation.context.config : null
|
|
8268
|
+
plugin.installed = config ? await evaluatePluginInstalled(config) : null
|
|
8269
|
+
}
|
|
8265
8270
|
const [apps, shareState, sidebarContext] = await Promise.all([
|
|
8266
8271
|
collectPluginApps(),
|
|
8267
8272
|
buildPluginShareState(plugin),
|
package/server/public/common.js
CHANGED
|
@@ -3013,7 +3013,15 @@ if (typeof window !== 'undefined' && !window.__pinokioNavigateListenerInstalled)
|
|
|
3013
3013
|
return;
|
|
3014
3014
|
}
|
|
3015
3015
|
}
|
|
3016
|
-
|
|
3016
|
+
let frame = document.activeElement;
|
|
3017
|
+
if (
|
|
3018
|
+
(!frame || frame.tagName !== 'IFRAME') &&
|
|
3019
|
+
new URLSearchParams(window.location.search).get('mode') === 'explore' &&
|
|
3020
|
+
event.origin === 'https://pinokio.co'
|
|
3021
|
+
) {
|
|
3022
|
+
const exploreFrame = document.querySelector('main > iframe');
|
|
3023
|
+
if (exploreFrame && event.source === exploreFrame.contentWindow) frame = exploreFrame;
|
|
3024
|
+
}
|
|
3017
3025
|
if (!frame || frame.tagName !== 'IFRAME') {
|
|
3018
3026
|
try {
|
|
3019
3027
|
console.warn('[pinokio:navigate] no active iframe');
|
|
@@ -3029,6 +3037,23 @@ if (typeof window !== 'undefined' && !window.__pinokioNavigateListenerInstalled)
|
|
|
3029
3037
|
} catch (_) {}
|
|
3030
3038
|
return;
|
|
3031
3039
|
}
|
|
3040
|
+
const localInstall =
|
|
3041
|
+
target.origin === 'http://localhost:42000' &&
|
|
3042
|
+
(
|
|
3043
|
+
(target.pathname === '/pinokio/download' && Boolean(target.searchParams.get('uri'))) ||
|
|
3044
|
+
(
|
|
3045
|
+
target.pathname === '/checkpoints' &&
|
|
3046
|
+
Boolean(target.searchParams.get('registry')) &&
|
|
3047
|
+
/^(?:sha256:)?[0-9a-f]{64}$/i.test(target.searchParams.get('hash') || '')
|
|
3048
|
+
)
|
|
3049
|
+
);
|
|
3050
|
+
const lanExplore =
|
|
3051
|
+
new URLSearchParams(window.location.search).get('mode') === 'explore' &&
|
|
3052
|
+
!['localhost', '127.0.0.1', '::1', '[::1]'].includes(window.location.hostname) &&
|
|
3053
|
+
event.origin === 'https://pinokio.co' && event.source === frame.contentWindow;
|
|
3054
|
+
if (lanExplore && localInstall) {
|
|
3055
|
+
target = new URL(`${target.pathname}${target.search}${target.hash}`, window.location.origin);
|
|
3056
|
+
}
|
|
3032
3057
|
if (target.origin !== window.location.origin) {
|
|
3033
3058
|
try {
|
|
3034
3059
|
console.warn('[pinokio:navigate] blocked origin', target.origin);
|
package/server/public/logs.js
CHANGED
|
@@ -590,7 +590,17 @@
|
|
|
590
590
|
return `${detailUrl}${separator}next=install`
|
|
591
591
|
}
|
|
592
592
|
}
|
|
593
|
-
redirectToPluginInstallIfNeeded(tool) {
|
|
593
|
+
async redirectToPluginInstallIfNeeded(tool) {
|
|
594
|
+
if (tool && tool.hasInstall === true && tool.hasInstalledCheck === true && typeof tool.installed !== 'boolean') {
|
|
595
|
+
const pluginPath = typeof tool.pluginPath === 'string' ? tool.pluginPath.trim() : ''
|
|
596
|
+
if (pluginPath) {
|
|
597
|
+
try {
|
|
598
|
+
const response = await fetch(`/api/plugin/install-state?path=${encodeURIComponent(pluginPath)}`)
|
|
599
|
+
const state = response.ok ? await response.json() : null
|
|
600
|
+
tool.installed = state && typeof state.installed === 'boolean' ? state.installed : null
|
|
601
|
+
} catch (_) {}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
594
604
|
const href = this.pluginInstallHref(tool)
|
|
595
605
|
if (!href) {
|
|
596
606
|
return false
|
|
@@ -992,7 +1002,7 @@
|
|
|
992
1002
|
return
|
|
993
1003
|
}
|
|
994
1004
|
error.textContent = ''
|
|
995
|
-
if (this.redirectToPluginInstallIfNeeded(tool)) {
|
|
1005
|
+
if (await this.redirectToPluginInstallIfNeeded(tool)) {
|
|
996
1006
|
close()
|
|
997
1007
|
return
|
|
998
1008
|
}
|
package/server/views/explore.ejs
CHANGED
|
@@ -177,9 +177,9 @@ body.dark .explore-url {
|
|
|
177
177
|
<%- include('partials/home_server_popover_assets') %>
|
|
178
178
|
<main>
|
|
179
179
|
<% if (theme === "dark") { %>
|
|
180
|
-
<iframe name="
|
|
180
|
+
<iframe name="pinokio-explore" src="<%=discover_dark%>" <%=agent === "electron" ? "no-referrer" : ""%> allow="fullscreen *;" allowfullscreen></iframe>
|
|
181
181
|
<% } else { %>
|
|
182
|
-
<iframe name="
|
|
182
|
+
<iframe name="pinokio-explore" src="<%=discover_light%>" <%=agent === "electron" ? "no-referrer" : ""%> allow="fullscreen *;" allowfullscreen></iframe>
|
|
183
183
|
<% } %>
|
|
184
184
|
<%- include('partials/main_sidebar', { selected: 'explore' }) %>
|
|
185
185
|
</main>
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
title: "Opencode",
|
|
3
|
+
icon: "icon.png",
|
|
4
|
+
description: "The AI coding agent built for the terminal.",
|
|
5
|
+
link: "https://opencode.ai/",
|
|
6
|
+
path: "plugin",
|
|
7
|
+
async installed(kernel) {
|
|
8
|
+
return Boolean(kernel.which("opencode"))
|
|
9
|
+
},
|
|
10
|
+
install: [{
|
|
11
|
+
method: "shell.run",
|
|
12
|
+
params: {
|
|
13
|
+
message: "npm install -g opencode-ai@latest"
|
|
14
|
+
}
|
|
15
|
+
}],
|
|
16
|
+
uninstall: [{
|
|
17
|
+
method: "shell.run",
|
|
18
|
+
params: {
|
|
19
|
+
message: "npm uninstall -g opencode-ai"
|
|
20
|
+
}
|
|
21
|
+
}, {
|
|
22
|
+
method: "fs.rm",
|
|
23
|
+
params: {
|
|
24
|
+
path: "."
|
|
25
|
+
}
|
|
26
|
+
}],
|
|
27
|
+
update: [{
|
|
28
|
+
method: "shell.run",
|
|
29
|
+
params: {
|
|
30
|
+
message: "git pull",
|
|
31
|
+
}
|
|
32
|
+
}, {
|
|
33
|
+
method: "shell.run",
|
|
34
|
+
params: {
|
|
35
|
+
message: "npm install -g opencode-ai@latest"
|
|
36
|
+
}
|
|
37
|
+
}],
|
|
38
|
+
run: [{
|
|
39
|
+
when: "{{platform === 'win32'}}",
|
|
40
|
+
method: "shell.run",
|
|
41
|
+
params: {
|
|
42
|
+
shell: "bash",
|
|
43
|
+
message: "opencode",
|
|
44
|
+
path: "{{args.cwd}}",
|
|
45
|
+
input: true
|
|
46
|
+
}
|
|
47
|
+
}, {
|
|
48
|
+
when: "{{platform !== 'win32'}}",
|
|
49
|
+
id: "run",
|
|
50
|
+
method: "shell.run",
|
|
51
|
+
params: {
|
|
52
|
+
message: "opencode",
|
|
53
|
+
path: "{{args.cwd}}",
|
|
54
|
+
input: true
|
|
55
|
+
}
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const opencode = require("../opencode/pinokio")
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
...opencode,
|
|
5
|
+
title: "Opencode Auto",
|
|
6
|
+
description: "OpenCode with permission prompts automatically approved unless explicitly denied.",
|
|
7
|
+
run: opencode.run.map((step) => ({
|
|
8
|
+
...step,
|
|
9
|
+
params: {
|
|
10
|
+
...step.params,
|
|
11
|
+
message: "opencode --auto",
|
|
12
|
+
},
|
|
13
|
+
})),
|
|
14
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
const assert = require("node:assert/strict")
|
|
2
|
+
const fs = require("node:fs/promises")
|
|
3
|
+
const path = require("node:path")
|
|
4
|
+
const test = require("node:test")
|
|
5
|
+
const { JSDOM, VirtualConsole } = require("jsdom")
|
|
6
|
+
|
|
7
|
+
const commonScriptPath = path.resolve(__dirname, "../server/public/common.js")
|
|
8
|
+
const exploreTemplatePath = path.resolve(__dirname, "../server/views/explore.ejs")
|
|
9
|
+
|
|
10
|
+
async function createHarness(url = "http://192.168.1.50:42000/home?mode=explore") {
|
|
11
|
+
const source = await fs.readFile(commonScriptPath, "utf8")
|
|
12
|
+
const virtualConsole = new VirtualConsole()
|
|
13
|
+
virtualConsole.on("jsdomError", (error) => {
|
|
14
|
+
throw error
|
|
15
|
+
})
|
|
16
|
+
const dom = new JSDOM("<!doctype html><body><main><iframe></iframe></main></body>", {
|
|
17
|
+
runScripts: "dangerously",
|
|
18
|
+
pretendToBeVisual: true,
|
|
19
|
+
url,
|
|
20
|
+
virtualConsole,
|
|
21
|
+
beforeParse(window) {
|
|
22
|
+
window.fetch = async () => ({ ok: true, json: async () => ({}) })
|
|
23
|
+
window.matchMedia = () => ({
|
|
24
|
+
matches: false,
|
|
25
|
+
addEventListener() {},
|
|
26
|
+
removeEventListener() {},
|
|
27
|
+
})
|
|
28
|
+
window.ResizeObserver = class {
|
|
29
|
+
observe() {}
|
|
30
|
+
disconnect() {}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
const script = dom.window.document.createElement("script")
|
|
35
|
+
script.textContent = source
|
|
36
|
+
dom.window.document.body.appendChild(script)
|
|
37
|
+
const frame = dom.window.document.querySelector("iframe")
|
|
38
|
+
frame.src = "https://pinokio.co/?embed=1&theme=dark"
|
|
39
|
+
frame.focus()
|
|
40
|
+
assert.equal(dom.window.document.activeElement, frame)
|
|
41
|
+
return { dom, frame }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function navigate(dom, frame, target, options = {}) {
|
|
45
|
+
dom.window.dispatchEvent(new dom.window.MessageEvent("message", {
|
|
46
|
+
data: { e: "pinokio:navigate", url: target },
|
|
47
|
+
origin: options.origin || "https://pinokio.co",
|
|
48
|
+
source: options.source === undefined ? frame.contentWindow : options.source,
|
|
49
|
+
}))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
test("Explore uses a stable frame identity instead of the launcher schema", async () => {
|
|
53
|
+
const source = await fs.readFile(exploreTemplatePath, "utf8")
|
|
54
|
+
|
|
55
|
+
assert.equal(source.match(/name="pinokio-explore"/g)?.length, 2)
|
|
56
|
+
assert.doesNotMatch(source, /name="<%=schema%>"/)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test("LAN Explore rebases registry download installs onto the Home Server origin", async (t) => {
|
|
60
|
+
const { dom, frame } = await createHarness()
|
|
61
|
+
t.after(() => dom.window.close())
|
|
62
|
+
|
|
63
|
+
navigate(dom, frame, "http://localhost:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo&path=api&branch=dev")
|
|
64
|
+
|
|
65
|
+
assert.equal(
|
|
66
|
+
frame.src,
|
|
67
|
+
"http://192.168.1.50:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo&path=api&branch=dev",
|
|
68
|
+
)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test("LAN Explore handles registry installs when mobile Safari leaves the parent body focused", async (t) => {
|
|
72
|
+
const { dom, frame } = await createHarness()
|
|
73
|
+
t.after(() => dom.window.close())
|
|
74
|
+
dom.window.document.body.tabIndex = -1
|
|
75
|
+
dom.window.document.body.focus()
|
|
76
|
+
assert.equal(dom.window.document.activeElement, dom.window.document.body)
|
|
77
|
+
|
|
78
|
+
navigate(dom, frame, "http://localhost:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo&path=api")
|
|
79
|
+
|
|
80
|
+
assert.equal(
|
|
81
|
+
frame.src,
|
|
82
|
+
"http://192.168.1.50:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo&path=api",
|
|
83
|
+
)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test("LAN Explore rebases valid checkpoint installs onto the Home Server origin", async (t) => {
|
|
87
|
+
const { dom, frame } = await createHarness()
|
|
88
|
+
t.after(() => dom.window.close())
|
|
89
|
+
const hash = `sha256%3A${"a".repeat(64)}`
|
|
90
|
+
|
|
91
|
+
navigate(dom, frame, `http://localhost:42000/checkpoints?registry=https%3A%2F%2Fapi.pinokio.co&hash=${hash}&path=api`)
|
|
92
|
+
|
|
93
|
+
assert.equal(
|
|
94
|
+
frame.src,
|
|
95
|
+
`http://192.168.1.50:42000/checkpoints?registry=https%3A%2F%2Fapi.pinokio.co&hash=${hash}&path=api`,
|
|
96
|
+
)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const blockedCases = [
|
|
100
|
+
["unrelated local route", "http://localhost:42000/tasker?vars=url", {}],
|
|
101
|
+
["download without a URI", "http://localhost:42000/pinokio/download", {}],
|
|
102
|
+
["checkpoint with an invalid hash", "http://localhost:42000/checkpoints?registry=https%3A%2F%2Fapi.pinokio.co&hash=abc", {}],
|
|
103
|
+
["different message origin", "http://localhost:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo", { origin: "https://example.com" }],
|
|
104
|
+
["different message source", "http://localhost:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo", { source: null }],
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
for (const [label, target, options] of blockedCases) {
|
|
108
|
+
test(`LAN Explore leaves ${label} blocked`, async (t) => {
|
|
109
|
+
const { dom, frame } = await createHarness()
|
|
110
|
+
t.after(() => dom.window.close())
|
|
111
|
+
const original = frame.src
|
|
112
|
+
|
|
113
|
+
navigate(dom, frame, target, options)
|
|
114
|
+
|
|
115
|
+
assert.equal(frame.src, original)
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
test("the additive branch does not run outside Explore", async (t) => {
|
|
120
|
+
const { dom, frame } = await createHarness("http://192.168.1.50:42000/home")
|
|
121
|
+
t.after(() => dom.window.close())
|
|
122
|
+
const original = frame.src
|
|
123
|
+
|
|
124
|
+
navigate(dom, frame, "http://localhost:42000/pinokio/download?uri=https%3A%2F%2Fgithub.com%2Facme%2Fdemo")
|
|
125
|
+
|
|
126
|
+
assert.equal(frame.src, original)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test("localhost keeps the existing same-origin navigation behavior", async (t) => {
|
|
130
|
+
const { dom, frame } = await createHarness("http://localhost:42000/home?mode=explore")
|
|
131
|
+
t.after(() => dom.window.close())
|
|
132
|
+
|
|
133
|
+
navigate(dom, frame, "http://localhost:42000/existing-local-route?value=1")
|
|
134
|
+
|
|
135
|
+
assert.equal(frame.src, "http://localhost:42000/existing-local-route?value=1")
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test("LAN keeps the existing same-origin navigation behavior", async (t) => {
|
|
139
|
+
const { dom, frame } = await createHarness()
|
|
140
|
+
t.after(() => dom.window.close())
|
|
141
|
+
|
|
142
|
+
navigate(dom, frame, "http://192.168.1.50:42000/existing-lan-route?value=1")
|
|
143
|
+
|
|
144
|
+
assert.equal(frame.src, "http://192.168.1.50:42000/existing-lan-route?value=1")
|
|
145
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const assert = require("node:assert/strict")
|
|
2
|
+
const test = require("node:test")
|
|
3
|
+
|
|
4
|
+
const opencode = require("../system/plugin/opencode/pinokio")
|
|
5
|
+
const opencodeAuto = require("../system/plugin/opencode-auto/pinokio")
|
|
6
|
+
|
|
7
|
+
test("OpenCode installed status follows executable availability", async () => {
|
|
8
|
+
const lookups = []
|
|
9
|
+
const kernel = {
|
|
10
|
+
which(name) {
|
|
11
|
+
lookups.push(name)
|
|
12
|
+
return null
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
assert.equal(await opencode.installed(kernel, {}), false)
|
|
17
|
+
|
|
18
|
+
kernel.which = (name) => {
|
|
19
|
+
lookups.push(name)
|
|
20
|
+
return "/pinokio/bin/npm/bin/opencode"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
assert.equal(await opencode.installed(kernel, {}), true)
|
|
24
|
+
assert.deepEqual(lookups, ["opencode", "opencode"])
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test("OpenCode Auto shares the managed lifecycle and launches in auto mode", () => {
|
|
28
|
+
for (const action of ["install", "uninstall", "update", "installed"]) {
|
|
29
|
+
assert.equal(opencodeAuto[action], opencode[action])
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
assert.equal(opencodeAuto.run.length, opencode.run.length)
|
|
33
|
+
for (let index = 0; index < opencodeAuto.run.length; index += 1) {
|
|
34
|
+
const normalStep = opencode.run[index]
|
|
35
|
+
const autoStep = opencodeAuto.run[index]
|
|
36
|
+
|
|
37
|
+
assert.equal(autoStep.when, normalStep.when)
|
|
38
|
+
assert.equal(autoStep.id, normalStep.id)
|
|
39
|
+
assert.equal(autoStep.method, normalStep.method)
|
|
40
|
+
assert.equal(autoStep.params.path, normalStep.params.path)
|
|
41
|
+
assert.equal(autoStep.params.input, normalStep.params.input)
|
|
42
|
+
assert.equal(autoStep.params.shell, normalStep.params.shell)
|
|
43
|
+
assert.equal(autoStep.params.message, "opencode --auto")
|
|
44
|
+
}
|
|
45
|
+
})
|
|
@@ -237,6 +237,34 @@ test("resolveActionSteps links system plugin setup prompts to plugin detail", as
|
|
|
237
237
|
assert.equal(steps[0].params.target, "_parent")
|
|
238
238
|
})
|
|
239
239
|
|
|
240
|
+
test("process uses kernel bin as a bundled plugin's implicit cwd", async () => {
|
|
241
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), "pinokio-plugin-cwd-"))
|
|
242
|
+
try {
|
|
243
|
+
const virtualSystemRoot = path.join(root, "app.asar", "node_modules", "pinokiod", "system")
|
|
244
|
+
const virtualPluginDir = path.join(virtualSystemRoot, "plugin", "demo")
|
|
245
|
+
|
|
246
|
+
const kernel = createKernel()
|
|
247
|
+
kernel.homedir = path.join(root, "pinokio")
|
|
248
|
+
kernel.path = (...parts) => path.join(kernel.homedir, ...parts)
|
|
249
|
+
kernel.shell = { init: async () => {} }
|
|
250
|
+
kernel.systemPath = (...parts) => path.join(virtualSystemRoot, ...parts)
|
|
251
|
+
const api = new Api(kernel)
|
|
252
|
+
const request = { uri: path.join(virtualPluginDir, "pinokio.js") }
|
|
253
|
+
api.logSessions = null
|
|
254
|
+
api.resolveScript = async () => ({
|
|
255
|
+
cwd: virtualPluginDir,
|
|
256
|
+
script: { run: [{ method: "shell.run", params: { message: "install" } }] },
|
|
257
|
+
})
|
|
258
|
+
api.queue = () => {}
|
|
259
|
+
|
|
260
|
+
await api.process(request, () => {})
|
|
261
|
+
|
|
262
|
+
assert.equal(request.cwd, kernel.path("bin"))
|
|
263
|
+
} finally {
|
|
264
|
+
await fs.rm(root, { recursive: true, force: true })
|
|
265
|
+
}
|
|
266
|
+
})
|
|
267
|
+
|
|
240
268
|
test("resolveActionSteps runs plugin action directly when installed check passes", async () => {
|
|
241
269
|
const api = new Api(createKernel())
|
|
242
270
|
const request = { id: "plugin-run-installed", path: "/pinokio/plugin/demo/pinokio.js" }
|
|
@@ -208,7 +208,7 @@ module.exports = {
|
|
|
208
208
|
const systemPlugins = menu.filter((item) => item.source === "system")
|
|
209
209
|
const localPlugins = menu.filter((item) => item.source === "local")
|
|
210
210
|
|
|
211
|
-
assert.strictEqual(systemPlugins.length,
|
|
211
|
+
assert.strictEqual(systemPlugins.length, 12)
|
|
212
212
|
assert.ok(systemPlugins.every((item) => item.system === true))
|
|
213
213
|
assert.ok(systemPlugins.every((item) => item.href.startsWith("/pinokio/run/plugin/")))
|
|
214
214
|
assert.ok(systemPlugins.every((item) => item.image.startsWith("/pinokio/asset/plugin/")))
|