thinkncollab-shell 2.0.0-beta.3 → 2.0.0-beta.4
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/Readme.md +2 -0
- package/dist/native/brand/favicon-64.png +0 -0
- package/dist/native/brand/tnc.ico +0 -0
- package/dist/native/tnc-tray/build-macos.sh +5 -0
- package/dist/native/tnc-tray/main.swift +5 -2
- package/dist/native/tnc-tray/tray.ps1 +4 -3
- package/dist/src/dock/tray/install.js +1 -1
- package/dist/src/dock/ui/page.js +4 -1
- package/package.json +1 -1
package/Readme.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<p align="center"><img src="native/brand/thinkncollab-logo.png" alt="ThinkNCollab" width="320"></p>
|
|
2
|
+
|
|
1
3
|
# ThinkNCollab Shell V2 (`thinknsh`)
|
|
2
4
|
|
|
3
5
|
> **The Native-First Collaborative Developer OS: Lightweight MicroVM Sandbox & Zero-Daemon Dev Runner with Live Database Snapshots, P2P Terminal Multiplexing, and OCI Compatibility.**
|
|
Binary file
|
|
Binary file
|
|
@@ -25,6 +25,10 @@ for arch in arm64 x86_64; do
|
|
|
25
25
|
xcrun swiftc -O -target "$arch-apple-macos13" -o "$WORK/tray-$arch" "$HERE/main.swift"
|
|
26
26
|
done
|
|
27
27
|
lipo -create -output "$APP/Contents/MacOS/thinknsh-tray" "$WORK/tray-arm64" "$WORK/tray-x86_64"
|
|
28
|
+
# ThinkNCollab icons (native/brand, made by make-icons.py): the app icon and the menu bar template
|
|
29
|
+
for f in AppIcon.icns menubar.png menubar@2x.png; do
|
|
30
|
+
cp "$HERE/../brand/$f" "$APP/Contents/Resources/$f"
|
|
31
|
+
done
|
|
28
32
|
|
|
29
33
|
cat > "$APP/Contents/Info.plist" <<PLIST
|
|
30
34
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -36,6 +40,7 @@ cat > "$APP/Contents/Info.plist" <<PLIST
|
|
|
36
40
|
<key>CFBundleIdentifier</key><string>com.thinkncollab.thinknsh</string>
|
|
37
41
|
<key>CFBundleExecutable</key><string>thinknsh-tray</string>
|
|
38
42
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
43
|
+
<key>CFBundleIconFile</key><string>AppIcon</string>
|
|
39
44
|
<key>CFBundleShortVersionString</key><string>${VERSION}</string>
|
|
40
45
|
<key>CFBundleVersion</key><string>${VERSION}</string>
|
|
41
46
|
<key>LSMinimumSystemVersion</key><string>13.0</string>
|
|
@@ -121,10 +121,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
121
121
|
|
|
122
122
|
// MARK: menu
|
|
123
123
|
|
|
124
|
+
// The TNC mark (Resources/menubar.png + @2x, a template macOS tints for light and dark),
|
|
125
|
+
// dimmed while dock is not running; a system symbol when the bundle has no icon.
|
|
124
126
|
private func setIcon(_ status: String) {
|
|
125
|
-
let
|
|
126
|
-
|
|
127
|
+
let img = Bundle.main.image(forResource: "menubar")
|
|
128
|
+
?? NSImage(systemSymbolName: status == "running" ? "shippingbox.fill" : "shippingbox", accessibilityDescription: nil)
|
|
127
129
|
img?.isTemplate = true
|
|
130
|
+
img?.accessibilityDescription = "thinknsh dock \(status)"
|
|
128
131
|
statusItem.button?.image = img
|
|
129
132
|
statusItem.button?.appearsDisabled = status != "running"
|
|
130
133
|
}
|
|
@@ -33,7 +33,7 @@ public static class TncTray {
|
|
|
33
33
|
static readonly ConcurrentQueue<string> lines = new ConcurrentQueue<string>();
|
|
34
34
|
static readonly JavaScriptSerializer json = new JavaScriptSerializer();
|
|
35
35
|
|
|
36
|
-
public static void Run(string node, string cli) {
|
|
36
|
+
public static void Run(string node, string cli, string dir) {
|
|
37
37
|
var psi = new ProcessStartInfo(node, "\"" + cli + "\" dock tray");
|
|
38
38
|
psi.UseShellExecute = false;
|
|
39
39
|
psi.RedirectStandardInput = true;
|
|
@@ -55,7 +55,8 @@ public static class TncTray {
|
|
|
55
55
|
errors.Start();
|
|
56
56
|
|
|
57
57
|
icon = new NotifyIcon();
|
|
58
|
-
|
|
58
|
+
var ico = System.IO.Path.Combine(dir ?? "", "tnc.ico"); // the TNC icon, next to this script
|
|
59
|
+
icon.Icon = System.IO.File.Exists(ico) ? new Icon(ico) : SystemIcons.Application;
|
|
59
60
|
icon.Text = "thinknsh dock";
|
|
60
61
|
icon.Visible = true;
|
|
61
62
|
icon.ContextMenuStrip = new ContextMenuStrip();
|
|
@@ -133,4 +134,4 @@ public static class TncTray {
|
|
|
133
134
|
if ($CompileOnly) { Write-Output 'tray compiled'; exit 0 }
|
|
134
135
|
if (-not $Node -or -not $Cli) { throw 'usage: tray.ps1 -Node <node.exe> -Cli <thinknsh.js>' }
|
|
135
136
|
[System.Windows.Forms.Application]::EnableVisualStyles()
|
|
136
|
-
[TncTray]::Run($Node, $Cli)
|
|
137
|
+
[TncTray]::Run($Node, $Cli, $PSScriptRoot)
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
|
|
5
5
|
* UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
|
|
6
6
|
*/
|
|
7
|
-
"use strict";const fs=require("fs"),os=require("os"),path=require("path"),{spawnSync,spawn}=require("child_process"),ROOT=path.join(__dirname,"..","..",".."),CLI=path.join(ROOT,"bin","thinknsh.js"),SOURCE=path.join(ROOT,"native","tnc-tray"),macTarget=()=>process.env.TNC_APP_DIR||path.join(os.homedir(),"Applications","Thinknsh.app"),winDir=()=>process.env.TNC_APP_DIR||path.join(process.env.LOCALAPPDATA||path.join(os.homedir(),"AppData","Local"),"Thinknsh"),winMenuEntry=()=>path.join(process.env.APPDATA||path.join(os.homedir(),"AppData","Roaming"),"Microsoft","Windows","Start Menu","Programs","Thinknsh.vbs");function agentConfig(){return JSON.stringify({node:process.execPath,cli:CLI},null,2)+"\n"}function findMacApp(n){const t=path.join(os.homedir(),".tnc","bin","Thinknsh.app");if(fs.existsSync(path.join(t,"Contents","MacOS","thinknsh-tray")))return t;const s=path.join(SOURCE,"build-macos.sh");if(fs.existsSync(s)&&0===spawnSync("xcrun",["--find","swiftc"],{stdio:"ignore"}).status){const t=fs.mkdtempSync(path.join(os.tmpdir(),"tnc-tray-"));n?.("building the menu-bar app from source (swiftc)");const e=spawnSync("bash",[s,t],{encoding:"utf8"});if(0!==e.status)throw new Error(`building the app failed: ${(e.stderr||e.stdout).trim().split("\n").slice(-3).join(" ")}`);return path.join(t,"Thinknsh.app")}throw new Error("the menu-bar app is not in this runtime: run thinknsh dock setup again, or install Xcode command line tools to build it")}function winLauncher(n){const t=n=>n.replace(/"/g,'""');return`' thinknsh dock tray (written by thinknsh dock app install)\r\nSet sh = CreateObject("WScript.Shell")\r\nsh.Run "powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File ""${t(path.join(n,"tray.ps1"))}"" -Node ""${t(process.execPath)}"" -Cli ""${t(CLI)}""", 0, False\r\n`}function removeEarlierApp(n){const t=path.join(os.homedir(),"Applications","TNC Dock.app"),s=path.join(os.homedir(),"Library","LaunchAgents","com.thinkncollab.dock.menubar.plist");fs.existsSync(s)&&(spawnSync("launchctl",["bootout",`gui/${process.getuid()}/com.thinkncollab.dock.menubar`],{stdio:"ignore"}),fs.rmSync(s,{force:!0})),fs.existsSync(t)&&(spawnSync("pkill",["-f",`${t}/Contents/MacOS/`],{stdio:"ignore"}),fs.rmSync(t,{recursive:!0,force:!0}),n.push(`removed the earlier menu bar app (${t})`))}function install({log:n}={}){const t=[];if("darwin"===process.platform){removeEarlierApp(t);const s=findMacApp(n),e=macTarget();fs.mkdirSync(path.dirname(e),{recursive:!0}),spawnSync("pkill",["-f",`${e}/Contents/MacOS/thinknsh-tray`],{stdio:"ignore"}),fs.rmSync(e,{recursive:!0,force:!0});const i=spawnSync("ditto",[s,e],{encoding:"utf8"});if(0!==i.status)throw new Error(`copying the app: ${i.stderr.trim()}`);fs.writeFileSync(path.join(e,"Contents","Resources","agent.json"),agentConfig()),t.push(`menu-bar app: ${e}`)}else{if("win32"!==process.platform)throw new Error("there is no tray app on Linux; the dashboard is thinknsh dock ui");{const n=winDir();fs.mkdirSync(n,{recursive:!0}),fs.copyFileSync(path.join(SOURCE,"tray.ps1"),path.join(n,"tray.ps1")),fs.writeFileSync(path.join(n,"Thinknsh.vbs"),winLauncher(n)),fs.mkdirSync(path.dirname(winMenuEntry()),{recursive:!0}),fs.copyFileSync(path.join(n,"Thinknsh.vbs"),winMenuEntry()),t.push(`tray app: ${n} (Start menu: Thinknsh)`)}}const s=require("../setup/autostart");return s.status().enabled&&t.push(...s.enable().filter(n=>/app/.test(n))),open(),t}function installedPath(){if("darwin"===process.platform)return fs.existsSync(macTarget())?macTarget():require("../setup/autostart").appBundle();if("win32"===process.platform){const n=path.join(winDir(),"Thinknsh.vbs");return fs.existsSync(n)?n:null}return null}function open(){const n=installedPath();if(!n)throw new Error("the tray app is not installed: thinknsh dock app install");"darwin"===process.platform?spawn("open",[n],{stdio:"ignore",detached:!0}).unref():spawn("wscript.exe",[n],{stdio:"ignore",detached:!0}).unref()}function uninstall(){const n=[];if("darwin"===process.platform){const t=macTarget();spawnSync("pkill",["-f",`${t}/Contents/MacOS/thinknsh-tray`],{stdio:"ignore"}),fs.existsSync(t)&&(fs.rmSync(t,{recursive:!0,force:!0}),n.push(`removed ${t}`))}else if("win32"===process.platform)for(const t of[winDir(),winMenuEntry()])fs.existsSync(t)&&(fs.rmSync(t,{recursive:!0,force:!0}),n.push(`removed ${t}`));const t=require("../setup/autostart");return t.status().app&&(fs.rmSync(path.join(path.dirname(t.status().file),`${t.APP_LABEL}.plist`),{force:!0}),n.push("removed the login item of the app")),n.length||n.push("the tray app was not installed"),n}module.exports={install,uninstall,open,installedPath,winLauncher};
|
|
7
|
+
"use strict";const fs=require("fs"),os=require("os"),path=require("path"),{spawnSync,spawn}=require("child_process"),ROOT=path.join(__dirname,"..","..",".."),CLI=path.join(ROOT,"bin","thinknsh.js"),SOURCE=path.join(ROOT,"native","tnc-tray"),macTarget=()=>process.env.TNC_APP_DIR||path.join(os.homedir(),"Applications","Thinknsh.app"),winDir=()=>process.env.TNC_APP_DIR||path.join(process.env.LOCALAPPDATA||path.join(os.homedir(),"AppData","Local"),"Thinknsh"),winMenuEntry=()=>path.join(process.env.APPDATA||path.join(os.homedir(),"AppData","Roaming"),"Microsoft","Windows","Start Menu","Programs","Thinknsh.vbs");function agentConfig(){return JSON.stringify({node:process.execPath,cli:CLI},null,2)+"\n"}function findMacApp(n){const t=path.join(os.homedir(),".tnc","bin","Thinknsh.app");if(fs.existsSync(path.join(t,"Contents","MacOS","thinknsh-tray")))return t;const s=path.join(SOURCE,"build-macos.sh");if(fs.existsSync(s)&&0===spawnSync("xcrun",["--find","swiftc"],{stdio:"ignore"}).status){const t=fs.mkdtempSync(path.join(os.tmpdir(),"tnc-tray-"));n?.("building the menu-bar app from source (swiftc)");const e=spawnSync("bash",[s,t],{encoding:"utf8"});if(0!==e.status)throw new Error(`building the app failed: ${(e.stderr||e.stdout).trim().split("\n").slice(-3).join(" ")}`);return path.join(t,"Thinknsh.app")}throw new Error("the menu-bar app is not in this runtime: run thinknsh dock setup again, or install Xcode command line tools to build it")}function winLauncher(n){const t=n=>n.replace(/"/g,'""');return`' thinknsh dock tray (written by thinknsh dock app install)\r\nSet sh = CreateObject("WScript.Shell")\r\nsh.Run "powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File ""${t(path.join(n,"tray.ps1"))}"" -Node ""${t(process.execPath)}"" -Cli ""${t(CLI)}""", 0, False\r\n`}function removeEarlierApp(n){const t=path.join(os.homedir(),"Applications","TNC Dock.app"),s=path.join(os.homedir(),"Library","LaunchAgents","com.thinkncollab.dock.menubar.plist");fs.existsSync(s)&&(spawnSync("launchctl",["bootout",`gui/${process.getuid()}/com.thinkncollab.dock.menubar`],{stdio:"ignore"}),fs.rmSync(s,{force:!0})),fs.existsSync(t)&&(spawnSync("pkill",["-f",`${t}/Contents/MacOS/`],{stdio:"ignore"}),fs.rmSync(t,{recursive:!0,force:!0}),n.push(`removed the earlier menu bar app (${t})`))}function install({log:n}={}){const t=[];if("darwin"===process.platform){removeEarlierApp(t);const s=findMacApp(n),e=macTarget();fs.mkdirSync(path.dirname(e),{recursive:!0}),spawnSync("pkill",["-f",`${e}/Contents/MacOS/thinknsh-tray`],{stdio:"ignore"}),fs.rmSync(e,{recursive:!0,force:!0});const i=spawnSync("ditto",[s,e],{encoding:"utf8"});if(0!==i.status)throw new Error(`copying the app: ${i.stderr.trim()}`);fs.writeFileSync(path.join(e,"Contents","Resources","agent.json"),agentConfig()),t.push(`menu-bar app: ${e}`)}else{if("win32"!==process.platform)throw new Error("there is no tray app on Linux; the dashboard is thinknsh dock ui");{const n=winDir();fs.mkdirSync(n,{recursive:!0}),fs.copyFileSync(path.join(SOURCE,"tray.ps1"),path.join(n,"tray.ps1"));const s=path.join(ROOT,"native","brand","tnc.ico");fs.existsSync(s)&&fs.copyFileSync(s,path.join(n,"tnc.ico")),fs.writeFileSync(path.join(n,"Thinknsh.vbs"),winLauncher(n)),fs.mkdirSync(path.dirname(winMenuEntry()),{recursive:!0}),fs.copyFileSync(path.join(n,"Thinknsh.vbs"),winMenuEntry()),t.push(`tray app: ${n} (Start menu: Thinknsh)`)}}const s=require("../setup/autostart");return s.status().enabled&&t.push(...s.enable().filter(n=>/app/.test(n))),open(),t}function installedPath(){if("darwin"===process.platform)return fs.existsSync(macTarget())?macTarget():require("../setup/autostart").appBundle();if("win32"===process.platform){const n=path.join(winDir(),"Thinknsh.vbs");return fs.existsSync(n)?n:null}return null}function open(){const n=installedPath();if(!n)throw new Error("the tray app is not installed: thinknsh dock app install");"darwin"===process.platform?spawn("open",[n],{stdio:"ignore",detached:!0}).unref():spawn("wscript.exe",[n],{stdio:"ignore",detached:!0}).unref()}function uninstall(){const n=[];if("darwin"===process.platform){const t=macTarget();spawnSync("pkill",["-f",`${t}/Contents/MacOS/thinknsh-tray`],{stdio:"ignore"}),fs.existsSync(t)&&(fs.rmSync(t,{recursive:!0,force:!0}),n.push(`removed ${t}`))}else if("win32"===process.platform)for(const t of[winDir(),winMenuEntry()])fs.existsSync(t)&&(fs.rmSync(t,{recursive:!0,force:!0}),n.push(`removed ${t}`));const t=require("../setup/autostart");return t.status().app&&(fs.rmSync(path.join(path.dirname(t.status().file),`${t.APP_LABEL}.plist`),{force:!0}),n.push("removed the login item of the app")),n.length||n.push("the tray app was not installed"),n}module.exports={install,uninstall,open,installedPath,winLauncher};
|
package/dist/src/dock/ui/page.js
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
|
|
5
5
|
* UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
|
|
6
6
|
*/
|
|
7
|
-
"use strict";const PAGE=String.raw`<!doctype html>
|
|
7
|
+
"use strict";const fs=require("fs"),path=require("path");function brandImage(e){try{return`data:image/png;base64,${fs.readFileSync(path.join(__dirname,"..","..","..","native","brand",e)).toString("base64")}`}catch(e){return""}}const FAVICON=brandImage("favicon-64.png"),LOGO=brandImage("favicon-64.png"),PAGE=String.raw`<!doctype html>
|
|
8
8
|
<html lang="en">
|
|
9
9
|
<head>
|
|
10
10
|
<meta charset="utf-8">
|
|
11
11
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
12
12
|
<title>dock dashboard</title>
|
|
13
|
+
${FAVICON?`<link rel="icon" type="image/png" href="${FAVICON}">`:""}
|
|
13
14
|
<style>
|
|
14
15
|
:root {
|
|
15
16
|
--bg: #f6f7f9; --panel: #ffffff; --text: #18202b; --muted: #5d6878; --line: #e3e7ed;
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
|
|
30
31
|
header { display: flex; align-items: center; gap: 12px; padding: 12px 20px; background: var(--panel); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 2; }
|
|
31
32
|
header h1 { font-size: 16px; margin: 0; letter-spacing: .2px; }
|
|
33
|
+
header .logo { width: 24px; height: 24px; border-radius: 6px; }
|
|
32
34
|
header .meta { color: var(--muted); font-size: 12px; }
|
|
33
35
|
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); display: inline-block; }
|
|
34
36
|
.dot.on { background: var(--ok); }
|
|
@@ -89,6 +91,7 @@ pre.term:focus { box-shadow: 0 0 0 2px var(--accent); }
|
|
|
89
91
|
</head>
|
|
90
92
|
<body>
|
|
91
93
|
<header>
|
|
94
|
+
${LOGO?`<img class="logo" src="${LOGO}" alt="ThinkNCollab" width="24" height="24">`:""}
|
|
92
95
|
<span class="dot" id="dot"></span>
|
|
93
96
|
<h1>dock</h1>
|
|
94
97
|
<span class="meta" id="meta">connecting…</span>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thinkncollab-shell",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.4",
|
|
4
4
|
"description": "Lightweight MicroVM Sandbox & Zero-Daemon Dev Runner: Fast MicroVM Containers, Native Microservices, Live Database Snapshots, and End-to-End Encrypted State Sync",
|
|
5
5
|
"main": "dist/src/core/shell.js",
|
|
6
6
|
"bin": {
|