diff --git a/.gitignore b/.gitignore
index 99600f9..18cf523 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
node_modules
-yarn-error.log
\ No newline at end of file
+yarn-error.log
+.system
+dist
diff --git a/.system b/.system
index 94b61e4..331bc76 100644
--- a/.system
+++ b/.system
@@ -1,4 +1,13 @@
{
- "instances": {},
- "handoff": ""
+ "handoff": "",
+ "instances": {
+ "C4A17A22AD4248858DB47161FE19B2EF": {
+ "config": {},
+ "module": "systemd"
+ },
+ "1B87C6B0E8814F55A7D916848AC3BB36": {
+ "config": {},
+ "module": "sshd"
+ }
+ }
}
\ No newline at end of file
diff --git a/install.vsh b/install.vsh
index 90ee679..fc59c53 100644
--- a/install.vsh
+++ b/install.vsh
@@ -1,4 +1,5 @@
create systemd
create sshd
-systemd add sshd exec sshd start
-set handoff invoke systemd boot
\ No newline at end of file
+invoke systemd add sshd invoke sshd start
+set handoff invoke systemd boot
+save
\ No newline at end of file
diff --git a/loader.mjs b/loader.mjs
new file mode 100644
index 0000000..1604afa
--- /dev/null
+++ b/loader.mjs
@@ -0,0 +1,59 @@
+import * as tsNode from 'ts-node/esm';
+import * as tsConfigPaths from "tsconfig-paths";
+import chalk from 'chalk';
+import { dirname, resolve as pathResolve } from 'path';
+import { fileURLToPath } from 'url';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+export const load = tsNode.load;
+export const transformSource = tsNode.transformSource;
+export const getFormat = tsNode.getFormat;
+
+let imports = 0;
+let echo = true;
+
+export async function resolve(specifier, context, defaultResolver) {
+ if(echo === false) {
+ } else if(imports === 0) {
+ console.log(chalk.green('#'), chalk.ansi256(242)('@kernel'))
+ } else {
+ console.log(chalk.green('#'), chalk.ansi256(242)(specifier));
+ }
+
+ if(specifier === '@echo off') {
+ echo = false;
+ }
+
+ const maps = {
+ 'file:///boot': pathResolve(__dirname, 'src', 'index.ts'),
+ '@kernel:base': pathResolve(__dirname, 'src', 'index.ts'),
+ '@kernel:log-hook': pathResolve(__dirname, 'src', 'logHook.ts'),
+ '@commands:executor': pathResolve(__dirname, 'src', 'commands', 'executor.ts'),
+ '@builtin:systemd': pathResolve(__dirname, 'src', 'modules', 'systemd.ts'),
+ '@builtin:sshd': pathResolve(__dirname, 'src', 'modules', 'sshd.ts'),
+ '@echo off': pathResolve(__dirname, 'src', 'noop.ts')
+ };
+
+ const matches = Object.keys(maps).filter(map => specifier.startsWith(map));
+
+ if(matches.length === 1) {
+ // console.log('matches', matches);
+ const match = matches[0];
+ const replace = maps[match];
+ const len = match.length;
+ specifier = replace + specifier.substring(len)
+
+ } else if(matches.length > 1) {
+ const error = `Ambiguous import
+specifier: ${specifier} matches:
+${matches.map(v => ' ' + v).join('\n')}\n`;
+ throw new Error(error);
+ }
+ // if (mappedSpecifier) {
+ // specifier = `${mappedSpecifier}.js`
+ // }
+ const poop = await tsNode.resolve(specifier, context, defaultResolver);
+ imports ++;
+ return poop;
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index c11bd1a..340005c 100644
--- a/package.json
+++ b/package.json
@@ -5,15 +5,19 @@
"license": "MIT",
"type": "module",
"scripts": {
- "start": "(clear || cls) && node --loader ts-node/esm ./src/index.ts"
+ "start": "node --no-warnings --loader ./loader.mjs /boot",
+ "tsc": "tsc"
},
"dependencies": {
"@types/node": "^16.11.12",
+ "@types/uuid": "^8.3.3",
"chalk": "^5.0.0",
"serverline": "^1.5.0",
"ssh2": "^1.5.0",
"telnet": "^0.0.1",
"ts-node": "^10.4.0",
- "typescript": "^4.5.3"
+ "tsconfig-paths": "^3.12.0",
+ "typescript": "^4.5.3",
+ "uuid": "^8.3.2"
}
}
diff --git a/src/externals.d.ts b/src/externals.d.ts
index b2ddfc3..a8ebaa8 100644
--- a/src/externals.d.ts
+++ b/src/externals.d.ts
@@ -1,2 +1,7 @@
declare module "serverline";
-declare module "telnet";
\ No newline at end of file
+declare module "telnet";
+declare module "@kernel:base";
+declare module "@commands:executor";
+declare module "@builtin:systemd";
+declare module "@builtin:sshd";
+declare module "@echo off";
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index db6d04f..c291a99 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,19 +1,24 @@
///
-import './logHook.js';
+// console.clear();
+
+import '@kernel:log-hook';
+import createExecutor from '@commands:executor';
+import * as uuid from 'uuid';
import serverline from 'serverline';
-import createExecutor from './commands/executor.js';
-import { create } from './commands/create.js';
-import { readFileSync, writeFileSync } from 'fs';
+import { existsSync, readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path'
import chalk from 'chalk';
-console.clear();
-
const args = process.argv.slice(2);
const [ startupFile ] = args;
-type Instance = any;
+type Instance = {
+ config: any;
+ ram: any;
+ module: string;
+ functions: any;
+};
const system = {
instances: new Map(),
@@ -28,13 +33,21 @@ export const exec = async (s: string, echo = true) => {
serverline.init({
prompt: chalk.cyan('λ ')
});
-// serverline.setCompletion(['help', 'command1', 'command2', 'login', 'check', 'ping'])
-const executor = createExecutor({
+const kernel = {
async create(module: string, name: string) {
+ // TODO assert module.
try {
- const functions = await import('./modules/' + module + '.js');
- console.log(functions)
+ const imported = (await import('@builtin:' + module));
+ const functions = 'default' in imported ? imported.default : imported;
+ const id = name ?? uuid.v4().replace(/-/g, '').toUpperCase();
+ system.instances.set(id, {
+ config: {},
+ ram: {},
+ module: module,
+ functions
+ });
+ return id;
} catch(e) {
console.log(e);
e.trace();
@@ -43,19 +56,37 @@ const executor = createExecutor({
quit() {
console.log('Shutting down');
serverline.close();
- process.exit(0);
+ setTimeout(() => process.exit(0), 0);
},
ls(flags: any) {
if(flags) console.log(flags)
- console.log('Instances (' + system.instances.size + ')');
+ console.log('Instances', chalk.ansi256(242)('(' + system.instances.size + ')'));
for(const [k, v] of system.instances) {
- console.log(' ' + k + ':', v);
+ let colorCode = 0;
+ for(const char of k) colorCode += char.charCodeAt(0);
+ colorCode %= 6 ** 3;
+ colorCode += 16;
+ console.log(
+ ' '
+ + chalk.ansi256(colorCode)(k.substring(0, 8))
+ + ':', JSON.stringify(v.config, null, 2).replace('\n', ' ').trim()
+ );
}
},
save() {
const timeStart = new Date().getTime();
- const systemString = JSON.stringify(system, null, 2);
+ const obj: any = {
+ handoff: system.handoff,
+ instances: {}
+ };
+ for(const [id, info] of system.instances.entries()) {
+ obj.instances[id] = {
+ config: info.config,
+ module: info.module
+ }
+ }
+ const systemString = JSON.stringify(obj, null, 2);
const fullPath = resolve('.system');
writeFileSync(fullPath, systemString);
const elapsed = new Date().getTime() - timeStart;
@@ -69,10 +100,20 @@ const executor = createExecutor({
exec: exec,
invoke(...a: any[]) {
console.log(a);
+ },
+ async script(path: string) {
+ const fullPath = resolve(path);
+ const lines = readFileSync(fullPath).toString().split('\n').map(v => v.trim());
+ for(const line of lines) {
+ await exec(line);
+ }
}
-});
+};
+
+const executor = createExecutor(kernel);
serverline.on('line', (a: string) => {
+ if(a.trim() === "") return;
exec(a, false);
})
@@ -81,12 +122,25 @@ serverline.on('SIGINT', () => {
});
+
(async () => {
- if(startupFile) {
- const fullPath = resolve(startupFile);
- const lines = readFileSync(fullPath).toString().split('\n').map(v => v.trim());
- for(const line of lines) {
- await exec(line);
+
+ if(existsSync('.system')) {
+ const state: any = JSON.parse(readFileSync('.system').toString());
+ system.handoff = state.handoff;
+ for(const [id, info] of Object.entries(state.instances)) {
+ await kernel.create(info.module, id);
+ system.instances.get(id).config = info.config;
}
}
-})();
\ No newline at end of file
+
+ if(startupFile) {
+ await exec('script ' + startupFile);
+ console.log(chalk.green('Script finished, exitting...'));
+ await exec('quit');
+ }
+})()
+
+import '@echo off';
+
+serverline.setCompletion(Object.keys(kernel))
\ No newline at end of file
diff --git a/src/modules/sshd.ts b/src/modules/sshd.ts
index d551f00..9fb61c2 100644
--- a/src/modules/sshd.ts
+++ b/src/modules/sshd.ts
@@ -1,6 +1,6 @@
import telnet from 'telnet';
-import { exec } from '@kernel';
+import { exec } from '@kernel:base';
export default {
start() {
diff --git a/src/noop.ts b/src/noop.ts
new file mode 100644
index 0000000..e69de29
diff --git a/tsconfig.json b/tsconfig.json
index 875302f..bef4e22 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,9 +5,11 @@
"module": "ESNext",
"moduleResolution": "Node",
"baseUrl": "./src",
- "paths": {
- "@kernel": [ "./" ]
- }
+ "outDir": "./dist",
+ "declaration": true
+ },
+ "paths": {
+ "@commands:executor": [""]
},
"include": [
"src/**/*.ts"
diff --git a/yarn.lock b/yarn.lock
index b3a7b06..62719cd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -34,11 +34,21 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
+"@types/json5@^0.0.29":
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
+ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+
"@types/node@^16.11.12":
version "16.11.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10"
integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==
+"@types/uuid@^8.3.3":
+ version "8.3.3"
+ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.3.tgz#c6a60686d953dbd1b1d45e66f4ecdbd5d471b4d0"
+ integrity sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==
+
acorn-walk@^8.1.1:
version "8.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
@@ -117,11 +127,23 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+json5@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
+ integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+ dependencies:
+ minimist "^1.2.0"
+
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+minimist@^1.2.0:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+ integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
@@ -153,6 +175,11 @@ ssh2@^1.5.0:
cpu-features "0.0.2"
nan "^2.15.0"
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+ integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
+
telnet@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/telnet/-/telnet-0.0.1.tgz#db164465c551a99ee785ea7fbba5a67cfc26c4af"
@@ -185,6 +212,16 @@ ts-node@^10.4.0:
make-error "^1.1.1"
yn "3.1.1"
+tsconfig-paths@^3.12.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
+ integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==
+ dependencies:
+ "@types/json5" "^0.0.29"
+ json5 "^1.0.1"
+ minimist "^1.2.0"
+ strip-bom "^3.0.0"
+
tweetnacl@^0.14.3:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@@ -195,6 +232,11 @@ typescript@^4.5.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c"
integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==
+uuid@^8.3.2:
+ version "8.3.2"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"