pinokiod 7.2.18 → 7.3.1
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-pins.js +53 -0
- package/kernel/bin/conda.js +35 -6
- package/kernel/bin/huggingface.js +1 -1
- package/kernel/bin/index.js +15 -2
- 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,53 @@
|
|
|
1
|
+
const semver = require('semver')
|
|
2
|
+
|
|
3
|
+
const CONDA_PIN_VERSION = "25.5.1"
|
|
4
|
+
const DEFAULT_SQLITE_PIN_VERSION = "3.47.2"
|
|
5
|
+
const WINDOWS_SQLITE_PIN_VERSION = "3.53.2"
|
|
6
|
+
const WINDOWS_PYTHON_SSL_FIX_SPEC = "python=3.10.20=*_1_cpython"
|
|
7
|
+
const WINDOWS_PYTHON_SSL_FIX_VERSION = "3.10.20"
|
|
8
|
+
|
|
9
|
+
const sqlitePinVersion = (platform) => {
|
|
10
|
+
return platform === "win32" ? WINDOWS_SQLITE_PIN_VERSION : DEFAULT_SQLITE_PIN_VERSION
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const sqliteInstallSpec = (platform) => {
|
|
14
|
+
return `sqlite=${sqlitePinVersion(platform)}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const sqlitePinnedSpec = (platform) => {
|
|
18
|
+
return `sqlite ==${sqlitePinVersion(platform)}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const isExpectedSqlitePinned = (platform, version) => {
|
|
22
|
+
return String(version) === sqlitePinVersion(platform)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const condaBuildNumber = (build) => {
|
|
26
|
+
const chunks = String(build || "").split("_").reverse()
|
|
27
|
+
const buildNumber = chunks.find((chunk) => /^\d+$/.test(chunk))
|
|
28
|
+
return buildNumber ? Number(buildNumber) : null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const isWindowsPythonSslFixed = (version, build) => {
|
|
32
|
+
const coerced = semver.coerce(version)
|
|
33
|
+
if (!coerced) {
|
|
34
|
+
return false
|
|
35
|
+
}
|
|
36
|
+
if (!semver.satisfies(coerced, ">=3.10.20 <3.11.0")) {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
if (semver.eq(coerced, WINDOWS_PYTHON_SSL_FIX_VERSION)) {
|
|
40
|
+
const buildNumber = condaBuildNumber(build)
|
|
41
|
+
return typeof buildNumber === "number" && buildNumber >= 1
|
|
42
|
+
}
|
|
43
|
+
return true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
CONDA_PIN_VERSION,
|
|
48
|
+
WINDOWS_PYTHON_SSL_FIX_SPEC,
|
|
49
|
+
isExpectedSqlitePinned,
|
|
50
|
+
isWindowsPythonSslFixed,
|
|
51
|
+
sqliteInstallSpec,
|
|
52
|
+
sqlitePinnedSpec,
|
|
53
|
+
}
|
package/kernel/bin/conda.js
CHANGED
|
@@ -4,6 +4,15 @@ 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
|
+
CONDA_PIN_VERSION,
|
|
9
|
+
WINDOWS_PYTHON_SSL_FIX_SPEC,
|
|
10
|
+
isExpectedSqlitePinned,
|
|
11
|
+
isWindowsPythonSslFixed,
|
|
12
|
+
sqliteInstallSpec,
|
|
13
|
+
sqlitePinnedSpec,
|
|
14
|
+
} = require('./conda-pins')
|
|
15
|
+
|
|
7
16
|
class Conda {
|
|
8
17
|
description = "Pinokio uses Conda to install various useful programs in an isolated manner."
|
|
9
18
|
urls = {
|
|
@@ -48,6 +57,12 @@ class Conda {
|
|
|
48
57
|
win32: ["miniconda/etc/profile.d", "miniconda/bin", "miniconda/Scripts", "miniconda/condabin", "miniconda/lib", "miniconda/Library/bin", "miniconda/pkgs", "miniconda"],
|
|
49
58
|
linux: ["miniconda/etc/profile.d", "miniconda/bin", "miniconda/condabin", "miniconda/lib", "miniconda/Library/bin", "miniconda/pkgs", "miniconda"]
|
|
50
59
|
}
|
|
60
|
+
pinnedPackages() {
|
|
61
|
+
return [
|
|
62
|
+
`conda ==${CONDA_PIN_VERSION}`,
|
|
63
|
+
sqlitePinnedSpec(this.kernel.platform),
|
|
64
|
+
].join("\n")
|
|
65
|
+
}
|
|
51
66
|
env() {
|
|
52
67
|
let base = {
|
|
53
68
|
// CONDA_ROOT: this.kernel.bin.path("miniconda"),
|
|
@@ -129,7 +144,7 @@ report_errors: false`)
|
|
|
129
144
|
let pinned_exists = await this.kernel.exists("bin/miniconda/conda-meta")
|
|
130
145
|
if (pinned_exists) {
|
|
131
146
|
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda ==24.11.3`)
|
|
132
|
-
await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'),
|
|
147
|
+
await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), this.pinnedPackages())
|
|
133
148
|
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), "")
|
|
134
149
|
//sqlite ==3.47.2`)
|
|
135
150
|
// await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.9.0`)
|
|
@@ -160,6 +175,7 @@ report_errors: false`)
|
|
|
160
175
|
let conda_check = {}
|
|
161
176
|
let conda = new Set()
|
|
162
177
|
let conda_versions = {}
|
|
178
|
+
let conda_builds = {}
|
|
163
179
|
let start = false
|
|
164
180
|
for(let line of lines) {
|
|
165
181
|
if (start) {
|
|
@@ -167,8 +183,10 @@ report_errors: false`)
|
|
|
167
183
|
if (chunks.length > 2) {
|
|
168
184
|
let name = chunks[0]
|
|
169
185
|
let version = chunks[1]
|
|
186
|
+
let build = chunks[2]
|
|
170
187
|
conda.add(name)
|
|
171
188
|
conda_versions[name] = version
|
|
189
|
+
conda_builds[name] = build
|
|
172
190
|
if (name === "conda") {
|
|
173
191
|
conda_check.conda = true
|
|
174
192
|
// //if (String(version) === "24.11.1") {
|
|
@@ -193,7 +211,7 @@ report_errors: false`)
|
|
|
193
211
|
// Use sqlite to check if `conda update -y --all` went through successfully
|
|
194
212
|
// sometimes it just fails silently so need to check
|
|
195
213
|
if (name === "sqlite") {
|
|
196
|
-
if (
|
|
214
|
+
if (isExpectedSqlitePinned(this.kernel.platform, version)) {
|
|
197
215
|
conda_check.sqlite = true
|
|
198
216
|
}
|
|
199
217
|
//let coerced = semver.coerce(version)
|
|
@@ -206,6 +224,9 @@ report_errors: false`)
|
|
|
206
224
|
// console.log("semver NOT satisfied")
|
|
207
225
|
//}
|
|
208
226
|
}
|
|
227
|
+
if (name === "python") {
|
|
228
|
+
conda_check.python = this.kernel.platform !== "win32" || isWindowsPythonSslFixed(version, build)
|
|
229
|
+
}
|
|
209
230
|
}
|
|
210
231
|
} else {
|
|
211
232
|
if (/.*name.*version.*build.*channel/i.test(line)) {
|
|
@@ -215,7 +236,8 @@ report_errors: false`)
|
|
|
215
236
|
}
|
|
216
237
|
this.kernel.bin.installed.conda = conda
|
|
217
238
|
this.kernel.bin.installed.conda_versions = conda_versions
|
|
218
|
-
|
|
239
|
+
this.kernel.bin.installed.conda_builds = conda_builds
|
|
240
|
+
return conda_check.conda && conda_check.mamba && conda_check.sqlite && (this.kernel.platform !== "win32" || conda_check.python)
|
|
219
241
|
//return conda_check.conda && conda_check.mamba
|
|
220
242
|
}
|
|
221
243
|
async install(req, ondata) {
|
|
@@ -266,7 +288,7 @@ report_errors: false`)
|
|
|
266
288
|
if (pinned_exists) {
|
|
267
289
|
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda=24.11.1`)
|
|
268
290
|
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), `conda ==24.11.3`)
|
|
269
|
-
await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'),
|
|
291
|
+
await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), this.pinnedPackages())
|
|
270
292
|
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), "sqlite ==3.47.2")
|
|
271
293
|
//await fs.promises.writeFile(this.kernel.path('bin/miniconda/conda-meta/pinned'), "")
|
|
272
294
|
//sqlite ==3.47.2`)
|
|
@@ -300,10 +322,18 @@ report_errors: false`)
|
|
|
300
322
|
}).join(" ")
|
|
301
323
|
console.log("Conda dependencies to install", { mods })
|
|
302
324
|
|
|
325
|
+
let condaPackages = [
|
|
326
|
+
`"${sqliteInstallSpec(this.kernel.platform)}"`,
|
|
327
|
+
`"conda-libmamba-solver>=25.4.0"`,
|
|
328
|
+
]
|
|
329
|
+
if (this.kernel.platform === "win32") {
|
|
330
|
+
condaPackages.unshift(`"${WINDOWS_PYTHON_SSL_FIX_SPEC}"`)
|
|
331
|
+
}
|
|
332
|
+
|
|
303
333
|
let cmds = [
|
|
304
334
|
//"conda clean -y --index-cache",
|
|
305
335
|
"conda clean -y --all",
|
|
306
|
-
`conda install -y -c conda-forge
|
|
336
|
+
`conda install -y -c conda-forge ${condaPackages.join(" ")} ${mods}`.trim(),
|
|
307
337
|
|
|
308
338
|
// `conda config --file ${this.kernel.path('condarc')} --set remote_connect_timeout_secs 20`,
|
|
309
339
|
// `conda config --file ${this.kernel.path('condarc')} --set remote_read_timeout_secs 300`,
|
|
@@ -339,7 +369,6 @@ report_errors: false`)
|
|
|
339
369
|
//if (this.kernel.platform === "win32" || this.kernel.platform === "darwin") {
|
|
340
370
|
// cmds.push("conda install -y conda-libmamba-solver=24.7.0 conda=24.7.1 --freeze-installed")
|
|
341
371
|
//}
|
|
342
|
-
|
|
343
372
|
await this.kernel.bin.exec({
|
|
344
373
|
message: cmds,
|
|
345
374
|
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
|
}
|