pinokiod 3.19.98 → 3.19.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/kernel/api/fs/index.js +19 -0
- package/kernel/api/index.js +5 -3
- package/kernel/api/local/index.js +0 -2
- package/kernel/bin/cli.js +0 -4
- package/kernel/git.js +59 -6
- package/kernel/index.js +0 -1
- package/kernel/plugin.js +1 -0
- package/kernel/util.js +58 -36
- package/package.json +1 -1
- package/server/index.js +322 -102
- package/server/public/android-chrome-192x192.png +0 -0
- package/server/public/android-chrome-512x512.png +0 -0
- package/server/public/apple-touch-icon.png +0 -0
- package/server/public/favicon-16x16.png +0 -0
- package/server/public/favicon-32x32.png +0 -0
- package/server/public/favicon.ico +0 -0
- package/server/public/site.webmanifest +1 -0
- package/server/public/style.css +7 -9
- package/server/socket.js +11 -8
- package/server/views/app.ejs +138 -58
- package/server/views/editor.ejs +1 -1
- package/server/views/git.ejs +143 -58
- package/server/views/{prototype/init.ejs → init/index.ejs} +212 -115
- package/server/views/partials/dynamic.ejs +1 -1
- package/server/views/partials/repos.ejs +2 -2
- package/server/views/terminal.ejs +1 -0
package/kernel/api/fs/index.js
CHANGED
|
@@ -410,6 +410,25 @@ class FS {
|
|
|
410
410
|
}
|
|
411
411
|
|
|
412
412
|
}
|
|
413
|
+
async make(req, ondata, kernel) {
|
|
414
|
+
/*
|
|
415
|
+
{
|
|
416
|
+
method: "fs.make",
|
|
417
|
+
params: {
|
|
418
|
+
path: "data/db"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
*/
|
|
422
|
+
// mkdir
|
|
423
|
+
let cwd = (req.cwd ? req.cwd : kernel.api.userdir)
|
|
424
|
+
if (req.params.path) {
|
|
425
|
+
let _path = kernel.api.filePath(req.params.path, cwd)
|
|
426
|
+
await fs.promises.mkdir(_path, { recursive: true }).catch((e) => { })
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
async remove(req, ondata, kernel) {
|
|
430
|
+
await this.rm(req, ondata, kernel)
|
|
431
|
+
}
|
|
413
432
|
async rm(req, ondata, kernel) {
|
|
414
433
|
let cwd = (req.cwd ? req.cwd : kernel.api.userdir)
|
|
415
434
|
//let filepath = path.resolve(cwd, req.params.path)
|
package/kernel/api/index.js
CHANGED
|
@@ -1387,9 +1387,11 @@ class Api {
|
|
|
1387
1387
|
break;
|
|
1388
1388
|
}
|
|
1389
1389
|
}
|
|
1390
|
-
if (
|
|
1391
|
-
|
|
1392
|
-
|
|
1390
|
+
if (request.method.startsWith("kernel")) {
|
|
1391
|
+
if (this.kernel.template.istemplate(request)) {
|
|
1392
|
+
console.log("something wrong with the request", request)
|
|
1393
|
+
return
|
|
1394
|
+
}
|
|
1393
1395
|
}
|
|
1394
1396
|
|
|
1395
1397
|
// replace {{{ }}} with {{ }}
|
package/kernel/bin/cli.js
CHANGED
|
@@ -15,11 +15,8 @@ class CLI {
|
|
|
15
15
|
} else {
|
|
16
16
|
exists = await Util.exists(this.kernel.path("bin/npm/bin/pterm"))
|
|
17
17
|
}
|
|
18
|
-
console.log("cli check")
|
|
19
|
-
console.log({exists})
|
|
20
18
|
if (exists) {
|
|
21
19
|
let p = this.kernel.which("pterm")
|
|
22
|
-
console.log({ p })
|
|
23
20
|
if (p) {
|
|
24
21
|
let res = await this.kernel.exec({
|
|
25
22
|
message: "pterm version terminal"
|
|
@@ -28,7 +25,6 @@ class CLI {
|
|
|
28
25
|
if (e && e.length > 0) {
|
|
29
26
|
let v = e[1]
|
|
30
27
|
let coerced = semver.coerce(v)
|
|
31
|
-
console.log({ e, v, coerced })
|
|
32
28
|
if (semver.satisfies(coerced, this.version)) {
|
|
33
29
|
return true
|
|
34
30
|
} else {
|
package/kernel/git.js
CHANGED
|
@@ -7,22 +7,54 @@ const ini = require('ini')
|
|
|
7
7
|
class Git {
|
|
8
8
|
constructor(kernel) {
|
|
9
9
|
this.kernel = kernel
|
|
10
|
+
this.dirs = new Set()
|
|
10
11
|
}
|
|
12
|
+
async findGitDirs(dir, results = []) {
|
|
13
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
14
|
+
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
if (entry.isDirectory()) {
|
|
17
|
+
if (entry.name === '.git') {
|
|
18
|
+
results.push(path.join(dir, entry.name));
|
|
19
|
+
continue; // don't go deeper in this repo
|
|
20
|
+
}
|
|
21
|
+
if (entry.name === 'node_modules' || entry.name === 'venv' || entry.name.startsWith(".")) {
|
|
22
|
+
continue; // skip these heavy folders
|
|
23
|
+
}
|
|
24
|
+
await this.findGitDirs(path.join(dir, entry.name), results);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return results;
|
|
28
|
+
}
|
|
29
|
+
|
|
11
30
|
async repos (root) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
31
|
+
console.time("Repos " + root)
|
|
32
|
+
let _repos = await this.findGitDirs(root)
|
|
33
|
+
// let _repos = await glob('**/.git/', {
|
|
34
|
+
// cwd: root,
|
|
35
|
+
// onlyDirectories: true,
|
|
36
|
+
// dot: true,
|
|
37
|
+
// ignore: ['**/node_modules/**', "**/venv/**"], // optional
|
|
38
|
+
// });
|
|
39
|
+
console.timeEnd("Repos " + root)
|
|
40
|
+
|
|
41
|
+
let name = path.basename(root)
|
|
42
|
+
console.time("Get config " + root)
|
|
18
43
|
|
|
19
44
|
let repos = []
|
|
20
45
|
for(let r of _repos) {
|
|
21
46
|
const gitPath = path.resolve(root, r)
|
|
22
47
|
const gitRelPath = path.relative(root, gitPath)
|
|
48
|
+
const gitRelPathSansGit = path.dirname(gitRelPath)
|
|
23
49
|
const gitParentPath = path.dirname(gitPath)
|
|
24
50
|
const gitParentRelPath = path.relative(this.kernel.path("api"), gitParentPath)
|
|
25
51
|
let dir = path.dirname(gitPath)
|
|
52
|
+
let display_name
|
|
53
|
+
if (gitRelPathSansGit === ".") {
|
|
54
|
+
display_name = name
|
|
55
|
+
} else {
|
|
56
|
+
display_name = `${name}/${gitRelPathSansGit}`
|
|
57
|
+
}
|
|
26
58
|
try {
|
|
27
59
|
let gitRemote = await git.getConfig({
|
|
28
60
|
fs,
|
|
@@ -31,6 +63,7 @@ class Git {
|
|
|
31
63
|
path: 'remote.origin.url'
|
|
32
64
|
})
|
|
33
65
|
repos.push({
|
|
66
|
+
name: display_name,
|
|
34
67
|
gitPath,
|
|
35
68
|
gitRelPath,
|
|
36
69
|
gitParentPath,
|
|
@@ -40,6 +73,7 @@ class Git {
|
|
|
40
73
|
})
|
|
41
74
|
} catch (e) {
|
|
42
75
|
repos.push({
|
|
76
|
+
name: display_name,
|
|
43
77
|
gitPath,
|
|
44
78
|
gitRelPath,
|
|
45
79
|
gitParentPath,
|
|
@@ -47,7 +81,9 @@ class Git {
|
|
|
47
81
|
dir,
|
|
48
82
|
})
|
|
49
83
|
}
|
|
84
|
+
this.dirs.add(dir)
|
|
50
85
|
}
|
|
86
|
+
console.timeEnd("Get config " + root)
|
|
51
87
|
return repos
|
|
52
88
|
}
|
|
53
89
|
async config (dir) {
|
|
@@ -60,5 +96,22 @@ class Git {
|
|
|
60
96
|
return null
|
|
61
97
|
}
|
|
62
98
|
}
|
|
99
|
+
async resolveCommitOid(dir, ref) {
|
|
100
|
+
const oid = await git.resolveRef({ fs, dir, ref });
|
|
101
|
+
const { type } = await git.readObject({ fs, dir, oid });
|
|
102
|
+
if (type === "tag") {
|
|
103
|
+
const { object } = await git.readTag({ fs, dir, oid });
|
|
104
|
+
return object;
|
|
105
|
+
}
|
|
106
|
+
if (type !== "commit") {
|
|
107
|
+
throw new Error(`Ref ${ref} points to a ${type}, not a commit.`);
|
|
108
|
+
}
|
|
109
|
+
return oid;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async getParentCommit(dir, commitOid) {
|
|
113
|
+
const { commit } = await git.readCommit({ fs, dir, oid: commitOid });
|
|
114
|
+
return commit.parent[0] || commitOid; // For initial commit
|
|
115
|
+
}
|
|
63
116
|
}
|
|
64
117
|
module.exports = Git
|
package/kernel/index.js
CHANGED
package/kernel/plugin.js
CHANGED
package/kernel/util.js
CHANGED
|
@@ -184,8 +184,16 @@ const log = async (filepath, str, session) => {
|
|
|
184
184
|
].join('|');
|
|
185
185
|
const regex = new RegExp(pattern, 'gi')
|
|
186
186
|
let stripped = str.replaceAll(regex, '');
|
|
187
|
+
|
|
188
|
+
// write to session
|
|
187
189
|
let logpath = path.resolve(filepath, session)
|
|
188
190
|
await fs.promises.writeFile(logpath, stripped)
|
|
191
|
+
|
|
192
|
+
// create latest from last 10 sessions
|
|
193
|
+
|
|
194
|
+
let dirpath = path.dirname(filepath)
|
|
195
|
+
|
|
196
|
+
|
|
189
197
|
let latest_logpath = path.resolve(filepath, "latest")
|
|
190
198
|
await fs.promises.writeFile(latest_logpath, stripped)
|
|
191
199
|
}
|
|
@@ -520,41 +528,16 @@ function u2p(urlPath) {
|
|
|
520
528
|
}
|
|
521
529
|
|
|
522
530
|
function classifyChange(head, workdir, stage) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
case '003':
|
|
534
|
-
return 'added (staged + modified)';
|
|
535
|
-
case '010':
|
|
536
|
-
case '020':
|
|
537
|
-
return 'untracked';
|
|
538
|
-
case '100':
|
|
539
|
-
return 'deleted (unstaged)';
|
|
540
|
-
case '101':
|
|
541
|
-
return 'deleted (staged)';
|
|
542
|
-
case '102':
|
|
543
|
-
return 'deleted (staged, but modified)';
|
|
544
|
-
case '110':
|
|
545
|
-
return 'modified (unstaged)';
|
|
546
|
-
case '111':
|
|
547
|
-
return 'modified (staged)';
|
|
548
|
-
case '112':
|
|
549
|
-
return 'modified (staged + unstaged)';
|
|
550
|
-
case '120':
|
|
551
|
-
return 'type changed (unstaged)';
|
|
552
|
-
case '121':
|
|
553
|
-
return 'type changed (staged)';
|
|
554
|
-
default:
|
|
555
|
-
return `unknown (${key})`;
|
|
556
|
-
}
|
|
557
|
-
|
|
531
|
+
if (head === 0 && workdir === 0 && stage === 0) return null; // shouldn't appear
|
|
532
|
+
if (head === 0 && workdir === 3) return 'untracked';
|
|
533
|
+
if (head === 0 && stage === 3) return 'added (staged)';
|
|
534
|
+
if (head === 1 && workdir === 0 && stage === 0) return 'deleted (unstaged)';
|
|
535
|
+
if (head === 1 && workdir === 0 && stage === 0) return 'deleted (staged)';
|
|
536
|
+
if (head === 1 && workdir === 2 && stage === 0) return 'modified (unstaged)';
|
|
537
|
+
if (head === 1 && workdir === 1 && stage === 2) return 'modified (staged)';
|
|
538
|
+
if (head === 1 && workdir === 2 && stage === 2) return 'modified (staged + unstaged)';
|
|
539
|
+
if (head === 1 && workdir === 1 && stage === 0) return 'clean';
|
|
540
|
+
return `unknown (${head},${workdir},${stage})`;
|
|
558
541
|
}
|
|
559
542
|
|
|
560
543
|
|
|
@@ -659,6 +642,45 @@ function diffLinesWithContext(diffs, context = 3) {
|
|
|
659
642
|
|
|
660
643
|
return summarized;
|
|
661
644
|
}
|
|
645
|
+
const readLines = async (filePath) => {
|
|
646
|
+
try {
|
|
647
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
648
|
+
return data
|
|
649
|
+
.split(/\r?\n/)
|
|
650
|
+
.map(line => line.trim())
|
|
651
|
+
.filter(line => line.length > 0 && !line.startsWith('#'));
|
|
652
|
+
} catch (err) {
|
|
653
|
+
if (err.code === 'ENOENT') return [];
|
|
654
|
+
throw err;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
const mergeLines = async (existingFilepath, filepath2) => {
|
|
659
|
+
let e = await exists(existingFilepath)
|
|
660
|
+
if (e) {
|
|
661
|
+
// exists. merge
|
|
662
|
+
console.log(existingFilepath, "exists. merge")
|
|
663
|
+
const existing = await readLines(existingFilepath)
|
|
664
|
+
const other = await readLines(filepath2);
|
|
665
|
+
const merged = [...new Set([...existing, ...other])].sort().join('\n') + '\n';
|
|
666
|
+
|
|
667
|
+
let current = await fs.promises.readFile(existingFilepath, "utf8")
|
|
668
|
+
if (current.trim() !== merged.trim()) {
|
|
669
|
+
console.log("merged has changed")
|
|
670
|
+
// changed
|
|
671
|
+
await fs.promises.writeFile(existingFilepath, merged)
|
|
672
|
+
} else {
|
|
673
|
+
console.log(" no changes needed")
|
|
674
|
+
}
|
|
675
|
+
} else {
|
|
676
|
+
// does not exist, just copy
|
|
677
|
+
console.log(existingFilepath, "does not exist. copy")
|
|
678
|
+
await fs.promises.cp(filepath2, existingFilepath)
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
|
|
662
684
|
module.exports = {
|
|
663
|
-
parse_env, log_path, api_path, update_env, parse_env_detail, openfs, port_running, du, is_port_available, find_python, find_venv, fill_object, run, openURL, u2p, p2u, log, diffLinesWithContext, classifyChange, push, filepicker, exists, clipboard
|
|
685
|
+
parse_env, log_path, api_path, update_env, parse_env_detail, openfs, port_running, du, is_port_available, find_python, find_venv, fill_object, run, openURL, u2p, p2u, log, diffLinesWithContext, classifyChange, push, filepicker, exists, clipboard, mergeLines
|
|
664
686
|
}
|