pinokiod 7.2.18 → 7.3.0
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 +2 -0
- package/kernel/api/index.js +13 -179
- package/kernel/api/process/index.js +44 -99
- package/kernel/bin/conda-python.js +30 -0
- package/kernel/bin/conda.js +22 -3
- package/kernel/bin/huggingface.js +1 -1
- package/kernel/bin/index.js +11 -1
- package/kernel/environment.js +11 -205
- package/kernel/git.js +13 -0
- package/kernel/index.js +1 -64
- package/kernel/plugin.js +58 -6
- package/kernel/prototype.js +0 -4
- package/kernel/shell.js +2 -23
- package/kernel/util.js +0 -60
- package/package.json +1 -1
- package/server/index.js +171 -229
- package/server/lib/content_validation.js +33 -47
- package/server/public/common.js +29 -103
- package/server/public/create-launcher.js +31 -4
- package/server/public/electron.css +6 -0
- package/server/public/style.css +0 -337
- package/server/public/task-launcher.css +3 -11
- package/server/public/task-launcher.js +32 -5
- package/server/public/universal-launcher.js +26 -3
- package/server/socket.js +11 -22
- package/server/views/app.ejs +30 -167
- package/server/views/d.ejs +35 -33
- package/server/views/editor.ejs +4 -25
- package/server/views/partials/main_sidebar.ejs +0 -1
- package/server/views/partials/menu.ejs +1 -1
- package/server/views/pre.ejs +1 -1
- package/server/views/shell.ejs +3 -11
- package/server/views/task_launch.ejs +10 -10
- package/server/views/terminal.ejs +5 -34
- package/spec/INSTRUCTION_SYNC.md +5 -5
- package/kernel/agent_instructions.js +0 -166
- package/kernel/api/shell_run_template.js +0 -273
- package/kernel/api/uri/index.js +0 -51
- package/kernel/plugin_sources.js +0 -289
- package/kernel/watch/context.js +0 -42
- package/kernel/watch/drivers/fs.js +0 -71
- package/kernel/watch/drivers/poll.js +0 -33
- package/kernel/watch/index.js +0 -185
- package/server/features/index.js +0 -13
- package/server/features/notes/index.js +0 -41
- package/server/features/notes/parser.js +0 -174
- package/server/features/notes/public/notes.css +0 -955
- package/server/features/notes/public/notes.js +0 -1149
- package/server/features/notes/registry_import.js +0 -412
- package/server/features/notes/routes.js +0 -156
- package/server/features/notes/service.js +0 -326
- package/server/features/notes/watcher.js +0 -74
- package/server/lib/workspace_catalog.js +0 -151
- package/server/lib/workspace_runtime.js +0 -390
- package/server/public/tasker.css +0 -336
- package/server/public/tasker.js +0 -407
- package/server/routes/workspaces.js +0 -44
- package/server/views/partials/workspace_row.ejs +0 -61
- package/server/views/tasker.ejs +0 -40
- package/server/views/workspaces.ejs +0 -813
- package/system/plugin/antigravity/antigravity.png +0 -0
- package/system/plugin/antigravity/pinokio.js +0 -35
- package/system/plugin/claude/claude.png +0 -0
- package/system/plugin/claude/pinokio.js +0 -61
- package/system/plugin/claude-auto/claude.png +0 -0
- package/system/plugin/claude-auto/pinokio.js +0 -72
- package/system/plugin/claude-desktop/icon.jpeg +0 -0
- package/system/plugin/claude-desktop/pinokio.js +0 -37
- package/system/plugin/codex/openai.webp +0 -0
- package/system/plugin/codex/pinokio.js +0 -56
- package/system/plugin/codex-auto/openai.webp +0 -0
- package/system/plugin/codex-auto/pinokio.js +0 -63
- package/system/plugin/codex-desktop/icon.png +0 -0
- package/system/plugin/codex-desktop/pinokio.js +0 -37
- package/system/plugin/crush/crush.png +0 -0
- package/system/plugin/crush/pinokio.js +0 -29
- package/system/plugin/cursor/cursor.jpeg +0 -0
- package/system/plugin/cursor/pinokio.js +0 -37
- package/system/plugin/gemini/gemini.jpeg +0 -0
- package/system/plugin/gemini/pinokio.js +0 -38
- package/system/plugin/gemini-auto/gemini.jpeg +0 -0
- package/system/plugin/gemini-auto/pinokio.js +0 -41
- package/system/plugin/qwen/pinokio.js +0 -48
- package/system/plugin/qwen/qwen.png +0 -0
- package/system/plugin/vscode/pinokio.js +0 -34
- package/system/plugin/vscode/vscode.png +0 -0
- package/system/plugin/windsurf/pinokio.js +0 -37
- package/system/plugin/windsurf/windsurf.png +0 -0
- package/test/plugin-sources.test.js +0 -45
package/Dockerfile
CHANGED
|
@@ -37,6 +37,8 @@ RUN mkdir -p /app/.pinokio-seed \
|
|
|
37
37
|
&& rm -rf /app/.pinokio-seed/network/system/.git \
|
|
38
38
|
&& rm -rf /app/.pinokio-seed/plugin \
|
|
39
39
|
&& mkdir -p /app/.pinokio-seed/plugin \
|
|
40
|
+
&& git clone --depth 1 https://github.com/pinokiocomputer/code /app/.pinokio-seed/plugin/code \
|
|
41
|
+
&& rm -rf /app/.pinokio-seed/plugin/code/.git \
|
|
40
42
|
&& rm -rf /app/.pinokio-seed/prototype/system \
|
|
41
43
|
&& mkdir -p /app/.pinokio-seed/prototype \
|
|
42
44
|
&& git clone --depth 1 https://github.com/pinokiocomputer/proto /app/.pinokio-seed/prototype/system \
|
package/kernel/api/index.js
CHANGED
|
@@ -11,8 +11,6 @@ const fastq = require('fastq')
|
|
|
11
11
|
const Loader = require("../loader")
|
|
12
12
|
const Environment = require("../environment")
|
|
13
13
|
const Util = require('../util')
|
|
14
|
-
const ShellRunTemplate = require('./shell_run_template')
|
|
15
|
-
const AgentInstructions = require("../agent_instructions")
|
|
16
14
|
|
|
17
15
|
class Api {
|
|
18
16
|
constructor(kernel) {
|
|
@@ -28,22 +26,8 @@ class Api {
|
|
|
28
26
|
this.proxies = {}
|
|
29
27
|
this.mods = {}
|
|
30
28
|
this.child_procs = {}
|
|
31
|
-
this.resolved_actions = {}
|
|
32
29
|
this.lproxy = new Lproxy()
|
|
33
30
|
}
|
|
34
|
-
startData(rpc) {
|
|
35
|
-
if (rpc && rpc.method === "process.wait" && rpc.params && typeof rpc.params === "object" && !Array.isArray(rpc.params)) {
|
|
36
|
-
let data = rpc
|
|
37
|
-
if (typeof data.title === "undefined" && typeof rpc.params.title !== "undefined") {
|
|
38
|
-
data = { ...data, title: rpc.params.title }
|
|
39
|
-
}
|
|
40
|
-
if (typeof data.description === "undefined" && typeof rpc.params.description !== "undefined") {
|
|
41
|
-
data = { ...data, description: rpc.params.description }
|
|
42
|
-
}
|
|
43
|
-
return data
|
|
44
|
-
}
|
|
45
|
-
return rpc
|
|
46
|
-
}
|
|
47
31
|
async launcher_path(name) {
|
|
48
32
|
let root_path = this.kernel.path("api", name)
|
|
49
33
|
let primary_path = path.resolve(root_path, "pinokio.js")
|
|
@@ -235,7 +219,7 @@ class Api {
|
|
|
235
219
|
meta.ui = `/p/${api_name}`
|
|
236
220
|
meta.browse = `/p/${api_name}/dev`
|
|
237
221
|
} else {
|
|
238
|
-
meta.icon = meta.icon ? `/asset/api/${api_name}/${
|
|
222
|
+
meta.icon = meta.icon ? `/asset/api/${api_name}/${meta.icon}` : "/pinokio-black.png"
|
|
239
223
|
meta.link = `/p/${api_name}/${relpath}/dev#n1`
|
|
240
224
|
meta.web_path = `/api/${api_name}/${relpath}`
|
|
241
225
|
meta.ui = `/p/${api_name}/${relpath}`
|
|
@@ -414,84 +398,6 @@ class Api {
|
|
|
414
398
|
let result = await endpoint(rpc, ondata, this.kernel)
|
|
415
399
|
return result
|
|
416
400
|
}
|
|
417
|
-
requestId(request) {
|
|
418
|
-
return request ? (request.id || request.path) : null
|
|
419
|
-
}
|
|
420
|
-
clearResolvedAction(requestOrId) {
|
|
421
|
-
const id = typeof requestOrId === "string" ? requestOrId : this.requestId(requestOrId)
|
|
422
|
-
if (id) {
|
|
423
|
-
delete this.resolved_actions[id]
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
setRunning(request, done) {
|
|
427
|
-
const id = this.requestId(request)
|
|
428
|
-
if (!id) {
|
|
429
|
-
return
|
|
430
|
-
}
|
|
431
|
-
this.running[id] = true
|
|
432
|
-
this.done[id] = done
|
|
433
|
-
}
|
|
434
|
-
isActionCandidate(action) {
|
|
435
|
-
return (Array.isArray(action) && action.length > 0) || typeof action === "function"
|
|
436
|
-
}
|
|
437
|
-
async actionContext({ request, script, scriptDir, actionKey, input, args }) {
|
|
438
|
-
const cwd = request.cwd || scriptDir
|
|
439
|
-
const id = this.requestId(request)
|
|
440
|
-
const env = await Environment.get2(request.path, this.kernel)
|
|
441
|
-
this.kernel.template.update({ envs: env, env })
|
|
442
|
-
const port = await this.kernel.port()
|
|
443
|
-
const name = path.relative(this.kernel.path("api"), scriptDir)
|
|
444
|
-
return {
|
|
445
|
-
kernel: this.kernel,
|
|
446
|
-
info: this.kernel.info,
|
|
447
|
-
script: this.kernel.script,
|
|
448
|
-
action: actionKey,
|
|
449
|
-
input,
|
|
450
|
-
args,
|
|
451
|
-
global: (this.kernel.memory.global[id] || {}),
|
|
452
|
-
local: (this.kernel.memory.local[id] || {}),
|
|
453
|
-
key: this.kernel.memory.key,
|
|
454
|
-
uri: request.uri,
|
|
455
|
-
cwd,
|
|
456
|
-
dirname: scriptDir,
|
|
457
|
-
exists: (...args) => {
|
|
458
|
-
return fs.existsSync(path.resolve(cwd, ...args))
|
|
459
|
-
},
|
|
460
|
-
running: (...args) => {
|
|
461
|
-
let fullpath = path.resolve(cwd, ...args)
|
|
462
|
-
return this.running[fullpath]
|
|
463
|
-
},
|
|
464
|
-
name,
|
|
465
|
-
self: script,
|
|
466
|
-
port,
|
|
467
|
-
env,
|
|
468
|
-
envs: env,
|
|
469
|
-
...this.kernel.vars,
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
async resolveActionSteps({ request, script, scriptDir, actionKey, input, args }) {
|
|
473
|
-
const id = this.requestId(request)
|
|
474
|
-
const cached = id ? this.resolved_actions[id] : null
|
|
475
|
-
if (cached && cached.actionKey === actionKey && Array.isArray(cached.steps)) {
|
|
476
|
-
return cached.steps
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
const action = script ? script[actionKey] : null
|
|
480
|
-
let steps
|
|
481
|
-
if (Array.isArray(action)) {
|
|
482
|
-
steps = action
|
|
483
|
-
} else if (typeof action === "function") {
|
|
484
|
-
const context = await this.actionContext({ request, script, scriptDir, actionKey, input, args })
|
|
485
|
-
steps = await action.call(script, this.kernel, this.kernel.info, context)
|
|
486
|
-
} else {
|
|
487
|
-
steps = null
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
if (id && Array.isArray(steps)) {
|
|
491
|
-
this.resolved_actions[id] = { actionKey, steps }
|
|
492
|
-
}
|
|
493
|
-
return steps
|
|
494
|
-
}
|
|
495
401
|
async stop(req, ondata) {
|
|
496
402
|
// 1. set the "stop" flag for the uri, so the next execution in the queue for the uri will NOT queue another task
|
|
497
403
|
// 2. stream a message closing the socket
|
|
@@ -500,24 +406,16 @@ class Api {
|
|
|
500
406
|
// /Users/x/pinokio/prototype/system/aicode/template/claude.json?cwd=/Users/x/pinokio/api/MMAudio.git
|
|
501
407
|
// take the first part only since the rest is the cwd
|
|
502
408
|
req.params.uri = req.params.id.split("?")[0]
|
|
503
|
-
this.clearResolvedAction(req.params.id)
|
|
504
409
|
}
|
|
505
410
|
|
|
506
411
|
// 1. if the scropt has 'on.stop', run it when stopping
|
|
507
412
|
let requestPath = this.filePath(req.params.uri)
|
|
508
|
-
this.clearResolvedAction(requestPath)
|
|
509
413
|
let { cwd, script } = await this.resolveScript(requestPath)
|
|
510
414
|
if (script.on) {
|
|
511
415
|
if (script.on.stop) {
|
|
512
416
|
await this.process(script.on.stop)
|
|
513
417
|
}
|
|
514
418
|
}
|
|
515
|
-
if (this.kernel.watch && typeof this.kernel.watch.stop === "function") {
|
|
516
|
-
if (req.params.id) {
|
|
517
|
-
await this.kernel.watch.stop(req.params.id)
|
|
518
|
-
}
|
|
519
|
-
await this.kernel.watch.stop(requestPath)
|
|
520
|
-
}
|
|
521
419
|
// reset modules
|
|
522
420
|
let modpath = this.resolvePath(cwd, req.params.uri)
|
|
523
421
|
if (this.child_procs[modpath]) {
|
|
@@ -992,7 +890,7 @@ class Api {
|
|
|
992
890
|
|
|
993
891
|
let { cwd: scriptDir, script } = await this.resolveScript(request.path)
|
|
994
892
|
const actionKey = request.action || 'run'
|
|
995
|
-
const steps =
|
|
893
|
+
const steps = (script && Array.isArray(script[actionKey])) ? script[actionKey] : []
|
|
996
894
|
const totalSteps = steps.length
|
|
997
895
|
|
|
998
896
|
let name = path.relative(this.kernel.path("api"), scriptDir)
|
|
@@ -1112,7 +1010,6 @@ class Api {
|
|
|
1112
1010
|
}
|
|
1113
1011
|
// replace {{{ }}} with {{ }}
|
|
1114
1012
|
rpc = this.kernel.template.flatten(rpc)
|
|
1115
|
-
rpc = ShellRunTemplate.renderEnvArgs(this.kernel, rpc, memory)
|
|
1116
1013
|
|
|
1117
1014
|
// 6. rpc must have method names
|
|
1118
1015
|
if (rpc.method) {
|
|
@@ -1281,7 +1178,7 @@ class Api {
|
|
|
1281
1178
|
this.ondata({
|
|
1282
1179
|
id: request.id || request.path,
|
|
1283
1180
|
type: "start",
|
|
1284
|
-
data:
|
|
1181
|
+
data: rpc
|
|
1285
1182
|
})
|
|
1286
1183
|
|
|
1287
1184
|
// DEPRECATED APIS
|
|
@@ -1557,41 +1454,6 @@ class Api {
|
|
|
1557
1454
|
}
|
|
1558
1455
|
return false
|
|
1559
1456
|
}
|
|
1560
|
-
async startWatchersForRequest(request, script, scriptDir, input) {
|
|
1561
|
-
if (!this.kernel.watch || typeof this.kernel.watch.startForScript !== "function") {
|
|
1562
|
-
return
|
|
1563
|
-
}
|
|
1564
|
-
const id = request.id || request.path
|
|
1565
|
-
if (!id) {
|
|
1566
|
-
return
|
|
1567
|
-
}
|
|
1568
|
-
const cwd = request.cwd || scriptDir
|
|
1569
|
-
await this.kernel.watch.startForScript({
|
|
1570
|
-
id,
|
|
1571
|
-
request,
|
|
1572
|
-
script,
|
|
1573
|
-
cwd,
|
|
1574
|
-
dirname: scriptDir,
|
|
1575
|
-
input,
|
|
1576
|
-
args: input
|
|
1577
|
-
})
|
|
1578
|
-
}
|
|
1579
|
-
async ensurePluginAgentInstructions(request) {
|
|
1580
|
-
if (!request || !request.cwd || !request.path) {
|
|
1581
|
-
return
|
|
1582
|
-
}
|
|
1583
|
-
if (!AgentInstructions.isPluginScriptPath(this.kernel, request.path)) {
|
|
1584
|
-
return
|
|
1585
|
-
}
|
|
1586
|
-
try {
|
|
1587
|
-
await AgentInstructions.ensureNoteInstructionsForCwd({
|
|
1588
|
-
kernel: this.kernel,
|
|
1589
|
-
cwd: request.cwd,
|
|
1590
|
-
})
|
|
1591
|
-
} catch (e) {
|
|
1592
|
-
console.warn("[agent-instructions] failed to update note instructions:", e && e.message ? e.message : e)
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
1457
|
createQueue(queue_id, concurrency) {
|
|
1596
1458
|
this.queues[queue_id] = fastq.promise(async ({ request, rawrpc, input, step, total, cwd, args }) => {
|
|
1597
1459
|
try {
|
|
@@ -1809,12 +1671,18 @@ class Api {
|
|
|
1809
1671
|
} else {
|
|
1810
1672
|
const actionKey = request.action || 'run'
|
|
1811
1673
|
request.action = actionKey
|
|
1812
|
-
const
|
|
1674
|
+
const steps = script ? script[actionKey] : null
|
|
1813
1675
|
|
|
1814
|
-
// 3. Check if the resolved endpoint has the requested action attribute and
|
|
1815
|
-
if (
|
|
1676
|
+
// 3. Check if the resolved endpoint has the requested action attribute and it's an array
|
|
1677
|
+
if (Array.isArray(steps) && steps.length > 0) {
|
|
1816
1678
|
|
|
1817
|
-
|
|
1679
|
+
if (request.id) {
|
|
1680
|
+
this.running[request.id] = true
|
|
1681
|
+
this.done[request.id] = done
|
|
1682
|
+
} else if (request.path) {
|
|
1683
|
+
this.running[request.path] = true
|
|
1684
|
+
this.done[request.path] = done
|
|
1685
|
+
}
|
|
1818
1686
|
|
|
1819
1687
|
// set DNS
|
|
1820
1688
|
|
|
@@ -1827,40 +1695,6 @@ class Api {
|
|
|
1827
1695
|
}
|
|
1828
1696
|
|
|
1829
1697
|
const initialPayload = typeof request.input === "undefined" ? {} : request.input
|
|
1830
|
-
let steps
|
|
1831
|
-
try {
|
|
1832
|
-
steps = await this.resolveActionSteps({
|
|
1833
|
-
request,
|
|
1834
|
-
script,
|
|
1835
|
-
scriptDir: cwd,
|
|
1836
|
-
actionKey,
|
|
1837
|
-
input: initialPayload,
|
|
1838
|
-
args: initialPayload
|
|
1839
|
-
})
|
|
1840
|
-
} catch (e) {
|
|
1841
|
-
this.clearResolvedAction(request)
|
|
1842
|
-
delete this.running[this.requestId(request)]
|
|
1843
|
-
this.ondata({
|
|
1844
|
-
id: request.id || request.path,
|
|
1845
|
-
type: "error",
|
|
1846
|
-
data: e.stack,
|
|
1847
|
-
})
|
|
1848
|
-
return
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
if (!Array.isArray(steps) || steps.length === 0) {
|
|
1852
|
-
this.clearResolvedAction(request)
|
|
1853
|
-
delete this.running[this.requestId(request)]
|
|
1854
|
-
this.ondata({
|
|
1855
|
-
id: request.id || request.path,
|
|
1856
|
-
type: "error",
|
|
1857
|
-
data: `missing or invalid attribute: ${actionKey}`
|
|
1858
|
-
})
|
|
1859
|
-
return
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
await this.ensurePluginAgentInstructions(request)
|
|
1863
|
-
await this.startWatchersForRequest(request, script, cwd, initialPayload)
|
|
1864
1698
|
this.queue(request, steps[0], initialPayload, 0, steps.length, cwd, initialPayload)
|
|
1865
1699
|
|
|
1866
1700
|
} else {
|
|
@@ -34,16 +34,6 @@ class Process {
|
|
|
34
34
|
constructor() {
|
|
35
35
|
this.appApi = new AppAPI()
|
|
36
36
|
}
|
|
37
|
-
async waitIndefinitely(req, kernel) {
|
|
38
|
-
await new Promise((resolve, reject) => {
|
|
39
|
-
this.resolve = resolve
|
|
40
|
-
|
|
41
|
-
// register the process with the root uri so it can be manually resolved (with this.resolve()) later
|
|
42
|
-
if (kernel && kernel.procs && req && req.parent && req.parent.path) {
|
|
43
|
-
kernel.procs[req.parent.path] = this
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
37
|
// async start(req, ondata, kernel) {
|
|
48
38
|
// /*
|
|
49
39
|
// req := {
|
|
@@ -169,8 +159,6 @@ class Process {
|
|
|
169
159
|
/*
|
|
170
160
|
params := {
|
|
171
161
|
sec: <SECONDS>,
|
|
172
|
-
title: (optional) Title to display in the footer while waiting,
|
|
173
|
-
description: (optional) Description to display in the footer while waiting,
|
|
174
162
|
message: (optional) Description to display while waiting,
|
|
175
163
|
menu: (optional) menu to display in the modal while waiting,
|
|
176
164
|
// ok: (optional) <ok button text> (if not specified, no ok button),
|
|
@@ -181,8 +169,6 @@ class Process {
|
|
|
181
169
|
|
|
182
170
|
params := {
|
|
183
171
|
min: <MINUTES>,
|
|
184
|
-
title: (optional) Title to display in the footer while waiting,
|
|
185
|
-
description: (optional) Description to display in the footer while waiting,
|
|
186
172
|
message: (optional) Description to display while waiting,
|
|
187
173
|
menu: (optional) menu to display in the modal while waiting,
|
|
188
174
|
// ok: (optional) <ok button text> (if not specified, no ok button),
|
|
@@ -194,8 +180,6 @@ class Process {
|
|
|
194
180
|
params := {
|
|
195
181
|
url: <URL>,
|
|
196
182
|
interval: (optional) how often to retry checking (in seconds)
|
|
197
|
-
title: (optional) Title to display in the footer while waiting,
|
|
198
|
-
description: (optional) Description to display in the footer while waiting,
|
|
199
183
|
message: (optional) the message to display while retrying (default: no message)
|
|
200
184
|
}
|
|
201
185
|
|
|
@@ -214,21 +198,9 @@ class Process {
|
|
|
214
198
|
|
|
215
199
|
or
|
|
216
200
|
|
|
217
|
-
params := {
|
|
218
|
-
title: (optional) Title to display in the footer while waiting,
|
|
219
|
-
description: (optional) Description to display in the footer while waiting,
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
This waits indefinitely until the script is stopped or the wait is manually
|
|
223
|
-
resolved.
|
|
224
|
-
|
|
225
|
-
or
|
|
226
|
-
|
|
227
201
|
|
|
228
202
|
params := {
|
|
229
203
|
on: <wait-on condition https://github.com/jeffbski/wait-on>,
|
|
230
|
-
title: (optional) Title to display in the footer while waiting,
|
|
231
|
-
description: (optional) Description to display in the footer while waiting,
|
|
232
204
|
message: (optional) Description to display while waiting,
|
|
233
205
|
menu: (optional) menu to display in the modal while waiting,
|
|
234
206
|
// ok: (optional) <ok button text> (if not specified, no ok button),
|
|
@@ -240,84 +212,57 @@ class Process {
|
|
|
240
212
|
if 'cancel' is pressed before the condition is met, stops the script
|
|
241
213
|
|
|
242
214
|
*/
|
|
243
|
-
let ms
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
215
|
+
let ms
|
|
216
|
+
if (req.params) {
|
|
217
|
+
if (req.params.app || req.params.id || req.params.name) {
|
|
218
|
+
await this.appApi.waitForAppPresence(req, ondata, kernel)
|
|
219
|
+
return
|
|
248
220
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
const showFooter = req.params && (req.params.title || req.params.description)
|
|
259
|
-
if (showFooter && typeof ondata === "function") {
|
|
260
|
-
ondata(req.params, "process.wait.start")
|
|
261
|
-
}
|
|
262
|
-
try {
|
|
263
|
-
if (req.params) {
|
|
264
|
-
if (req.params.app || req.params.id || req.params.name) {
|
|
265
|
-
await this.appApi.waitForAppPresence(req, ondata, kernel)
|
|
266
|
-
return
|
|
221
|
+
// Display modal
|
|
222
|
+
if (req.params.sec || req.params.min) {
|
|
223
|
+
// Wait
|
|
224
|
+
if (req.params.sec) {
|
|
225
|
+
ms = req.params.sec * 1000
|
|
226
|
+
} else if (req.params.min) {
|
|
227
|
+
ms = req.params.min * 60 * 1000
|
|
267
228
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
// Wait
|
|
271
|
-
if (req.params.sec) {
|
|
272
|
-
ms = req.params.sec * 1000
|
|
273
|
-
} else if (req.params.min) {
|
|
274
|
-
ms = req.params.min * 60 * 1000
|
|
275
|
-
}
|
|
276
|
-
await new Promise((resolve, reject) => {
|
|
277
|
-
this.resolve = resolve
|
|
229
|
+
await new Promise((resolve, reject) => {
|
|
230
|
+
this.resolve = resolve
|
|
278
231
|
|
|
279
|
-
|
|
280
|
-
|
|
232
|
+
// register the process with the root uri so it can be manually resolved (with this.resolve()) later
|
|
233
|
+
kernel.procs[req.parent.path] = this
|
|
281
234
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
235
|
+
setTimeout(() => {
|
|
236
|
+
this.resolve()
|
|
237
|
+
}, ms)
|
|
238
|
+
})
|
|
239
|
+
} else if (req.params.uri) {
|
|
240
|
+
let interval = req.params.interval ? req.params.interval * 1000 : 1000
|
|
241
|
+
ondata(req.params, "loading.start")
|
|
242
|
+
await waitForUrl(req.params.uri, req.params.message, interval, ondata)
|
|
243
|
+
ondata(req.params, "loading.end")
|
|
244
|
+
} else if (req.params.url) {
|
|
245
|
+
let interval = req.params.interval ? req.params.interval * 1000 : 1000
|
|
246
|
+
ondata(req.params, "loading.start")
|
|
247
|
+
await waitForUrl(req.params.url, req.params.message, interval, ondata)
|
|
248
|
+
ondata(req.params, "loading.end")
|
|
249
|
+
} else if (req.params.on) {
|
|
250
|
+
// Wait
|
|
251
|
+
if (req.params.message) {
|
|
252
|
+
ondata({
|
|
253
|
+
raw: `\r\nWaiting: ${JSON.stringify(req.params.on)}\r\n`
|
|
285
254
|
})
|
|
286
|
-
|
|
287
|
-
let interval = req.params.interval ? req.params.interval * 1000 : 1000
|
|
288
|
-
ondata(req.params, "loading.start")
|
|
289
|
-
await waitForUrl(req.params.uri, req.params.message, interval, ondata)
|
|
290
|
-
ondata(req.params, "loading.end")
|
|
291
|
-
} else if (req.params.url) {
|
|
292
|
-
let interval = req.params.interval ? req.params.interval * 1000 : 1000
|
|
293
|
-
ondata(req.params, "loading.start")
|
|
294
|
-
await waitForUrl(req.params.url, req.params.message, interval, ondata)
|
|
295
|
-
ondata(req.params, "loading.end")
|
|
296
|
-
} else if (req.params.on) {
|
|
297
|
-
// Wait
|
|
298
|
-
if (req.params.message) {
|
|
299
|
-
ondata({
|
|
300
|
-
raw: `\r\nWaiting: ${JSON.stringify(req.params.on)}\r\n`
|
|
301
|
-
})
|
|
302
|
-
ondata(req.params, "wait")
|
|
303
|
-
}
|
|
304
|
-
console.log("Wait", req.params.on)
|
|
305
|
-
await waitOn(req.params.on)
|
|
306
|
-
console.log("Wait finished")
|
|
307
|
-
ondata(req.params, "wait.end")
|
|
308
|
-
} else {
|
|
309
|
-
await this.waitIndefinitely(req, kernel)
|
|
255
|
+
ondata(req.params, "wait")
|
|
310
256
|
}
|
|
311
|
-
|
|
312
|
-
await
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (waitPath && kernel && kernel.activeProcessWaits) {
|
|
316
|
-
delete kernel.activeProcessWaits[waitPath]
|
|
317
|
-
}
|
|
318
|
-
if (showFooter && typeof ondata === "function") {
|
|
319
|
-
ondata(req.params, "process.wait.end")
|
|
257
|
+
console.log("Wait", req.params.on)
|
|
258
|
+
await waitOn(req.params.on)
|
|
259
|
+
console.log("Wait finished")
|
|
260
|
+
ondata(req.params, "wait.end")
|
|
320
261
|
}
|
|
262
|
+
} else {
|
|
263
|
+
await new Promise((resolve, reject) => {
|
|
264
|
+
this.resolve = resolve
|
|
265
|
+
})
|
|
321
266
|
}
|
|
322
267
|
}
|
|
323
268
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const semver = require('semver')
|
|
2
|
+
|
|
3
|
+
const WINDOWS_PYTHON_SSL_FIX_SPEC = "python=3.10.20=*_1_cpython"
|
|
4
|
+
const WINDOWS_PYTHON_SSL_FIX_VERSION = "3.10.20"
|
|
5
|
+
|
|
6
|
+
const condaBuildNumber = (build) => {
|
|
7
|
+
const chunks = String(build || "").split("_").reverse()
|
|
8
|
+
const buildNumber = chunks.find((chunk) => /^\d+$/.test(chunk))
|
|
9
|
+
return buildNumber ? Number(buildNumber) : null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const isWindowsPythonSslFixed = (version, build) => {
|
|
13
|
+
const coerced = semver.coerce(version)
|
|
14
|
+
if (!coerced) {
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
17
|
+
if (!semver.satisfies(coerced, ">=3.10.20 <3.11.0")) {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
if (semver.eq(coerced, WINDOWS_PYTHON_SSL_FIX_VERSION)) {
|
|
21
|
+
const buildNumber = condaBuildNumber(build)
|
|
22
|
+
return typeof buildNumber === "number" && buildNumber >= 1
|
|
23
|
+
}
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
WINDOWS_PYTHON_SSL_FIX_SPEC,
|
|
29
|
+
isWindowsPythonSslFixed,
|
|
30
|
+
}
|
package/kernel/bin/conda.js
CHANGED
|
@@ -4,6 +4,11 @@ const fetch = require('cross-fetch')
|
|
|
4
4
|
const { glob } = require('glob')
|
|
5
5
|
const semver = require('semver')
|
|
6
6
|
const { buildCondaListFromMeta } = require('./conda-meta')
|
|
7
|
+
const {
|
|
8
|
+
WINDOWS_PYTHON_SSL_FIX_SPEC,
|
|
9
|
+
isWindowsPythonSslFixed,
|
|
10
|
+
} = require('./conda-python')
|
|
11
|
+
|
|
7
12
|
class Conda {
|
|
8
13
|
description = "Pinokio uses Conda to install various useful programs in an isolated manner."
|
|
9
14
|
urls = {
|
|
@@ -160,6 +165,7 @@ report_errors: false`)
|
|
|
160
165
|
let conda_check = {}
|
|
161
166
|
let conda = new Set()
|
|
162
167
|
let conda_versions = {}
|
|
168
|
+
let conda_builds = {}
|
|
163
169
|
let start = false
|
|
164
170
|
for(let line of lines) {
|
|
165
171
|
if (start) {
|
|
@@ -167,8 +173,10 @@ report_errors: false`)
|
|
|
167
173
|
if (chunks.length > 2) {
|
|
168
174
|
let name = chunks[0]
|
|
169
175
|
let version = chunks[1]
|
|
176
|
+
let build = chunks[2]
|
|
170
177
|
conda.add(name)
|
|
171
178
|
conda_versions[name] = version
|
|
179
|
+
conda_builds[name] = build
|
|
172
180
|
if (name === "conda") {
|
|
173
181
|
conda_check.conda = true
|
|
174
182
|
// //if (String(version) === "24.11.1") {
|
|
@@ -206,6 +214,9 @@ report_errors: false`)
|
|
|
206
214
|
// console.log("semver NOT satisfied")
|
|
207
215
|
//}
|
|
208
216
|
}
|
|
217
|
+
if (name === "python") {
|
|
218
|
+
conda_check.python = this.kernel.platform !== "win32" || isWindowsPythonSslFixed(version, build)
|
|
219
|
+
}
|
|
209
220
|
}
|
|
210
221
|
} else {
|
|
211
222
|
if (/.*name.*version.*build.*channel/i.test(line)) {
|
|
@@ -215,7 +226,8 @@ report_errors: false`)
|
|
|
215
226
|
}
|
|
216
227
|
this.kernel.bin.installed.conda = conda
|
|
217
228
|
this.kernel.bin.installed.conda_versions = conda_versions
|
|
218
|
-
|
|
229
|
+
this.kernel.bin.installed.conda_builds = conda_builds
|
|
230
|
+
return conda_check.conda && conda_check.mamba && conda_check.sqlite && (this.kernel.platform !== "win32" || conda_check.python)
|
|
219
231
|
//return conda_check.conda && conda_check.mamba
|
|
220
232
|
}
|
|
221
233
|
async install(req, ondata) {
|
|
@@ -300,10 +312,18 @@ report_errors: false`)
|
|
|
300
312
|
}).join(" ")
|
|
301
313
|
console.log("Conda dependencies to install", { mods })
|
|
302
314
|
|
|
315
|
+
let condaPackages = [
|
|
316
|
+
`"sqlite=3.47.2"`,
|
|
317
|
+
`"conda-libmamba-solver>=25.4.0"`,
|
|
318
|
+
]
|
|
319
|
+
if (this.kernel.platform === "win32") {
|
|
320
|
+
condaPackages.unshift(`"${WINDOWS_PYTHON_SSL_FIX_SPEC}"`)
|
|
321
|
+
}
|
|
322
|
+
|
|
303
323
|
let cmds = [
|
|
304
324
|
//"conda clean -y --index-cache",
|
|
305
325
|
"conda clean -y --all",
|
|
306
|
-
`conda install -y -c conda-forge
|
|
326
|
+
`conda install -y -c conda-forge ${condaPackages.join(" ")} ${mods}`.trim(),
|
|
307
327
|
|
|
308
328
|
// `conda config --file ${this.kernel.path('condarc')} --set remote_connect_timeout_secs 20`,
|
|
309
329
|
// `conda config --file ${this.kernel.path('condarc')} --set remote_read_timeout_secs 300`,
|
|
@@ -339,7 +359,6 @@ report_errors: false`)
|
|
|
339
359
|
//if (this.kernel.platform === "win32" || this.kernel.platform === "darwin") {
|
|
340
360
|
// cmds.push("conda install -y conda-libmamba-solver=24.7.0 conda=24.7.1 --freeze-installed")
|
|
341
361
|
//}
|
|
342
|
-
|
|
343
362
|
await this.kernel.bin.exec({
|
|
344
363
|
message: cmds,
|
|
345
364
|
env: {
|
|
@@ -18,7 +18,7 @@ class Huggingface {
|
|
|
18
18
|
let version = this.kernel.bin.installed.conda_versions.huggingface_hub
|
|
19
19
|
if (version) {
|
|
20
20
|
let coerced = semver.coerce(version)
|
|
21
|
-
if (
|
|
21
|
+
if (semver.satisfies(coerced, ">=1.0.1")) {
|
|
22
22
|
return true
|
|
23
23
|
}
|
|
24
24
|
}
|
package/kernel/bin/index.js
CHANGED
|
@@ -22,6 +22,7 @@ const VS = require("./vs")
|
|
|
22
22
|
const Cuda = require("./cuda")
|
|
23
23
|
const Torch = require("./torch")
|
|
24
24
|
const { buildCondaListFromMeta } = require('./conda-meta')
|
|
25
|
+
const { isWindowsPythonSslFixed } = require('./conda-python')
|
|
25
26
|
const { glob } = require('glob')
|
|
26
27
|
const fakeUa = require('fake-useragent');
|
|
27
28
|
const fse = require('fs-extra')
|
|
@@ -348,6 +349,8 @@ class Bin {
|
|
|
348
349
|
let conda_check = {}
|
|
349
350
|
let conda = new Set()
|
|
350
351
|
let conda_versions = {}
|
|
352
|
+
let conda_builds = {}
|
|
353
|
+
this.correct_conda = false
|
|
351
354
|
|
|
352
355
|
//////////////////////////////////////////////////////////////////
|
|
353
356
|
// exception handling
|
|
@@ -386,8 +389,10 @@ class Bin {
|
|
|
386
389
|
if (chunks.length > 2) {
|
|
387
390
|
let name = chunks[0]
|
|
388
391
|
let version = chunks[1]
|
|
392
|
+
let build = chunks[2]
|
|
389
393
|
conda.add(name)
|
|
390
394
|
conda_versions[name] = version
|
|
395
|
+
conda_builds[name] = build
|
|
391
396
|
if (name === "conda") {
|
|
392
397
|
conda_check.conda = true
|
|
393
398
|
}
|
|
@@ -408,6 +413,9 @@ class Bin {
|
|
|
408
413
|
conda_check.sqlite = true
|
|
409
414
|
}
|
|
410
415
|
}
|
|
416
|
+
if (name === "python") {
|
|
417
|
+
conda_check.python = this.platform !== "win32" || isWindowsPythonSslFixed(version, build)
|
|
418
|
+
}
|
|
411
419
|
}
|
|
412
420
|
} else {
|
|
413
421
|
if (/.*name.*version.*build.*channel/i.test(line)) {
|
|
@@ -416,13 +424,14 @@ class Bin {
|
|
|
416
424
|
}
|
|
417
425
|
}
|
|
418
426
|
|
|
419
|
-
if (conda_check.conda && conda_check.mamba && conda_check.sqlite) {
|
|
427
|
+
if (conda_check.conda && conda_check.mamba && conda_check.sqlite && (this.platform !== "win32" || conda_check.python)) {
|
|
420
428
|
//if (conda_check.conda && conda_check.mamba) {
|
|
421
429
|
this.correct_conda = true
|
|
422
430
|
}
|
|
423
431
|
}
|
|
424
432
|
this.installed.conda = conda
|
|
425
433
|
this.installed.conda_versions = conda_versions
|
|
434
|
+
this.installed.conda_builds = conda_builds
|
|
426
435
|
}
|
|
427
436
|
async refreshInstalled() {
|
|
428
437
|
|
|
@@ -430,6 +439,7 @@ class Bin {
|
|
|
430
439
|
|
|
431
440
|
this.installed_initialized = false
|
|
432
441
|
this.requirements_cache = {}
|
|
442
|
+
this.correct_conda = false
|
|
433
443
|
|
|
434
444
|
//this.installed = {}
|
|
435
445
|
|