thinkncollab-shell 0.0.20 → 2.0.0-beta.1.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.
Files changed (201) hide show
  1. package/LICENSE +82 -0
  2. package/Readme.md +246 -502
  3. package/dist/bin/thinknsh.js +8 -0
  4. package/dist/src/commands/auth/login.js +7 -0
  5. package/dist/src/commands/auth/logout.js +7 -0
  6. package/dist/src/commands/auth/register.js +7 -0
  7. package/dist/src/commands/auth/whoami.js +7 -0
  8. package/dist/src/commands/dock/bench.js +7 -0
  9. package/dist/src/commands/dock/ci.js +7 -0
  10. package/dist/src/commands/dock/cluster.js +7 -0
  11. package/dist/src/commands/dock/containers.js +7 -0
  12. package/dist/src/commands/dock/dock.js +7 -0
  13. package/dist/src/commands/github/commits.js +7 -0
  14. package/dist/src/commands/github/issue-create.js +7 -0
  15. package/dist/src/commands/github/issues.js +7 -0
  16. package/dist/src/commands/github/pulls.js +7 -0
  17. package/dist/src/commands/github/statusgh.js +7 -0
  18. package/dist/src/commands/index.js +7 -0
  19. package/dist/src/commands/message/say.js +7 -0
  20. package/dist/src/commands/room/join.js +7 -0
  21. package/dist/src/commands/room/leave.js +7 -0
  22. package/dist/src/commands/room/rooms.js +7 -0
  23. package/dist/src/commands/room/sync.js +7 -0
  24. package/dist/src/commands/sandbox/console.js +7 -0
  25. package/dist/src/commands/sandbox/dep.js +7 -0
  26. package/dist/src/commands/sandbox/deploy.js +7 -0
  27. package/dist/src/commands/sandbox/dev.js +7 -0
  28. package/dist/src/commands/sandbox/exec.js +7 -0
  29. package/dist/src/commands/sandbox/freeze.js +7 -0
  30. package/dist/src/commands/sandbox/push.js +7 -0
  31. package/dist/src/commands/sandbox/resume.js +7 -0
  32. package/dist/src/commands/sandbox/sandbox.js +7 -0
  33. package/dist/src/commands/sandbox/share.js +7 -0
  34. package/dist/src/commands/sandbox/snapshot.js +7 -0
  35. package/dist/src/commands/sandbox/sync-deps.js +7 -0
  36. package/dist/src/commands/shell/doctor.js +7 -0
  37. package/dist/src/commands/shell/notifications.js +7 -0
  38. package/dist/src/commands/shell/notify.js +7 -0
  39. package/dist/src/commands/shell/status.js +7 -0
  40. package/dist/src/commands/shell/version.js +7 -0
  41. package/dist/src/commands/tasks/build.js +7 -0
  42. package/dist/src/commands/tasks/complete.js +7 -0
  43. package/dist/src/commands/tasks/create-task.js +7 -0
  44. package/dist/src/commands/tasks/loadtest.js +7 -0
  45. package/dist/src/commands/tasks/task-status.js +7 -0
  46. package/dist/src/commands/tasks/task.js +7 -0
  47. package/dist/src/commands/tasks/tasks.js +7 -0
  48. package/dist/src/commands/team/invite.js +7 -0
  49. package/dist/src/commands/team/myteam.js +7 -0
  50. package/dist/src/commands/team/teammates.js +7 -0
  51. package/dist/src/commands/terminal/share.js +7 -0
  52. package/dist/src/core/api-client.js +7 -0
  53. package/dist/src/core/crypto/e2ee-vault.js +7 -0
  54. package/dist/src/core/dep-store.js +7 -0
  55. package/dist/src/core/dependency-tracker.js +7 -0
  56. package/dist/src/core/geekload.js +7 -0
  57. package/dist/src/core/local-runner.js +7 -0
  58. package/dist/src/core/multi-lang-scanner.js +7 -0
  59. package/dist/src/core/notification-window.js +8 -0
  60. package/dist/src/core/notify-auth.js +7 -0
  61. package/dist/src/core/project-config.js +7 -0
  62. package/dist/src/core/sandbox/arch-shim.js +7 -0
  63. package/dist/src/core/sandbox/capsule-builder.js +7 -0
  64. package/dist/src/core/sandbox/cgroups.js +7 -0
  65. package/dist/src/core/sandbox/container-monitor.js +7 -0
  66. package/dist/src/core/sandbox/crun-manager.js +7 -0
  67. package/dist/src/core/sandbox/engine.js +7 -0
  68. package/dist/src/core/sandbox/image-manager.js +7 -0
  69. package/dist/src/core/sandbox/image-store.js +7 -0
  70. package/dist/src/core/sandbox/index.js +7 -0
  71. package/dist/src/core/sandbox/macos-sandbox.js +7 -0
  72. package/dist/src/core/sandbox/microvm-manager.js +7 -0
  73. package/dist/src/core/sandbox/native-service-manager.js +7 -0
  74. package/dist/src/core/sandbox/network.js +7 -0
  75. package/dist/src/core/sandbox/oci-exporter.js +7 -0
  76. package/dist/src/core/sandbox/oci-puller.js +7 -0
  77. package/dist/src/core/sandbox/oci-runtime-spec.js +7 -0
  78. package/dist/src/core/sandbox/policy-engine.js +7 -0
  79. package/dist/src/core/sandbox/port-proxy-daemon.js +7 -0
  80. package/dist/src/core/sandbox/room-sync-manager.js +7 -0
  81. package/dist/src/core/sandbox/runtime-manager.js +7 -0
  82. package/dist/src/core/sandbox/snapshot-manager.js +7 -0
  83. package/dist/src/core/sandbox/storage.js +7 -0
  84. package/dist/src/core/sandbox/supervisor.js +7 -0
  85. package/dist/src/core/sandbox/tunnel-daemon.js +7 -0
  86. package/dist/src/core/sandbox/tunnel.js +7 -0
  87. package/dist/src/core/sandbox/window-launcher.js +7 -0
  88. package/dist/src/core/sandbox/windows-wsl2.js +7 -0
  89. package/dist/src/core/sandbox-window.js +8 -0
  90. package/dist/src/core/shell.js +7 -0
  91. package/dist/src/core/websocket.js +7 -0
  92. package/dist/src/dock/api/routes.js +7 -0
  93. package/dist/src/dock/api/server.js +7 -0
  94. package/dist/src/dock/api/wire.js +7 -0
  95. package/dist/src/dock/bench/memory.js +7 -0
  96. package/dist/src/dock/bench/runner.js +7 -0
  97. package/dist/src/dock/build/builder.js +7 -0
  98. package/dist/src/dock/build/buildfile.js +7 -0
  99. package/dist/src/dock/build/buildkit.js +7 -0
  100. package/dist/src/dock/build/changes.js +7 -0
  101. package/dist/src/dock/ci/actions.js +7 -0
  102. package/dist/src/dock/ci/runner.js +7 -0
  103. package/dist/src/dock/ci/workflow.js +7 -0
  104. package/dist/src/dock/cli/api.js +7 -0
  105. package/dist/src/dock/cli/args.js +7 -0
  106. package/dist/src/dock/cli/commands.js +7 -0
  107. package/dist/src/dock/cli/compose.js +7 -0
  108. package/dist/src/dock/cli/context.js +7 -0
  109. package/dist/src/dock/cli/files.js +7 -0
  110. package/dist/src/dock/cli/format.js +7 -0
  111. package/dist/src/dock/cli/manage.js +7 -0
  112. package/dist/src/dock/cli/moved.js +7 -0
  113. package/dist/src/dock/cli/services.js +7 -0
  114. package/dist/src/dock/cli/session.js +7 -0
  115. package/dist/src/dock/cli/workspace.js +7 -0
  116. package/dist/src/dock/client.js +7 -0
  117. package/dist/src/dock/compat/cases.js +7 -0
  118. package/dist/src/dock/compat/runner.js +7 -0
  119. package/dist/src/dock/config.js +7 -0
  120. package/dist/src/dock/daemon-main.js +7 -0
  121. package/dist/src/dock/daemon.js +7 -0
  122. package/dist/src/dock/deploy/compose.js +7 -0
  123. package/dist/src/dock/engine.js +7 -0
  124. package/dist/src/dock/image/archive.js +7 -0
  125. package/dist/src/dock/image/auth.js +7 -0
  126. package/dist/src/dock/image/reference.js +7 -0
  127. package/dist/src/dock/image/registry.js +7 -0
  128. package/dist/src/dock/image/tar.js +7 -0
  129. package/dist/src/dock/index.js +7 -0
  130. package/dist/src/dock/linux/host.js +7 -0
  131. package/dist/src/dock/paths.js +7 -0
  132. package/dist/src/dock/runtime/emulation.js +7 -0
  133. package/dist/src/dock/runtime/fsevents.js +7 -0
  134. package/dist/src/dock/runtime/fsops.js +7 -0
  135. package/dist/src/dock/runtime/hostfwd.js +7 -0
  136. package/dist/src/dock/runtime/logs.js +7 -0
  137. package/dist/src/dock/runtime/network.js +7 -0
  138. package/dist/src/dock/runtime/ports.js +7 -0
  139. package/dist/src/dock/runtime/rootfs.js +7 -0
  140. package/dist/src/dock/runtime/seccomp-profile.LICENSE +202 -0
  141. package/dist/src/dock/runtime/seccomp-profile.json +1227 -0
  142. package/dist/src/dock/runtime/seccomp.js +7 -0
  143. package/dist/src/dock/runtime/spec.js +7 -0
  144. package/dist/src/dock/runtime/stats.js +7 -0
  145. package/dist/src/dock/runtime/volumes.js +7 -0
  146. package/dist/src/dock/selftest.js +7 -0
  147. package/dist/src/dock/setup/app.js +7 -0
  148. package/dist/src/dock/setup/autostart.js +7 -0
  149. package/dist/src/dock/setup/index.js +7 -0
  150. package/dist/src/dock/setup/integrate.js +7 -0
  151. package/dist/src/dock/setup/migrate.js +7 -0
  152. package/dist/src/dock/state/store.js +7 -0
  153. package/dist/src/dock/ui/page.js +385 -0
  154. package/dist/src/dock/ui/server.js +7 -0
  155. package/dist/src/dock/version.js +7 -0
  156. package/dist/src/dock/workspace/apps.js +7 -0
  157. package/dist/src/dock/workspace/workspace.js +7 -0
  158. package/dist/src/events/notifications.js +7 -0
  159. package/dist/src/utils/logger.js +7 -0
  160. package/dist/src/utils/terminalCrypto.js +7 -0
  161. package/package.json +41 -16
  162. package/bin/thinknsh.js +0 -71
  163. package/src/commands/auth/login.js +0 -84
  164. package/src/commands/auth/logout.js +0 -32
  165. package/src/commands/auth/register.js +0 -52
  166. package/src/commands/auth/whoami.js +0 -52
  167. package/src/commands/github/commits.js +0 -58
  168. package/src/commands/github/issue-create.js +0 -59
  169. package/src/commands/github/issues.js +0 -57
  170. package/src/commands/github/pulls.js +0 -58
  171. package/src/commands/github/statusgh.js +0 -50
  172. package/src/commands/index.js +0 -136
  173. package/src/commands/message/say.js +0 -49
  174. package/src/commands/room/join.js +0 -142
  175. package/src/commands/room/leave.js +0 -24
  176. package/src/commands/room/rooms.js +0 -66
  177. package/src/commands/shell/notify.js +0 -88
  178. package/src/commands/shell/status.js +0 -73
  179. package/src/commands/shell/version.js +0 -18
  180. package/src/commands/tasks/build.js +0 -190
  181. package/src/commands/tasks/complete.js +0 -940
  182. package/src/commands/tasks/create-task.js +0 -101
  183. package/src/commands/tasks/loadtest.js +0 -101
  184. package/src/commands/tasks/suggestTask.js +0 -0
  185. package/src/commands/tasks/task-status.js +0 -72
  186. package/src/commands/tasks/task.js +0 -182
  187. package/src/commands/tasks/tasks.js +0 -184
  188. package/src/commands/team/invite.js +0 -46
  189. package/src/commands/team/myteam.js +0 -78
  190. package/src/commands/team/teammates.js +0 -52
  191. package/src/commands/terminal/share.js +0 -261
  192. package/src/core/api-client.js +0 -246
  193. package/src/core/geekload.js +0 -524
  194. package/src/core/local-runner.js +0 -861
  195. package/src/core/notification-window.js +0 -165
  196. package/src/core/project-config.js +0 -100
  197. package/src/core/shell.js +0 -734
  198. package/src/core/websocket.js +0 -657
  199. package/src/events/notifications.js +0 -184
  200. package/src/utils/logger.js +0 -159
  201. package/src/utils/terminalCrypto.js +0 -47
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
4
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
5
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
6
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
7
+ */
8
+ const path=require("path"),chalk=require("chalk"),ThinkNCollabShell=require("../src/core/shell"),args=process.argv.slice(2);if(0!==args.length&&["--help","-h","help"].includes(args[0]))console.log(`\n${chalk.cyan("ThinkNCollab Shell V2 - Native Cloud & Container Engine")}\n\n${chalk.yellow("Usage:")}\n thinknsh Start interactive shell\n thinknsh <command> Run single command\n thinknsh --help Show this help\n thinknsh --version Show version\n\n${chalk.yellow("Containers:")}\n ${chalk.green("thinknsh run")} [options] IMAGE [CMD] Run a container (thinknsh run -it alpine sh)\n ${chalk.green("thinknsh ps")} [-a] List containers\n ${chalk.green("thinknsh logs")} [-f] NAME Show or follow output\n ${chalk.green("thinknsh exec")} -it NAME sh Shell into a running container\n ${chalk.green("thinknsh stop")} | start | restart | rm NAME…\n ${chalk.green("thinknsh build")} -t NAME . Build an image from a Containerfile\n ${chalk.green("thinknsh images")} | pull | rmi | tag Manage images\n ${chalk.green("thinknsh compose")} up -d | down | ps | logs Multi-container apps\n ${chalk.green("thinknsh volume")} | network | system Volumes, networks, disk usage\n ${chalk.green("thinknsh dock")} setup | status | selftest Engine setup and checks\n\n Every command has its own help: thinknsh run --help\n\n${chalk.yellow("Examples:")}\n thinknsh run -d --name db -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres:16\n thinknsh run --rm -it alpine sh\n thinknsh build -t myapp .\n thinknsh compose up -d\n\n${chalk.dim('For more commands, type "help" in the interactive shell')}\n `),process.exit(0);else if(args.includes("--version")||1===args.length&&"-v"===args[0]){let n;try{n=require("../../package.json")}catch{n=require("../package.json")}console.log(n.version),process.exit(0)}else{const n=new ThinkNCollabShell({serverUrl:process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com",apiUrl:process.env.THINKNCOLLAB_API_URL||"https://thinkncollab.com",wsUrl:process.env.THINKNCOLLAB_WS_URL||"https://thinkncollab.com",autoConnect:"true"===process.env.THINKNCOLLAB_AUTO_CONNECT});if(args.length>0){const e=!require("../src/commands/dock/containers").ALL_NAMES.includes(args[0])&&args.some(n=>["dev","up","console","notifications","panel","notif-panel"].includes(n))||args.includes("-f")||args.includes("--follow")||"notify"===args[0]&&args.some(n=>/^\d{4,5}$/.test(n)),s=args.map(n=>n.includes(" ")||n.includes("\t")?`"${n.replace(/"/g,'\\"')}"`:n).join(" ");n.execute(s,args).then(()=>{e||process.exit(process.exitCode||0)}).catch(n=>{console.error(chalk.red(`Error: ${n.message}`)),process.exit(1)})}else n.start().catch(n=>{console.error(chalk.red(`Fatal error: ${n.message}`)),process.exit(1)})}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"login",description:"Login to ThinkNCollab",aliases:["signin"],requiresAuth:!1,async execute(e,s){if(s.api.isAuthenticated()){const e=s.api.getUser();return console.log(chalk.green(`[OK] Already logged in as ${e.name} (${e.email})`)),void console.log(chalk.dim(' Run "logout" first to switch accounts.'))}let a=e[0],o=e[1];if(!a||!o){const{input:e,password:s}=require("@inquirer/prompts");a||(a=await e({message:"Email:",validate:e=>e.includes("@")||"Enter a valid email"})),o||(o=await s({message:"Password:",mask:"*",validate:e=>e.length>=1||"Password required"}))}console.log(chalk.blue(" Logging in..."));try{const e=await s.api.login(a,o),l=e.user;if(s.ws.setUser(l,e.token),s.ws.isConnected())s.ws._announceUser?.();else try{await s.ws.connect(e.token),console.log(chalk.dim(" Connected to ThinkNCollab server"))}catch(e){console.log(chalk.yellow(` [WARN] WebSocket unavailable: ${e.message}`))}console.log(chalk.green(`[OK] Welcome, ${l.name}!`)),console.log(chalk.dim(` Logged in as ${l.email}`))}catch(e){e.message.includes("401")||e.message.toLowerCase().includes("invalid")||e.message.toLowerCase().includes("unauthorized")?console.log(chalk.red("[FAIL] Invalid email or password")):e.message.includes("connect")||e.message.includes("ECONNREFUSED")?console.log(chalk.red("[FAIL] Cannot reach server — is it running?")):console.log(chalk.red(`[FAIL] Login failed: ${e.message}`))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),fs=require("fs-extra");module.exports={name:"logout",description:"Logout from ThinkNCollab",aliases:["signout","exit"],requiresAuth:!0,async execute(e,s){s.printMessage(chalk.cyan(" Logging out..."));try{await s.api.logout();const e=s.getSessionPath();await fs.remove(e),s.printMessage(chalk.green("[OK] Logged out successfully"))}catch(e){s.printMessage(chalk.red(`[FAIL] Logout failed: ${e.message}`))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),{exec}=require("child_process");module.exports={name:"register",description:"Create a new ThinkNCollab account",aliases:["signup","reg"],requiresAuth:!1,async execute(e,o){try{console.log(chalk.cyan(" Opening registration in browser..."));const e=o.api.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com",l=`${e}/register?ref=cli&cliRef=${require("crypto").randomBytes(8).toString("hex")}`,c="win32"===process.platform?`start "" "${l}"`:"darwin"===process.platform?`open "${l}"`:`xdg-open "${l}"`;exec(c,e=>{e&&(console.log(chalk.yellow("[WARN] Could not open browser automatically.")),console.log(chalk.dim(" Open this URL manually:")),console.log(chalk.cyan(` ${l}`)))}),console.log(chalk.green("[OK] Registration page opened!")),console.log(chalk.dim(` URL: ${l}`)),console.log(""),console.log(chalk.dim(" After registering, come back and run:")),console.log(chalk.cyan(" login"))}catch(e){console.log(chalk.red(`[FAIL] Error: ${e.message}`))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"whoami",description:"Show current user information",aliases:["user","me"],requiresAuth:!1,async execute(e,l){const o=l.api.getUser(),a=l.ws.getCurrentRoom?.(),n=l.api.session;let c=null;try{const e=(await l.api._request("GET","/thinknsh/session/history")).find(e=>e._id!==n?.shellSessionId);e&&(c=e)}catch{}console.log(chalk.cyan("\n User Information:")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(` ${chalk.yellow("Name:")} ${o.name||"Not set"}`),console.log(` ${chalk.yellow("Email:")} ${o.email}`),console.log(` ${chalk.yellow("User ID:")} ${o._id||"N/A"}`),console.log(` ${chalk.yellow("Type:")} ${o.userType||"User"}`),console.log(` ${chalk.yellow("Status:")} ${l.ws.isConnected?.()?chalk.green("● Online"):chalk.gray("○ Offline")}`),a&&console.log(` ${chalk.yellow("Room:")} ${chalk.cyan(a)}`),n?.timestamp&&console.log(` ${chalk.yellow("Login At:")} ${chalk.dim(new Date(n.timestamp).toLocaleString())}`),c?.logoutAt?console.log(` ${chalk.yellow("Last Logout:")} ${chalk.dim(new Date(c.logoutAt).toLocaleString())}`):c?.lastSeenAt&&console.log(` ${chalk.yellow("Last Seen:")} ${chalk.dim(new Date(c.lastSeenAt).toLocaleString())} ${chalk.red("(crash?)")}`),c?.machineId&&console.log(` ${chalk.yellow("Last Machine:")} ${chalk.dim(c.machineId)}`),console.log()}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ "use strict";const chalk=require("chalk"),{runBench,saveReport}=require("../../dock/bench/runner"),MB=1048576,fmt=e=>`${(e/MB).toFixed(1)} MB`;function flag(e,s,o){const n=e.indexOf(`--${s}`);if(-1===n||void 0===e[n+1])return o;const t=Number(e[n+1]);if(!Number.isFinite(t)||t<=0)throw new Error(`--${s} must be a positive number`);return t}function printReport(e){const s=e.machine,o="darwin"===s.platform?`macOS ${s.macos} · ${s.model}`:`${s.platform} ${s.osRelease}`;if(console.log(chalk.bold(`\nthinknsh bench — ${e.scenario}`)+chalk.dim(` (${o} · ${s.ncpu} CPUs · ${fmt(s.totalMem)} RAM)`)),"stopped"===e.scenario){const s=e.result;if(s.satisfied)console.log(chalk.green(" ✓ No thinknsh background processes: 0 MB"));else{console.log(chalk.yellow(` ✗ ${s.processes.length} thinknsh background process(es) still running:`));for(const e of s.processes)console.log(chalk.dim(` ${e.pid} ${e.role} ${e.args.slice(0,100)}`))}return}const n=e.result;void 0!==e.bootMs&&console.log(` VM boot to ready ${e.bootMs} ms ${chalk.dim(`(${e.params.vmCpus} CPUs, ${e.params.vmMemMB} MB VM)`)}`),console.log(` samples ${n.samples} ${chalk.dim(`(every ${e.params.interval}s, method: ${n.methods.join(", ")||"n/a"})`)}`),console.log(chalk.bold(` total median ${fmt(n.total.median)} min ${fmt(n.total.min)} p95 ${fmt(n.total.p95)} max ${fmt(n.total.max)}`));for(const[e,s]of Object.entries(n.byRole))console.log(` ${e.padEnd(16)} median ${fmt(s.median)}`);0===n.processes.length&&console.log(chalk.dim(" (no thinknsh background processes were running)")),n.methods.includes("rss")&&console.log(chalk.yellow(" note: some processes were measured by RSS (footprint/PSS unavailable)"))}module.exports={name:"bench",description:"Measure the real memory cost of thinknsh (reproducible, saved as JSON)",usage:"thinknsh bench [idle|containers|current|stopped] [--duration s] [--interval s] [--settle s] [--mem MB] [--cpus n] [--json]",requiresAuth:!1,examples:["thinknsh bench idle # boot an empty MicroVM, measure, shut it down","thinknsh bench containers # postgres + redis through dock, measured","thinknsh bench current # measure what is running right now","thinknsh bench stopped # verify nothing runs in the background (0 MB)"],async execute(e=[]){const s=e[0]&&!e[0].startsWith("--")?e[0]:"idle",o=e.includes("--json");try{const n=await runBench({scenario:s,duration:flag(e,"duration",30),interval:flag(e,"interval",2),settle:flag(e,"settle",10),mem:flag(e,"mem",512),cpus:flag(e,"cpus",2),log:o?()=>{}:e=>console.log(chalk.dim(` ${e}`)),onSample:o?null:(e,s)=>process.stdout.write(chalk.dim(`\r sample ${s}: ${fmt(e.totalBytes)} `))}),t=saveReport(n);o?console.log(JSON.stringify(n,null,2)):(process.stdout.write("\n"),printReport(n),console.log(chalk.dim(`\n saved: ${t}\n`))),"stopped"!==s||n.result.satisfied||(process.exitCode=1)}catch(e){console.error(chalk.red(`bench failed: ${e.message}`)),process.exitCode=1}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ "use strict";const fs=require("fs"),path=require("path"),chalk=require("chalk"),DIRS=[".tnc/workflows",".github/workflows"];function listWorkflows(e){const s=[];for(const o of DIRS){const l=path.join(e,o);if(fs.existsSync(l))for(const e of fs.readdirSync(l).sort())/\.ya?ml$/.test(e)&&s.push(path.join(l,e))}return s}function findWorkflow(e,s){if(s&&fs.existsSync(s)&&fs.statSync(s).isFile())return path.resolve(s);const o=listWorkflows(e);return s?o.find(e=>path.basename(e)===s||path.basename(e).replace(/\.ya?ml$/,"")===s)||null:o[0]||null}const COLORS=[chalk.cyan,chalk.magenta,chalk.yellow,chalk.blue,chalk.green,chalk.redBright],ICON={success:chalk.green("✓"),failure:chalk.red("✗"),skipped:chalk.dim("○"),cancelled:chalk.yellow("⊘"),running:chalk.dim("▸")},secs=e=>`${(e/1e3).toFixed(1)}s`;function printer(){const e=new Map,s=s=>{const o=s.leg?`${s.job} (${s.leg})`:s.job;return e.has(o)||e.set(o,COLORS[e.size%COLORS.length]),e.get(o)(`[${o}]`)};return e=>{switch(e.type){case"run":console.log(chalk.bold(`▶ ${e.text}`)+chalk.dim(` (run ${e.id})`));break;case"job":"skipped"===e.status&&console.log(`${s(e)} ${ICON.skipped} job skipped`);break;case"leg":"running"===e.status?console.log(`${s(e)} ${chalk.dim(`${e.image} · ${e.platform}`)}`):console.log(`${s(e)} ${ICON[e.status]||""} ${e.status} ${chalk.dim(secs(e.durationMs||0))}`);break;case"step":if("running"===e.status)console.log(`${s(e)} ${ICON.running} ${chalk.bold(e.step)}`);else if("skipped"!==e.status||void 0===e.exitCode){const o="failure"===e.status?chalk.red(` (exit ${e.exitCode}${e.ignored?", continue-on-error":""})`):"";console.log(`${s(e)} ${ICON[e.status]||""} ${e.step}${o}${e.durationMs?chalk.dim(` ${secs(e.durationMs)}`):""}`)}break;case"out":console.log(`${s(e)} ${"stderr"===e.stream?chalk.dim(e.text):e.text}`);break;case"note":console.log(`${e.job?`${s(e)} `:""}${chalk.dim(e.text)}`)}}}function summary(e){console.log("");for(const s of e.jobs)if(s.legs.length)for(const e of s.legs){const o="failure"===e.status?[...e.steps||[]].reverse().find(e=>"failure"===e.status):null;console.log(` ${ICON[e.status]||""} ${e.name||s.name}${e.label&&!String(e.name||"").includes(e.label)?` (${e.label})`:""} ${chalk.dim(`${e.platform||""} ${secs(e.durationMs||0)}`)}${o?chalk.red(` failed at "${o.name}"`):""}`)}else console.log(` ${ICON[s.status]||""} ${s.name} ${chalk.dim(s.status)}`);console.log(""),console.log(e.passed?chalk.bgGreen.black(" PASS ")+` ${e.name}`:chalk.bgRed.white(" FAIL ")+` ${e.name}`)}module.exports={name:"ci",description:"Run CI workflows (.tnc/workflows) locally: jobs, matrix legs for both CPUs, services, each in a fresh container",usage:"thinknsh ci run [WORKFLOW] [--job ID] [--max-parallel N] [--secret K=V] [--in-place] [--keep] [--json] | ci list",requiresAuth:!1,examples:["thinknsh ci list","thinknsh ci run # the first workflow in .tnc/workflows","thinknsh ci run nodejs-ci --job build-and-test","thinknsh ci run ci.yml --secret NPM_TOKEN=xyz"],async execute(e=[]){const s=e[0]||"run",o=process.cwd();if("list"===s){const e=listWorkflows(o);if(!e.length)return void console.log(chalk.yellow("no workflows in .tnc/workflows or .github/workflows"));for(const s of e)console.log(path.relative(o,s));return}if("run"!==s)return console.log(chalk.yellow(`usage: ${module.exports.usage}`)),void(process.exitCode=1);const l=e.slice(1),n={jobs:[],secrets:{},maxParallel:0,inPlace:!1,keep:!1,json:!1};let t=null;for(let e=0;e<l.length;e++){const s=l[e];if("--job"===s)n.jobs.push(l[++e]);else if("--max-parallel"===s)n.maxParallel=Number(l[++e]);else if("--secret"===s){const s=String(l[++e]||""),o=s.indexOf("=");o>0?n.secrets[s.slice(0,o)]=s.slice(o+1):n.secrets[s]=process.env[s]||""}else if("--in-place"===s)n.inPlace=!0;else if("--keep"===s)n.keep=!0;else if("--json"===s)n.json=!0;else{if(s.startsWith("-")||t)return console.log(chalk.red(`unknown option ${s}`)),void(process.exitCode=1);t=s}}const r=findWorkflow(o,t);if(!r)return console.log(chalk.red(t?`no workflow ${t}`:"no workflows in .tnc/workflows or .github/workflows")),void(process.exitCode=1);const{runWorkflow:c}=require("../../dock/ci/runner");try{const e=await c({projectDir:o,workflowText:fs.readFileSync(r,"utf8"),workflowFile:path.basename(r),onLog:n.json?()=>{}:printer(),maxParallel:n.maxParallel,inPlace:n.inPlace,keep:n.keep,secrets:n.secrets,onlyJobs:n.jobs});n.json?console.log(JSON.stringify(e,null,2)):summary(e),e.passed||(process.exitCode=1)}catch(e){console.log(chalk.red(`✗ ${e.message}`)),process.exitCode=1}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ "use strict";const fs=require("fs"),path=require("path"),chalk=require("chalk"),{composeToStack}=require("../../dock/deploy/compose"),{COMPOSE_LEGACY_FILES}=require("../../dock/api/wire");function flag(e,o){const s=e.indexOf(o);return-1===s?null:e[s+1]}function roomOf(e,o){const s=flag(e,"--room")||o?.ws?.getCurrentRoom?.()||o?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID;if(!s)throw new Error("no room selected: join a room first or pass --room <id>");return"object"==typeof s?s._id||s.id:s}function findComposeFile(e){const o=flag(e,"-f")||flag(e,"--file");if(o)return o;for(const e of["compose.yaml","compose.yml",...COMPOSE_LEGACY_FILES])if(fs.existsSync(e))return e;throw new Error("no compose file found (compose.yaml / compose.yml); pass -f <file>")}async function api(e,o,s,r){if(!e?.api?.isAuthenticated?.())throw new Error("please login first: thinknsh login");return e.api._request(o,`/dock/v2${s}`,r)}function printStatus({deployments:e=[],pods:o=[],nodes:s=[]}){const r=(e,o)=>String(e??"").padEnd(o);console.log(chalk.bold(`\n${r("DEPLOYMENT",28)}${r("READY",8)}${r("REV",5)}IMAGE`));for(const o of e){const e=o.status||{},s=`${e.ready||0}/${o.spec.replicas}`,t=(e.ready||0)===o.spec.replicas?chalk.green:chalk.yellow;console.log(`${r(o.name,28)}${t(r(s,8))}${r(o.revision,5)}${o.spec.image}`)}e.length||console.log(chalk.dim(" (no deployments)")),console.log(chalk.bold(`\n${r("POD",36)}${r("NODE",18)}${r("PHASE",12)}MESSAGE`));const t=e=>s.find(o=>String(o.agentId)===String(e))?.name||(e?String(e).slice(-8):"-");for(const e of o){const o=e.terminating?"Terminating":e.phase,s=e.ready?chalk.green:"Failed"===o?chalk.red:chalk.yellow;console.log(`${r(e.name,36)}${r(t(e.nodeAgentId),18)}${s(r(o,12))}${chalk.dim(e.message||"")}`)}console.log(chalk.bold(`\n${r("NODE",24)}${r("STATUS",10)}${r("CPU",6)}${r("MEMORY",10)}DOCK`));for(const e of s)console.log(`${r(e.name,24)}${(e.ready?chalk.green:chalk.red)(r(e.ready?"Ready":"NotReady",10))}${r(e.capacity?.cpu,6)}${r(`${e.capacity?.memoryMB} MB`,10)}${e.dockVersion||chalk.dim(e.message||"-")}`);console.log("")}module.exports={name:"cluster",description:"Deploy compose stacks to your servers and manage them (dock cluster)",usage:"thinknsh cluster <deploy|status|scale|rollback|rm|nodes|secret>",requiresAuth:!1,examples:["thinknsh cluster deploy -f compose.yaml","thinknsh cluster status","thinknsh cluster scale shop-web 3","thinknsh cluster rollback shop-web"],async execute(e=[],o){const s=(e[0]||"status").toLowerCase();try{switch(s){case"deploy":{const s=findComposeFile(e),r=composeToStack(s,{stackName:flag(e,"--stack")});for(const e of r.warnings)console.log(chalk.yellow(` ! ${e}`));console.log(chalk.bold(`\nstack ${r.stack}: ${Object.keys(r.services).length} service(s) from ${path.basename(s)}`));for(const[e,o]of Object.entries(r.services)){const s=o.ports.map(e=>e.hostPort?`${e.hostPort}→${e.containerPort}`:e.containerPort).join(", ");console.log(` ${chalk.cyan(`${r.stack}-${e}`.padEnd(28))} ${o.image} ×${o.replicas}${s?` ports ${s}`:""}`)}if(e.includes("--dry-run"))return;const t=await api(o,"PUT",`/rooms/${roomOf(e,o)}/stacks/${r.stack}`,{services:r.services});return console.log(chalk.green(`\n✓ applied ${t.applied.length} deployment(s)`)+(t.removed.length?chalk.dim(`, removed ${t.removed.join(", ")}`):"")),void console.log(chalk.dim(" watch the rollout: thinknsh cluster status"))}case"status":case"nodes":return void printStatus(await api(o,"GET",`/rooms/${roomOf(e,o)}/cluster`));case"scale":{const[,s,r]=e;if(!s||void 0===r)throw new Error("usage: thinknsh cluster scale <deployment> <replicas>");const{deployment:t}=await api(o,"POST",`/rooms/${roomOf(e,o)}/deployments/${s}/scale`,{replicas:Number(r)});return void console.log(chalk.green(`✓ ${t.name} scaled to ${t.spec.replicas}`))}case"rollback":{const[,s,r]=e;if(!s)throw new Error("usage: thinknsh cluster rollback <deployment> [revision]");const{deployment:t}=await api(o,"POST",`/rooms/${roomOf(e,o)}/deployments/${s}/rollback`,r&&!r.startsWith("--")?{revision:Number(r)}:{});return void console.log(chalk.green(`✓ ${t.name} rolled back: now revision ${t.revision} (${t.spec.image})`))}case"secret":{const[,s="ls",r,t]=e,n=roomOf(e,o);if("ls"===s){const e=await api(o,"GET",`/rooms/${n}/secrets`);e.length||console.log(chalk.dim(" (no secrets)"));for(const o of e)console.log(` ${o.name.padEnd(32)} ${chalk.dim(new Date(o.updatedAt).toLocaleString())}`);return}if(!r)throw new Error(`usage: thinknsh cluster secret ${s} <NAME>`);if("rm"===s)return await api(o,"DELETE",`/rooms/${n}/secrets/${encodeURIComponent(r)}`),void console.log(chalk.green(`✓ secret ${r} removed`));if("set"!==s)throw new Error("usage: thinknsh cluster secret <set|ls|rm> [NAME] [value|-]");let c=t&&"-"!==t&&!t.startsWith("--")?t:null;if(null!==c||process.stdin.isTTY&&"-"!==t||(c=await new Promise(e=>{let o="";process.stdin.on("data",e=>{o+=e}),process.stdin.on("end",()=>e(o.replace(/\r?\n$/,"")))})),null===c){const{password:e}=require("@inquirer/prompts");c=await e({message:`value for ${r}:`,mask:"*"})}return await api(o,"PUT",`/rooms/${n}/secrets/${encodeURIComponent(r)}`,{value:c}),void console.log(chalk.green(`✓ secret ${r} saved`)+chalk.dim(" (pods using it are recreated with the new value)"))}case"rm":{const s=e[1];if(!s)throw new Error("usage: thinknsh cluster rm <stack>");const r=await api(o,"PUT",`/rooms/${roomOf(e,o)}/stacks/${s}`,{services:{}});return void console.log(chalk.green(`✓ removed ${r.removed.length} deployment(s) of stack ${s}`))}default:console.log(chalk.yellow(`unknown subcommand "${s}". Usage: ${module.exports.usage}`)),process.exitCode=1}}catch(e){console.error(chalk.red(`cluster ${s}: ${e.message}`)),process.exitCode=1}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ "use strict";const{runCommand}=require("../../dock/cli/commands"),DESCRIPTIONS={run:"Run a container (pulls the image if needed)",create:"Create a container without starting it",start:"Start stopped containers",stop:"Stop running containers",restart:"Restart containers",kill:"Send a signal to containers",rm:"Remove containers",wait:"Wait for containers to stop and print exit codes",ps:"List containers",logs:"Show container output",exec:"Run a command in a running container",inspect:"Show details of containers, images, volumes or networks",images:"List images",pull:"Download an image",push:"Upload an image to a registry (also: sandbox push ecr://… / --export)",login:"Log in to a container registry (-u USER [REGISTRY]); with an email, to ThinkNCollab",logout:"Log out of a container registry (REGISTRY); without one, of ThinkNCollab",rmi:"Remove images",tag:"Give an image another name",build:"Build an image from a Containerfile",cp:"Copy files between a container and this machine (CONTAINER:PATH)",stats:"Live CPU, memory, network and disk use of containers",top:"Show the processes of a container",pause:"Freeze every process of containers",unpause:"Thaw paused containers",rename:"Rename a container",update:"Change memory/CPU limits or the restart policy of containers",diff:"Show files changed in a container",port:"Show the published ports of a container",commit:"Make an image from a container's changes",save:"Write images to a tar file (loads in any engine)",load:"Read images from a tar file",import:"Make an image from a root filesystem tar",compose:"Run multi-container apps from a compose file",workspace:"One secure container per project for all coding agents and editors (Claude, Codex, Antigravity, Cursor)",service:"Dev databases as containers: postgres, redis, mysql (start, stop, status, logs, rm)",registry:"A local image registry as a container (start, stop, status, push, pull)",capsule:"Older name for image commands (build, images, run, rmi)",vault:"Older name for volume commands, plus backup and restore",mesh:"Older name for network commands",stack:"Older name for compose",vm:"Older name for dock setup/start/stop/status",volume:"Manage volumes",network:"Manage networks",system:"Disk usage, cleanup and engine info",container:"Manage containers (ls, rm, prune, …)",image:"Manage images (ls, rm, prune, …)"},NAMES=Object.keys(DESCRIPTIONS),looksLikeRegistry=e=>!!e&&!e.startsWith("-")&&!e.includes("@")&&(e.includes(".")||e.includes(":")||"localhost"===e),REGISTRY_FORM={login:e=>e.some(e=>/^(-u|--username|--password-stdin)(=|$)/.test(e)||/^-u./.test(e))||1===e.length&&looksLikeRegistry(e[0])||["--help","-h"].includes(e[0]),logout:e=>1===e.length&&(looksLikeRegistry(e[0])||["--help","-h"].includes(e[0])),push:e=>!e.some(e=>/^[a-z][a-z0-9+.-]*:\/\//.test(e)||/^--export/.test(e))&&"export"!==e[0]},LEGACY={login:"../auth/login",logout:"../auth/logout",push:"../sandbox/push"},ALIASES={volume:["vol","volumes"],network:["net","networks"],images:["img"],service:["svc","services","db"],capsule:["cap"],vm:["microvm","vz"]};async function runLegacy(e,a,o,s){const t=require(LEGACY[e]);if(!t.requiresAuth||o?.api?.isAuthenticated())return t.execute(a,o,s);console.log(require("chalk").red("[FAIL] Please login first: login"))}module.exports=NAMES.map(e=>({name:e,description:DESCRIPTIONS[e],usage:`thinknsh ${e} --help`,requiresAuth:!1,selfExiting:!0,...LEGACY[e]?{aliases:require(LEGACY[e]).aliases}:ALIASES[e]?{aliases:ALIASES[e]}:{},async execute(a=[],o,s=e){if(LEGACY[e]&&(s!==e||!REGISTRY_FORM[e](a)))return runLegacy(e,a,o,s);process.exitCode=await runCommand(e,a)}})),module.exports.REGISTRY_FORM=REGISTRY_FORM,module.exports.NAMES=NAMES,module.exports.ALL_NAMES=module.exports.flatMap(e=>[e.name,...e.aliases||[]]);
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ "use strict";const fs=require("fs"),path=require("path"),chalk=require("chalk"),{spawn}=require("child_process"),{dockPaths}=require("../../dock/paths"),{request,ping}=require("../../dock/client"),{readPid,pidAlive}=require("../../dock/daemon"),{PHASE}=require("../../dock/version"),sleep=e=>new Promise(o=>setTimeout(o,e));async function setupCmd(e){const{setup:o}=require("../../dock/setup"),s=o=>{const s=e.indexOf(o);return-1===s?void 0:e[s+1]};try{const t=await o({from:s("--from"),baseUrl:s("--url"),force:e.includes("--force"),log:e=>console.log(chalk.dim(` ${e}`))});return console.log(chalk.green(`✓ dock runtime ${t} installed for ${process.platform}/${process.arch}`)),console.log(chalk.dim(" next: thinknsh dock start")),!0}catch(e){return console.log(chalk.red(`✗ setup failed: ${e.message}`)),!1}}async function start(e){if(await ping(e.socket))return console.log(chalk.green(`dock is already running (pid ${readPid(e.pidFile)||"?"})`)),!0;fs.mkdirSync(e.home,{recursive:!0,mode:448});const o=fs.openSync(e.logFile,"a"),s=spawn(process.execPath,[path.join(__dirname,"..","..","dock","daemon-main.js")],{detached:!0,stdio:["ignore",o,o],env:process.env});s.unref(),fs.closeSync(o);for(let o=0;o<50;o++){if(await ping(e.socket))return console.log(chalk.green(`✓ dock started (pid ${s.pid})`)),console.log(chalk.dim(` socket: ${e.socket}`)),console.log(chalk.dim(" try: thinknsh run --rm alpine echo hello")),!0;if(null!==s.exitCode)break;await sleep(100)}console.log(chalk.red(`✗ dock failed to start. Last log lines (${e.logFile}):`));try{console.log(chalk.dim(fs.readFileSync(e.logFile,"utf8").trim().split("\n").slice(-5).join("\n")))}catch(e){}return!1}async function stop(e){const o=readPid(e.pidFile);if(!o||!pidAlive(o))return console.log(chalk.dim("dock is not running")),!0;process.kill(o,"SIGTERM");for(let e=0;e<50;e++){if(!pidAlive(o))return console.log(chalk.green(`✓ dock stopped (pid ${o})`)),!0;await sleep(100)}return console.log(chalk.red(`✗ dock (pid ${o}) did not stop within 5s`)),!1}async function status(e){if(!await ping(e.socket))return console.log(`${chalk.red("●")} dock is not running ${chalk.dim("start it with: thinknsh dock start")}`),!1;const[o,s]=await Promise.all([request(e.socket,"GET","/version"),request(e.socket,"GET","/info")]);if(console.log(`${chalk.green("●")} dock ${o.body.Version} running (pid ${readPid(e.pidFile)||"?"})`),console.log(` socket ${e.socket}`),console.log(` API version ${o.body.ApiVersion} (min ${o.body.MinAPIVersion})`),console.log(` phase ${PHASE}`),console.log(` containers ${s.body.Containers} (${s.body.ContainersRunning} running)`),console.log(` images ${s.body.Images}`),"darwin"===process.platform){const e=require("../../dock/setup/autostart").installed();console.log(` autostart ${e?"on (starts when you log in)":chalk.dim("off (turn on: thinknsh dock autostart)")}`)}for(const e of s.body.Warnings||[])console.log(chalk.yellow(` ${e}`));return!0}async function compat(e,o){const{runCompat:s,toMarkdown:t}=require("../../dock/compat/runner");let n=e.socket,r=null;if(!await ping(n)){const e=require("os"),{DockDaemon:o}=require("../../dock/daemon"),s=fs.mkdtempSync(path.join(e.tmpdir(),"tnc-dock-check-"));r={daemon:new o({home:s}),home:s},await r.daemon.start(),n=r.daemon.paths.socket}try{const a=await s({socketPath:n,home:r?r.home:e.home}),c={pass:chalk.green,fail:chalk.red,pending:chalk.dim,early:chalk.cyan};console.log(chalk.bold(`\ndock check — phase ${a.phase}${r?chalk.dim(" (temporary daemon)"):""}\n`));for(const e of a.results){const o=c[e.result](e.result.padEnd(8));console.log(` ${o} ${e.phase} ${e.id.padEnd(20)} ${chalk.dim(e.detail)}`)}const i=a.tally;console.log(`\n ${chalk.green(`${i.pass||0} pass`)} ${chalk.red(`${i.fail||0} fail`)} ${i.pending||0} pending ${i.early||0} early`);const l=o.indexOf("--md");return-1!==l&&o[l+1]&&(fs.writeFileSync(o[l+1],t(a)),console.log(chalk.dim(` report written to ${o[l+1]}`))),a.ok}finally{r&&(await r.daemon.stop(),fs.rmSync(r.home,{recursive:!0,force:!0}))}}async function selftest(e){if(!await ping(e.socket)&&!await start(e))return!1;console.log(chalk.bold(`\ndock selftest — ${process.platform}/${process.arch}\n`));const{runSelftest:o}=require("../../dock/selftest"),{report:s,file:t}=await o({log:e=>console.log(` ${e.startsWith("✓")?chalk.green(e):chalk.red(e)}`)}),n=s.passed===s.total?chalk.green:chalk.red;return console.log(n(`\n ${s.passed}/${s.total} checks passed`)),console.log(chalk.dim(` report: ${t} (share this file)\n`)),s.passed===s.total}function parseSize(e){const o=/^(\d+(?:\.\d+)?)\s*([mg]?)b?$/i.exec(String(e||"").trim());if(!o)throw new Error(`invalid size "${e}" (examples: 4g, 6144m)`);return Math.round(parseFloat(o[1])*("m"===o[2].toLowerCase()?1:1024))}async function configCmd(e){const{readConfig:o,writeConfig:s,effective:t,configFile:n}=require("../../dock/config"),r=o();let a=!1;for(let o=0;o<e.length;o++){const s=e[o],t=()=>{if(o+1>=e.length)throw new Error(`${s} needs a value`);return e[++o]};if("--cpus"===s)r.cpus=Math.max(1,parseInt(t(),10)),a=!0;else if("--memory"===s||"-m"===s)r.memoryMB=parseSize(t()),a=!0;else if("--disk-size"===s)r.diskGB=parseInt(t(),10),a=!0;else if("--share"===s){const e=path.resolve(t().replace(/^~(?=\/|$)/,require("os").homedir()));if(!fs.existsSync(e)||!fs.statSync(e).isDirectory())throw new Error(`${e} is not a folder`);r.shares=[...new Set([...r.shares||[],e])],a=!0}else if("--unshare"===s){const e=path.resolve(t());r.shares=(r.shares||[]).filter(o=>o!==e),a=!0}else if("--publish-address"===s){const e=t();if(!require("net").isIP(e))throw new Error(`--publish-address needs an IP address (127.0.0.1, 0.0.0.0 …), not "${e}"`);r.publishAddress=e,a=!0}else{if("--reset"!==s)throw new Error(`unknown option ${s} (--cpus N, --memory 8g, --disk-size GB, --share PATH, --unshare PATH, --publish-address IP, --reset)`);for(const e of Object.keys(r))delete r[e];a=!0}}a&&s(r);const c=t(),i=(e,s)=>void 0!==o()[e]?s:`${s} ${chalk.dim("(default)")}`;console.log(` cpus ${i("cpus",c.cpus)}`),console.log(` memory ${i("memoryMB",`${c.memoryMB} MB`)} ${chalk.dim("a ceiling: macOS backs only what containers use")}`),console.log(` disk size ${i("diskGB",`${c.diskGB} GB`)} ${chalk.dim("used when the data disk is created")}`),console.log(` shared ${[require("os").homedir(),"/private/tmp","/private/var/folders","/Volumes",...c.shares].join(", ")}`),console.log(` ports ${i("publishAddress",c.publishAddress)} ${chalk.dim("127.0.0.1"===c.publishAddress?"-p without an address: this machine only":"-p without an address: open to the network")}`),console.log(chalk.dim(` file: ${n()}`));const l=e.filter(e=>e.startsWith("-")&&"--publish-address"!==e);return a&&l.length?console.log(chalk.yellow(" applies when the Linux VM next boots: thinknsh dock vm-restart (stops running containers)")):a&&console.log(chalk.dim(" ports: applies to containers started from now on")),!0}async function migrateCmd(e,o){const{migrate:s}=require("../../dock/setup/migrate"),t=e=>{const s=o.indexOf(e);return-1===s?void 0:o[s+1]};if(!await ping(e.socket))return console.log(chalk.red("✗ dock is not running. Start it with: thinknsh dock start")),!1;try{const n=await s({from:t("--from"),to:`unix://${e.socket}`,images:o.includes("--images"),volumes:o.includes("--volumes"),dryRun:o.includes("--dry-run"),overwrite:o.includes("--overwrite"),log:e=>console.log(chalk.dim(` ${e}`))}),r=(e,o)=>o?`${e}: ${o.moved} copied, ${o.skipped} already here`:null;return console.log(chalk.green(`✓ ${[r("images",n.images),r("volumes",n.volumes)].filter(Boolean).join("; ")}`)),console.log(chalk.dim(" containers are not moved: recreate them here (thinknsh compose up / thinknsh run)")),!0}catch(e){return console.log(chalk.red(`✗ migrate failed: ${e.message}`)),!1}}async function uiCmd(e,o){const{startUi:s}=require("../../dock/ui/server");if(!await ping(e.socket))return console.log(chalk.red("✗ dock is not running. Start it with: thinknsh dock start")),!1;const t=await s({socketPath:e.socket,port:Number((()=>{const e=o.indexOf("--port");return-1===e?void 0:o[e+1]})())||0});if(console.log(chalk.green("✓ dock dashboard")),console.log(` ${t.url}`),console.log(chalk.dim(" the link carries this session's token; Ctrl-C stops the dashboard")),!o.includes("--no-open")){const e="darwin"===process.platform?["open",[t.url]]:"win32"===process.platform?["cmd",["/c","start","",t.url]]:["xdg-open",[t.url]];try{spawn(e[0],e[1],{stdio:"ignore",detached:!0}).on("error",()=>{}).unref()}catch(e){}}return await new Promise(e=>{const o=()=>{t.close().then(e)};process.once("SIGINT",o),process.once("SIGTERM",o)}),!0}async function useCmd(e,o){const{use:s}=require("../../dock/setup/integrate");try{for(const t of s(e.socket,{off:o.includes("--off"),system:o.includes("--system")}))console.log(` ${t}`);return o.includes("--off")||console.log(chalk.green("✓ tools built for other engines now use dock")+chalk.dim(" (undo: thinknsh dock use --off)")),!0}catch(e){return console.log(chalk.red(`✗ ${e.message}`)),!1}}async function vmRestart(e,o){if(await ping(e.socket)){const s=((await request(e.socket,"GET","/containers/json")).body||[]).map(e=>e.Names[0].slice(1));if(s.length&&!o.includes("--force"))return console.log(chalk.yellow(` running containers would stop: ${s.join(", ")}`)),console.log(chalk.dim(" stop them first, or pass --force")),!1}if(await stop(e),"darwin"===process.platform){const{spawnSync:e}=require("child_process");e(path.join(require("os").homedir(),".tnc","bin","tnc-vz"),["stop"],{stdio:"ignore"})}else if("win32"===process.platform){const{spawnSync:e}=require("child_process");e("wsl.exe",["--terminate",require("../../dock/setup").WSL_DISTRO],{stdio:"ignore"})}const s=await start(e);return s&&console.log(chalk.dim(" the Linux VM boots with the new settings on the next command that needs it")),s}function appCmd(e,o){try{const s=require("../../dock/setup/app").app({off:o.includes("--off"),home:e.home,socket:e.socket,cli:process.argv[1],version:require("../../dock/setup").BUNDLE_VERSION,log:e=>console.log(chalk.dim(` ${e}`))});for(const e of s)console.log(` ${e}`);return!0}catch(e){return console.log(chalk.red(`✗ ${e.message}`)),!1}}function autostartCmd(e,o){try{const s=require("../../dock/setup/autostart").autostart({off:o.includes("--off"),cli:process.argv[1],logFile:e.logFile});for(const e of s)console.log(` ${e}`);return!0}catch(e){return console.log(chalk.red(`✗ ${e.message}`)),!1}}async function foreground(){require("../../dock/daemon-main"),await new Promise(()=>{})}module.exports={name:"dock",description:"dock: ThinkNCollab container engine daemon (TNC Engine API)",usage:"thinknsh dock <setup|start|stop|status|check|selftest|config|use|env|autostart|app|vm-restart|migrate|ui|daemon>",requiresAuth:!1,examples:["thinknsh dock setup","thinknsh dock start","thinknsh dock selftest","thinknsh dock check --md check.md","thinknsh dock config --memory 8g --cpus 6","thinknsh dock use","thinknsh dock autostart","thinknsh dock app"],async execute(e=[]){const o=(e[0]||"status").toLowerCase(),s=dockPaths();let t=!0;switch(o){case"setup":t=await setupCmd(e.slice(1));break;case"start":t=await start(s);break;case"stop":t=await stop(s);break;case"status":t=await status(s);break;case"check":t=await compat(s,e.slice(1));break;case"selftest":t=await selftest(s);break;case"daemon":await foreground();break;case"config":try{t=await configCmd(e.slice(1))}catch(e){console.log(chalk.red(`✗ ${e.message}`)),t=!1}break;case"use":t=await useCmd(s,e.slice(1));break;case"env":console.log(require("../../dock/setup/integrate").env(s.socket));break;case"vm-restart":t=await vmRestart(s,e.slice(1));break;case"migrate":t=await migrateCmd(s,e.slice(1));break;case"ui":t=await uiCmd(s,e.slice(1));break;case"autostart":t=autostartCmd(s,e.slice(1));break;case"app":t=appCmd(s,e.slice(1));break;default:console.log(chalk.yellow(`unknown subcommand "${o}". Usage: ${module.exports.usage}`)),t=!1}t||(process.exitCode=1)}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3");module.exports={name:"commits",description:"List recent GitHub commits for the linked repository",aliases:["gh-commits"],requiresAuth:!0,requiresRoom:!0,async execute(e,o){const t=o.ws.getCurrentRoom();if(t){console.log(chalk.dim("\n Fetching recent commits...\r"));try{const e=await o.api._request("GET",`/thinknsh/${t}/github/commits`);if(console.log(" ".repeat(30)+"\r"),console.log(chalk.cyan("\n Recent Commits (Last 15):")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),!e||0===e.length)return console.log(chalk.dim(" No commits found.")),void console.log();const l=new Table({head:["SHA","Message","Author","Date"],colWidths:[10,45,18,15]});e.forEach(e=>{const o=e.sha.slice(0,7),t=e.message.split("\n")[0];l.push([chalk.yellow(o),chalk.white(t.length>40?t.slice(0,37)+"...":t),e.author||"-",new Date(e.date).toLocaleDateString()])}),console.log(l.toString()),console.log()}catch(e){console.log(" ".repeat(30)+"\r"),console.log(chalk.red(`[FAIL] Failed to fetch commits: ${e.message}`))}}else console.log(chalk.yellow("[WARN] Please join a room first: join <room-id>"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"issue-create",description:"Create a new GitHub issue in the linked repository",aliases:["create-issue","gh-issue-create","gh-create-issue"],requiresAuth:!0,requiresRoom:!0,async execute(e,s){const o=s.ws.getCurrentRoom();if(!o)return void console.log(chalk.yellow("[WARN] Please join a room first: join <room-id>"));let i=e[0],l=e.slice(1).join(" ");if(!i)try{const{input:e}=require("@inquirer/prompts");i=await e({message:"Enter issue title:",validate:e=>!!e.trim()||"Title is required"}),l=await e({message:"Enter issue description (body) (optional):"})}catch(e){return void console.log(chalk.red("[FAIL] Missing arguments. Usage: issue-create <title> <body>"))}console.log(chalk.dim("\n Creating GitHub issue...\r"));try{const e=await s.api._request("POST",`/thinknsh/${o}/github/issues`,{title:i,body:l});console.log(" ".repeat(30)+"\r"),console.log(chalk.green("\n[OK] GitHub issue created successfully!")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(` ${chalk.yellow("Issue Number:")} #${e.number}`),console.log(` ${chalk.yellow("Title:")} ${e.title}`),console.log(` ${chalk.yellow("URL:")} ${chalk.cyan(e.html_url)}`),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"))}catch(e){console.log(" ".repeat(30)+"\r"),console.log(chalk.red(`[FAIL] Failed to create issue: ${e.message}`))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3");module.exports={name:"issues",description:"List open GitHub issues for the linked repository",aliases:["gh-issues"],requiresAuth:!0,requiresRoom:!0,async execute(e,o){const s=o.ws.getCurrentRoom();if(s){console.log(chalk.dim("\n Fetching open issues...\r"));try{const e=await o.api._request("GET",`/thinknsh/${s}/github/issues`);if(console.log(" ".repeat(30)+"\r"),console.log(chalk.cyan("\n Open GitHub Issues:")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),!e||0===e.length)return console.log(chalk.dim(" No open issues found in the linked repository.")),void console.log();const t=new Table({head:["#","Title","Author","Comments","Updated At"],colWidths:[8,45,15,10,15]});e.forEach(e=>{t.push([chalk.green(`#${e.number}`),chalk.white(e.title.length>40?e.title.slice(0,37)+"...":e.title),e.user||"-",e.comments,new Date(e.updated_at).toLocaleDateString()])}),console.log(t.toString()),console.log()}catch(e){console.log(" ".repeat(30)+"\r"),console.log(chalk.red(`[FAIL] Failed to fetch issues: ${e.message}`))}}else console.log(chalk.yellow("[WARN] Please join a room first: join <room-id>"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3");module.exports={name:"pulls",description:"List open GitHub pull requests for the linked repository",aliases:["prs","gh-pulls","gh-prs"],requiresAuth:!0,requiresRoom:!0,async execute(e,l){const o=l.ws.getCurrentRoom();if(o){console.log(chalk.dim("\n Fetching open pull requests...\r"));try{const e=await l.api._request("GET",`/thinknsh/${o}/github/pulls`);if(console.log(" ".repeat(30)+"\r"),console.log(chalk.cyan("\n Open GitHub Pull Requests:")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),!e||0===e.length)return console.log(chalk.dim(" No open pull requests found.")),void console.log();const t=new Table({head:["#","Title","Author","Status","Updated At"],colWidths:[8,45,15,10,15]});e.forEach(e=>{const l=e.draft?chalk.gray("Draft"):chalk.green("Open");t.push([chalk.green(`#${e.number}`),chalk.white(e.title.length>40?e.title.slice(0,37)+"...":e.title),e.user||"-",l,new Date(e.updated_at).toLocaleDateString()])}),console.log(t.toString()),console.log()}catch(e){console.log(" ".repeat(30)+"\r"),console.log(chalk.red(`[FAIL] Failed to fetch pull requests: ${e.message}`))}}else console.log(chalk.yellow("[WARN] Please join a room first: join <room-id>"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"statusgh",description:"Show GitHub connection and linked repository status",aliases:["statusgt","gh-status"],requiresAuth:!0,requiresRoom:!0,async execute(e,o){const l=o.ws.getCurrentRoom();if(l){console.log(chalk.dim("\n Fetching GitHub status...\r"));try{const e=await o.api._request("GET",`/thinknsh/${l}/github/status`);console.log(" ".repeat(30)+"\r"),console.log(chalk.cyan("\n GitHub Integration Status:")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(` ${chalk.yellow("GitHub Connection:")} ${e.connected?chalk.green("Connected [OK]"):chalk.red("Not Connected [FAIL]")}`),e.githubUsername&&console.log(` ${chalk.yellow("GitHub Username:")} ${e.githubUsername}`),console.log(` ${chalk.yellow("Repository Linked:")} ${e.repoLinked?chalk.green("Linked [OK]"):chalk.red("Not Linked [FAIL]")}`),e.repo&&console.log(` ${chalk.yellow("Repository Name:")} ${e.repo.fullName||`${e.repo.owner}/${e.repo.name}`}`),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),e.connected?e.repoLinked||console.log(chalk.yellow("\n Please link a GitHub repository to this room on the Web Dashboard repository setting page.")):console.log(chalk.yellow("\n Please connect your GitHub account via the Web Dashboard integration panel.")),console.log()}catch(e){console.log(" ".repeat(30)+"\r"),console.log(chalk.red(`[FAIL] Failed to fetch GitHub status: ${e.message}`))}}else console.log(chalk.yellow("[WARN] Please join a room first: join <room-id>"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");class CommandRegistry{constructor(s){this.shell=s,this.commands=new Map,this.aliases=new Map,this.categories=new Map,this.loadCommands()}loadCommands(){const s=(s,a)=>{try{const e=require(s);if(Array.isArray(e))return void e.forEach(s=>this.register(s,a));if(!e||!e.name)return void console.error(chalk.red(`[FAIL] BAD COMMAND (no name): ${s}`));this.register(e,a)}catch(a){console.error(chalk.red(`[FAIL] Failed to load ${s}: ${a.message}`))}};s("./auth/login","auth"),s("./auth/logout","auth"),s("./auth/whoami","auth"),s("./auth/register","auth"),s("./team/myteam","team"),s("./team/teammates","team"),s("./team/invite","team"),s("./room/join","room"),s("./room/leave","room"),s("./room/rooms","room"),s("./room/sync","room"),s("./message/say","message"),s("./shell/status","shell"),s("./shell/notify","shell"),s("./shell/version","shell"),s("./shell/doctor","shell"),s("./tasks/tasks","tasks"),s("./tasks/task","tasks"),s("./tasks/task-status","tasks"),s("./tasks/complete","tasks"),s("./tasks/create-task","tasks"),s("./tasks/loadtest","tasks"),s("./tasks/build","tasks"),s("./terminal/share","terminal"),s("./github/statusgh","github"),s("./github/issues","github"),s("./github/pulls","github"),s("./github/commits","github"),s("./github/issue-create","github"),s("./sandbox/sandbox","sandbox"),s("./sandbox/dev","sandbox"),s("./sandbox/freeze","sandbox"),s("./sandbox/resume","sandbox"),s("./sandbox/share","sandbox"),s("./sandbox/deploy","sandbox"),s("./sandbox/sync-deps","sandbox"),s("./sandbox/dep","sandbox"),s("./sandbox/console","sandbox"),s("./sandbox/snapshot","sandbox"),s("./sandbox/push","sandbox"),s("./dock/containers","containers"),s("./dock/dock","dock"),s("./dock/bench","dock"),s("./dock/cluster","dock"),s("./dock/ci","dock")}register(s,a){s&&s.name?(this.commands.set(s.name,s),this.categories.has(a)||this.categories.set(a,[]),this.categories.get(a).push(s.name),s.aliases&&s.aliases.forEach(a=>this.aliases.set(a,s.name))):console.error(chalk.yellow(`[WARN] Skipping invalid command in category: ${a}`))}addAlias(s,a){this.aliases.set(s,a)}getCommand(s){return this.commands.has(s)||this.aliases.has(s)&&(s=this.aliases.get(s)),this.commands.get(s)}async execute(s,a,e=null){const o=e&&e.length>0?e:a.parseCommand(s),t=o[0].toLowerCase(),n=o.slice(1),r=this.getCommand(t);if(!r)return!1;try{if(r.requiresAuth&&!a.api?.isAuthenticated())return console.log(chalk.red("[FAIL] Please login first: login")),!0;if(r.requiresRoom&&!a.ws?.getCurrentRoom())return console.log(chalk.red("[FAIL] Please join a room first: join <room-id>")),!0;a._lastCommand=t,await r.execute(n,a,t)}catch(s){console.log(chalk.red(`[FAIL] Command error: ${s.message}`))}return!0}getHelpText(){let s=chalk.cyan("\n Available Commands:\n");s+=chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n");for(const[a,e]of this.categories)s+=chalk.yellow(`${a.toUpperCase()}:\n`),e.forEach(a=>{const e=this.commands.get(a);if(!e||!a)return;const o=e.aliases?chalk.dim(` (${e.aliases.join(", ")})`):"";s+=` ${chalk.green(a.padEnd(14))}${o} - ${e.description||""}\n`}),s+="\n";return s}}module.exports=CommandRegistry;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"say",description:"Send a message to the current room",aliases:["msg","m","send"],requiresAuth:!0,requiresRoom:!0,async execute(e,o){const s=e.join(" ").trim();if(!s)return void console.log(chalk.red("[FAIL] Usage: say <message>"));const n=o.ws.getCurrentRoom?.();if(n)try{o.isTyping&&(o.ws.socket?.emit("thinknsh:typing",{roomId:n,typing:!1}),o.isTyping=!1,clearTimeout(o.typingTimeout)),await o.ws.sendMessage(s);const e=o.api.getUser(),t=(new Date).toLocaleTimeString();console.log(chalk.dim(`[${t}] `)+chalk.green(`${e?.name||"You"}: `)+chalk.white(s))}catch(e){console.log(chalk.red(`[FAIL] Failed to send: ${e.message}`))}else console.log(chalk.red("[FAIL] Not in any room. Use: join <room-id>"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),JOIN_TIMEOUT_MS=8e3;module.exports={name:"join",description:"Join a collaboration room",aliases:["enter","goto"],requiresAuth:!0,async execute(o,e){if(0===o.length)return void console.log(chalk.red("[FAIL] Usage: join <room-id> [password]"));const n=o[0],s=o[1];if(!e.ws.isConnected()){console.log(chalk.dim(" Connecting..."));try{await e.ws.connect()}catch(o){return void console.log(chalk.red(`[FAIL] WebSocket connect failed: ${o.message}`))}}let c;console.log(chalk.cyan(` Joining room ${chalk.bold(n)}...`));try{c=await e.api.joinRoom(n,s)}catch(o){return void(o.message?.toLowerCase().includes("password")?console.log(chalk.red(`[FAIL] Room requires a password: join ${n} <password>`)):o.message?.toLowerCase().includes("not found")?(console.log(chalk.red(`[FAIL] Room not found: ${n}`)),console.log(chalk.dim(' Type "rooms" to see available rooms'))):o.message?.toLowerCase().includes("not a member")||o.message?.toLowerCase().includes("unauthorized")?console.log(chalk.red("[FAIL] You are not a member of this room")):console.log(chalk.red(`[FAIL] Failed to join: ${o.message}`)))}const l=c.room||c,a=e.api.getUser?.()||{};await new Promise(o=>{const s=setTimeout(()=>{e.ws.socket?.off("thinknsh:joined",t),e.ws.socket?.off("thinknsh:error",i),console.log(chalk.red("[FAIL] Join timeout — server did not confirm. Try again.")),o()},8e3);function t(t){if(clearTimeout(s),e.ws.socket?.off("thinknsh:error",i),!t.success)return console.log(chalk.red(`[FAIL] Join rejected: ${t.message||"unknown error"}`)),void o();console.log(chalk.green(`[OK] Joined ${chalk.bold(l.name||n)}`)),l.description&&console.log(chalk.dim(` ${l.description}`));const r=c.participants||[];r.length&&console.log(chalk.dim(` ${r.length} participant(s)`));const h=t.history||[];h.length&&(console.log(chalk.cyan("\n Recent messages:")),h.slice(-5).forEach(o=>{const e=new Date(o.timestamp).toLocaleTimeString(),n=o.userId===a._id?.toString()||o.userId===a.id?.toString()?chalk.green("you"):chalk.cyan(o.name||"Unknown"),s="shell"===o.source?chalk.dim("[shell]"):"";console.log(` ${chalk.dim(`[${e}]`)} ${n}${s}: ${o.message}`)}));const d=r.filter(o=>o.online);d.length&&(console.log(chalk.cyan("\n Online:")),d.forEach(o=>{const e=o.email===a.email?chalk.green(" (you)"):"";console.log(` ${chalk.green("●")} ${o.name||o.email}${e}`)})),console.log(chalk.dim("\n say <message> to chat | leave to exit\n")),o()}function i(n){clearTimeout(s),e.ws.socket?.off("thinknsh:joined",t),console.log(chalk.red(`[FAIL] ${n.message||"Join error"}`)),o()}e.ws.socket.once("thinknsh:joined",t),e.ws.socket.once("thinknsh:error",i),e.ws.socket.emit("thinknsh:join",{roomId:n,userId:a._id?.toString()||a.id?.toString(),name:a.name||a.username||"Unknown",userType:a.model||a.role||"User"})})}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"leave",description:"Leave current room",aliases:["exit-room","part"],requiresAuth:!0,requiresRoom:!0,async execute(e,o){o.ws.getCurrentRoom()?(console.log(chalk.cyan(" Leaving room...")),await o.ws.leaveRoom(),console.log(chalk.green("[OK] Left room"))):console.log(chalk.yellow("[WARN] Not in any room"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk");module.exports={name:"rooms",description:"List available rooms",aliases:["channels","ls"],requiresAuth:!0,async execute(o,e){const l=o.includes("--all")||o.includes("-a");console.log(chalk.cyan("\n Available Rooms:")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));try{const o=await e.api.getRooms(),a=e?.api?.getCurrentRoom?.()||e?.ws?.getCurrentRoom?.(),n="string"==typeof a?{id:a}:a||null;if(0===o.length)return console.log(chalk.yellow(" No rooms available")),void console.log(chalk.dim(" Create a room with: join <new-room-name>"));const c=o.filter(o=>o.isMember),s=o.filter(o=>!o.isMember);c.length>0&&(console.log(chalk.yellow("\n YOUR ROOMS:")),c.forEach(o=>{const e=n&&n.id===o.id?chalk.green(" (current)"):"",l=o.active?chalk.green("●"):chalk.gray("○");console.log(` ${l} ${chalk.white(o.name)}${e}`),console.log(chalk.dim(` ${o.participants} online · ${o.description||""}`))})),s.length>0&&l?(console.log(chalk.yellow("\n PUBLIC ROOMS:")),s.slice(0,10).forEach(o=>{console.log(` ○ ${chalk.white(o.name)}`),console.log(chalk.dim(` ${o.participants} online · ${o.description||""}`))}),s.length>10&&console.log(chalk.dim(` ... and ${s.length-10} more (use --all to see all)`))):s.length>0&&console.log(chalk.dim(`\n ${s.length} other rooms available (use --all to see)`)),console.log(chalk.dim('\n Type "join <room-name>" to join a room'))}catch(o){console.log(chalk.red(`[FAIL] Failed to fetch rooms: ${o.message}`))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3"),RoomSyncManager=require("../../core/sandbox/room-sync-manager");module.exports={name:"room",description:"Manage room environments, live states, collaboration, and P2P sync",aliases:["room-sync","sync","mirror"],requiresAuth:!0,async execute(e,o){const n=e[0]?.toLowerCase()||"help";if("join"===n)return require("./join").execute(e.slice(1),o);if("leave"===n)return require("./leave").execute(e.slice(1),o);if("rooms"===n||"list"===n&&!e[1])return require("./rooms").execute(e.slice(1),o);const r=new RoomSyncManager,t=o?.ws?.getCurrentRoom?.()||o?.currentRoom||o?.api?.getCurrentRoom?.()||o?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID,a="object"==typeof t&&null!==t?t.id||t._id||t.roomId:t;if(!a)return console.log(chalk.red("\n[FAIL] You are not in an active room.")),void console.log(chalk.dim(" Join a room first using: join <room-id> or room join <room-id>\n"));if("publish"===n||"share"===n||"push"===n){const n=e.slice(1).find(e=>!e.startsWith("-"))||"dev-state",t=e.includes("--no-code")||e.includes("--db-only");try{await r.publishState(a,o,{name:n,cwd:process.cwd(),noCode:t})}catch(e){console.log(chalk.red(`\n[FAIL] Could not publish state to room: ${e.message}\n`))}return}if("states"===n||"list"===n||"ls"===n){const e=await r.listStates(a,o);if(console.log(chalk.cyan(`\n[RoomSync] Shared States in Room [${a}]:`)),0===e.length)return console.log(chalk.dim(" No shared states found in this room yet.")),void console.log(chalk.dim(" Publish your current state with: thinknsh room share\n"));const n=new Table({head:[chalk.cyan("STATE ID"),chalk.cyan("NAME"),chalk.cyan("AUTHOR"),chalk.cyan("SERVICES"),chalk.cyan("CODE"),chalk.cyan("SIZE"),chalk.cyan("CREATED")],style:{head:[],border:[]}});return e.forEach(e=>{n.push([chalk.green((e.id||e.stateId||"").slice(0,16)),chalk.bold(e.name||e.id),e.author||"teammate",(e.services||[]).join(", ")||"runtime",e.hasCode?chalk.green("✓ Yes"):chalk.dim("No"),`${e.sizeMB||e.bundleSizeMB||"0"} MB`,e.createdAt||e.publishedAt?new Date(e.createdAt||e.publishedAt).toLocaleTimeString():"now"])}),console.log(n.toString()),void console.log(chalk.dim("\nPull any state using: thinknsh room pull <state-id>\n"))}if("pull"===n||"sync"===n||"merge"===n){const n=e.slice(1).filter(e=>!e.startsWith("-")),t=n.length>0?n.join(" "):null,l=e.includes("--overwrite")||e.includes("--force");try{await r.pullState(a,t,o,{cwd:process.cwd(),overwrite:l})}catch(e){console.log(chalk.red(`\n[FAIL] Could not sync state from room: ${e.message}\n`))}return}if("undo"!==n&&"rollback"!==n&&"revert"!==n){if("verify"===n||"safety"===n||"safety-number"===n){const o=require("../../core/crypto/e2ee-vault"),n=e[1]?.toLowerCase();if("mark"===n&&e[2]){const n=e[2];return void(o.markPeerVerified(n)?console.log(chalk.green(`\n[OK] Peer "${n}" marked as MANUALLY VERIFIED.`)):console.log(chalk.yellow(`\n[Notice] Peer "${n}" not found in local known_peers.json registry.`)))}const r=o.getRoomKey(a),t=o.computeSafetyNumber(r),l=o._fingerprint(r),c=o.getKnownPeers();console.log(chalk.cyan.bold("\n ThinkNCollab End-to-End Encryption (E2EE) Verification")),console.log(chalk.dim(" "+"═".repeat(60))),console.log(chalk.white(" Room ID: ")+chalk.bold(a)),console.log(chalk.white(" Active Key Fingerprint: ")+chalk.green(l)),console.log(chalk.white("\n 60-DIGIT SAFETY NUMBER (Compare with teammates on call/Slack):")),console.log(chalk.yellow.bold(" ┌────────────────────────────────────────────────────────┐")),console.log(chalk.yellow.bold(` │ ${t} │`)),console.log(chalk.yellow.bold(" └────────────────────────────────────────────────────────┘")),console.log(chalk.dim(" If the digits match on both sides, your channel is guaranteed free")),console.log(chalk.dim(" from any Man-In-The-Middle (MITM) tampering or compromised relays.\n"));const s=Object.entries(c);if(s.length>0){console.log(chalk.cyan(" Known Peers in TOFU (Trust-On-First-Use) Registry:"));const e=new Table({head:[chalk.cyan("USER ID"),chalk.cyan("KEY FINGERPRINT"),chalk.cyan("FIRST SEEN"),chalk.cyan("STATUS")],style:{head:[],border:[]}});s.forEach(([o,n])=>{e.push([o,n.fingerprint||"unknown",n.firstSeen?new Date(n.firstSeen).toLocaleDateString():"recent",n.verified?chalk.green("✓ VERIFIED"):chalk.yellow("● TOFU (UNVERIFIED)")])}),console.log(e.toString()),console.log(chalk.dim("\n To mark a peer verified: thinknsh room verify mark <userId>\n"))}else console.log(chalk.dim(" No remote peer public keys recorded yet in this workspace.\n"));return}if("rotate-key"===n||"rekey"===n){const e=require("../../core/crypto/e2ee-vault");console.log(chalk.cyan(`\n[RoomKey] Rotating 256-bit encryption key for Room [${a}]...`));const n=e.rotateRoomKey(a),r=e.computeSafetyNumber(n),t=e._fingerprint(n);if(o?.ws?.isConnected?.())try{o.ws.socket.emit("thinknsh:room-rekeyed",{roomId:a,fingerprint:t,rotatedAt:(new Date).toISOString()})}catch(e){}return console.log(chalk.green("[OK] Room key rotated successfully (Forward Secrecy Activated)!")),console.log(chalk.dim(" Previous key has been securely moved to archive (~/.tnc/vault/rooms/archive).")),console.log(chalk.dim(" Evicted members can no longer decrypt newly published state bundles or terminal streams.")),console.log(chalk.white(" New Key Fingerprint: ")+chalk.green(t)),void console.log(chalk.white(" New Safety Number: ")+chalk.yellow(r)+"\n")}console.log(chalk.cyan("\n ThinkNCollab Room Commands")),console.log(chalk.dim(" "+"─".repeat(45))),[["room share [name]","Publish project code, database & env state to room"],["room pull [state]","Smart-merge teammate code, database & env into workspace"],["room merge [state]","Smart 3-way merge teammate changes into workspace"],["room undo","Rollback last merge from safety backup"],["room states","List shared state bundles in room"],["room verify","Show E2EE 60-digit safety number & TOFU peers"],["room rotate-key","Rotate room key (Forward Secrecy on eviction)"],["room join <id>","Join a collaborative room"],["room leave","Leave current room"],["room list","List available rooms"]].forEach(([e,o])=>{console.log(` ${chalk.green(e.padEnd(24))} ${chalk.dim(o)}`)}),console.log()}else try{r.rollbackLastMerge(a,process.cwd())}catch(e){console.log(chalk.red(`\n[FAIL] Could not undo merge: ${e.message}\n`))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),{SandboxEngine}=require("../../core/sandbox"),SandboxWindowLauncher=require("../../core/sandbox/window-launcher");module.exports={name:"console",description:"Launch the dedicated 3rd Terminal Window for a sandbox",aliases:["terminal","sandbox-window"],requiresAuth:!1,async execute(n,o){let e=n[0];if(!e){const n=(new SandboxEngine).list().filter(n=>"RUNNING"===n.state);if(1!==n.length)return n.length>1?(console.log(chalk.yellow("Multiple sandboxes running. Please specify one:")),void n.forEach(n=>console.log(` • thinknsh console ${n.id}`))):void console.log(chalk.yellow("No running sandbox found. Start one first using: thinknsh dev"));e=n[0].id}console.log(chalk.cyan(`\nLaunching Sandbox Console Window for [${chalk.bold(e)}]...`)),SandboxWindowLauncher.spawn(e)}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3"),path=require("path"),{execSync}=require("child_process"),{getDepStore}=require("../../core/dep-store"),DependencyTracker=require("../../core/dependency-tracker"),MANAGER_INSTALL_CMD={npm:e=>`npm install ${e}`,pip:e=>`pip3 install ${e}`,cargo:e=>`cargo add ${e}`,go:e=>`go get ${e}`,brew:e=>`brew install ${e}`,apt:e=>`apt-get install -y ${e}`,system:e=>null},MANAGER_REMOVE_CMD={npm:e=>`npm uninstall ${e}`,pip:e=>`pip3 uninstall -y ${e}`,cargo:e=>`cargo remove ${e}`,go:e=>`go mod edit -droprequire ${e}`,brew:e=>`brew uninstall ${e}`,apt:e=>`apt-get remove -y ${e}`,system:e=>null};function detectManager(e){const n=-1!==e.indexOf("--manager")?e.indexOf("--manager"):e.indexOf("-m");return-1!==n&&e[n+1]?e[n+1]:"npm"}module.exports={name:"dep",description:"Multi-language dependency manager (install, remove, list, status, sync, log)",aliases:["deps","dependencies","pkg"],requiresAuth:!1,async execute(e,n){const a=getDepStore(),o=e[0]?.toLowerCase(),l=process.cwd(),c=path.basename(l);if("install"===o||"add"===o||"i"===o){const t=e.find(e=>!e.startsWith("-")&&e!==o);if(!t)return void console.log(chalk.red("[FAIL] Usage: dep install <package>[@version] [--manager npm|pip|cargo|go]"));const s=t.match(/^([^@>=<^~]+)(?:[@>=<^~]+(.+))?$/),r=s?s[1]:t,i=s&&s[2]||null,d=detectManager(e),g=n.activeSandbox?.id||null,p=MANAGER_INSTALL_CMD[d]?.(t);if(!p)return console.log(chalk.yellow(`[INFO] Package "${r}" registered in dep store for system manager. Install manually.`)),a.recordDep(r,{version:i,manager:d,project:c,sandboxId:g,status:"pending"}),void a.logAction(r,{manager:d,action:"register",sandboxId:g,project:c});console.log(chalk.cyan(`\n⟳ Installing ${chalk.bold(t)} via ${chalk.yellow(d)}...`));try{execSync(p,{stdio:"inherit",cwd:l}),a.recordDep(r,{version:i,manager:d,project:c,sandboxId:g,status:"installed"}),a.logAction(r,{manager:d,action:"install",sandboxId:g,project:c});try{const e=new DependencyTracker(l);await e.scanAndRecord(n)}catch(e){}console.log(chalk.green(`\n[OK] ${r} installed & recorded in dep store (${chalk.dim("~/.tnc/deps.db")})\n`))}catch(e){a.recordDep(r,{version:i,manager:d,project:c,sandboxId:g,status:"failed"}),a.logAction(r,{manager:d,action:"fail",sandboxId:g,project:c,error:e.message}),console.log(chalk.red(`[FAIL] Install failed: ${e.message}`))}return}if("remove"===o||"rm"===o||"uninstall"===o){const t=e.find(e=>!e.startsWith("-")&&e!==o);if(!t)return void console.log(chalk.red("[FAIL] Usage: dep remove <package> [--manager npm|pip|cargo|go]"));const s=detectManager(e),r=n.activeSandbox?.id||null,i=MANAGER_REMOVE_CMD[s]?.(t);if(i){console.log(chalk.cyan(`\n⟳ Removing ${chalk.bold(t)} via ${chalk.yellow(s)}...`));try{execSync(i,{stdio:"inherit",cwd:l})}catch(e){console.log(chalk.yellow(`[WARN] Remove command had issues: ${e.message.split("\n")[0]}`))}}a.removeDep(t,{manager:s,project:c}),a.logAction(t,{manager:s,action:"remove",sandboxId:r,project:c});try{const e=new DependencyTracker(l);await e.scanAndRecord(n)}catch(e){}return void console.log(chalk.green(`\n[OK] ${t} removed from dep store.\n`))}if("list"===o||"ls"===o){const n=e.includes("--manager")?e[e.indexOf("--manager")+1]:null,o=e.includes("--sandbox")?e[e.indexOf("--sandbox")+1]:null,l=e.includes("--status")?e[e.indexOf("--status")+1]:null,c=e.includes("--project")?e[e.indexOf("--project")+1]:null,t=a.listDeps({manager:n,project:c,sandboxId:o,status:l});if(0===t.length)return void console.log(chalk.yellow('\n No recorded dependencies found. Run "dep install <pkg>" or "dep sync" to populate.\n'));const s=new Table({head:[chalk.cyan("Package"),chalk.cyan("Version"),chalk.cyan("Manager"),chalk.cyan("Project"),chalk.cyan("Status"),chalk.cyan("Installed At")],colWidths:[28,14,10,18,12,22],style:{head:[],border:[]}});for(const e of t){const n="installed"===e.status?chalk.green:"failed"===e.status?chalk.red:chalk.yellow;s.push([chalk.white(e.name),e.version||chalk.dim("latest"),chalk.yellow(e.manager),e.project||chalk.dim("-"),n(e.status||"unknown"),e.installed_at?chalk.dim(e.installed_at.split("T")[0]):chalk.dim("-")])}return console.log(chalk.cyan("\n TNC Dependency Registry — ~/.tnc/deps.db")),console.log(` Total: ${chalk.bold(t.length)} packages\n`),console.log(s.toString()),void console.log("")}if("status"===o){const e=a.summary({project:path.basename(l)}),n=a.summary();if(console.log(chalk.cyan("\n TNC Dependency Store Status")),console.log(chalk.dim(" DB: ~/.tnc/deps.db\n")),console.log(chalk.yellow(` Current Project: ${chalk.white(c)}`)),0===Object.keys(e).length)console.log(chalk.dim(" No dependencies recorded for this project."));else for(const[n,a]of Object.entries(e))console.log(` ${chalk.green("●")} ${chalk.yellow(n.padEnd(10))} ${chalk.white(a)} packages`);console.log(chalk.yellow("\n Global Store:"));for(const[e,a]of Object.entries(n))console.log(` ${chalk.dim("○")} ${chalk.dim(e.padEnd(10))} ${chalk.dim(a)} packages`);const o=a.getLog({limit:3});if(o.length>0){console.log(chalk.yellow("\n Recent Activity:"));for(const e of o){const n="install"===e.action?chalk.green("↑ install"):"remove"===e.action?chalk.red("↓ remove"):chalk.yellow(` ${e.action}`);console.log(` ${n} ${chalk.white(e.package_name)} [${chalk.dim(e.manager)}] ${chalk.dim(e.timestamp?.split("T")[0]||"")}`)}}return void console.log("")}if("log"===o){const n=e.indexOf("--limit"),o=-1!==n&&parseInt(e[n+1])||20,l=a.getLog({limit:o});if(0===l.length)return void console.log(chalk.yellow("\n No install history found.\n"));const c=new Table({head:[chalk.cyan("Action"),chalk.cyan("Package"),chalk.cyan("Manager"),chalk.cyan("Project"),chalk.cyan("Timestamp")],colWidths:[12,28,10,18,22],style:{head:[],border:[]}});for(const e of l){const n="install"===e.action?chalk.green(e.action):"remove"===e.action?chalk.red(e.action):chalk.yellow(e.action);c.push([n,e.package_name,chalk.yellow(e.manager),e.project||"-",chalk.dim(e.timestamp||"")])}return console.log(chalk.cyan(`\n TNC Dep Install Log (last ${o}):\n`)),console.log(c.toString()),void console.log("")}if("sync"!==o){if("purge"===o){const n=e[1]||c;return a.purgeProject(n),void console.log(chalk.green(`[OK] All dep records for project "${n}" purged from store.\n`))}console.log(`\n${chalk.cyan("TNC Dependency Manager — Docker-style package control")}\n\n${chalk.yellow("Usage:")}\n dep install <pkg>[@version] [--manager npm|pip|cargo|go] Install & record\n dep remove <pkg> [--manager npm|pip|cargo|go] Uninstall & mark removed\n dep list [--manager X] [--sandbox X] [--status X] List dep registry\n dep status Show dep store summary\n dep log [--limit 20] Install history\n dep sync Sync from thinkncollab.yml\n dep purge <project> Wipe project records\n\n${chalk.yellow("Examples:")}\n dep install express@4.18.2\n dep install --manager pip numpy\n dep list --manager npm\n dep list --sandbox my-sandbox\n dep status\n dep sync\n\n${chalk.dim("Registry: ~/.tnc/deps.db (SQLite) or ~/.tnc/deps.json (fallback)")}\n`)}else{console.log(chalk.cyan("\n⟳ Syncing thinkncollab.yml → dep store..."));try{const e=new DependencyTracker(l).loadConfig();getDepStore().recordFromConfig(e,{sandboxId:n.activeSandbox?.id||null}),console.log(chalk.green("[OK] Dep store synchronized from thinkncollab.yml\n")),console.log(chalk.dim(' Run "dep list" to view recorded packages.\n'))}catch(e){console.log(chalk.red(`[FAIL] Sync error: ${e.message}`))}}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),path=require("path"),fs=require("fs-extra"),{SandboxEngine}=require("../../core/sandbox"),SandboxTunnel=require("../../core/sandbox/tunnel"),engine=new SandboxEngine;function syncToDashboard(e,o,n){if(n?.ws?.isConnected())try{n.ws.emitSandboxSync(e,o)}catch(e){}return new Promise(r=>{let t=!1;const s=()=>{t||(t=!0,r())},a=(n?.ws?.config?.serverUrl||n?.api?.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com").replace(/\/$/,""),i=n?.ws?.getCurrentRoom?.()||n?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID||e?.roomId||null,c=n?.api?.getUser?.()?._id||n?.api?.getUser?.()?.id||n?.api?.userId||n?.ws?.userId||n?.config?.user?._id||n?.config?.userId||process.env.THINKNCOLLAB_USER_ID||e?.userId||null,l=n?.config?.roomName||e?.roomName||null,d=n?.api?.getUser?.()?.name||n?.config?.user?.name||n?.config?.userName||n?.config?.username||e?.userName||process.env.THINKNCOLLAB_USER_NAME||null,p={event:o,sandbox:{...e,roomId:i||e?.roomId||null,roomName:l||e?.roomName||null,userId:c||e?.userId||null,userName:d||e?.userName||null},roomId:i||e?.roomId||null,roomName:l||e?.roomName||null,userId:c||e?.userId||null,userName:d||e?.userName||null,timestamp:(new Date).toISOString()};try{const e=require("socket.io-client")(a+"/thinknsh",{transports:["websocket","polling"],timeout:1200,reconnection:!1});e.on("connect",()=>{e.emit("sandbox:sync",p),setTimeout(()=>{e.disconnect(),s()},60)}),e.on("connect_error",()=>{e.disconnect(),s()})}catch(e){s()}try{const e=a.startsWith("https"),o=e?require("https"):require("http"),n=new URL(a),r=JSON.stringify(p),t=o.request({hostname:n.hostname,port:n.port||(e?443:80),path:"/thinknsh/api/sandboxes/sync",method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r)},timeout:1e3},()=>s());t.on("error",()=>s()),t.on("timeout",()=>{t.destroy(),s()}),t.write(r),t.end()}catch(e){s()}setTimeout(s,1500)})}const net=require("net");function isPortInUse(e){return new Promise(o=>{const n=net.createServer();n.once("error",()=>o(!0)),n.once("listening",()=>{n.close(()=>o(!1))}),n.listen(e,"0.0.0.0")})}async function findFreePort(e=5e3){let o=e;for(;o<65535;){if(!await isPortInUse(o))return o;o++}return 5e3}module.exports={name:"deploy",description:"Deploy project directly into isolated Zero-Docker No-Daemon Production environment",aliases:["prod-deploy","release"],requiresAuth:!1,async execute(e,o){const n=process.cwd(),r=e[0]&&!e[0].startsWith("-")?e[0]:"production",t=`prod-${path.basename(n).toLowerCase().replace(/[^a-z0-9_-]/g,"-").replace(/^-+|-+$/g,"")||"app"}`;console.log(chalk.cyan(`\n Initializing No-Docker Production Deployment [${chalk.bold(t)}]...`)),console.log(chalk.dim(` Target Env : ${chalk.bold.green(r.toUpperCase())}`)),console.log(chalk.dim(` Source Folder : ${n}`));let s="npm start",a=3e3;const i=path.join(n,"package.json");if(fs.existsSync(i))try{const e=fs.readJsonSync(i);s=e.scripts?.start?"npm start":e.scripts?.dev?"npm run dev":"node server.js",e.config?.port&&(a=parseInt(e.config.port,10))}catch(e){}else fs.existsSync(path.join(n,"app.py"))&&(s="python3 app.py",a=5e3);let c=null;for(let o=0;o<e.length;o++)"-p"!==e[o]&&"--port"!==e[o]||!e[o+1]||(c=parseInt(e[o+1],10));c||(c=await isPortInUse(a)?await findFreePort(5e3):a);const l=o?.ws?.getCurrentRoom?.()||o?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID||null,d=o?.api?.getUser?.()?._id||o?.api?.getUser?.()?.id||o?.api?.userId||o?.ws?.userId||o?.config?.user?._id||o?.config?.userId||process.env.THINKNCOLLAB_USER_ID||null,p=o?.config?.roomName||null,m=o?.api?.getUser?.()?.name||o?.config?.user?.name||o?.config?.userName||o?.config?.username||process.env.THINKNCOLLAB_USER_NAME||null;console.log(chalk.cyan(`\n[Deploy] Launching Native Kernel Sandbox (${r})...`));const u=await engine.start(t,{cmd:s,cwd:n,hostPort:c,containerPort:c,memoryLimit:"2g",allowNetwork:!0,roomId:l,roomName:p,userId:d,userName:m});if(u.success||u.meta&&u.message?.includes("already running")){const e={...u.meta,environment:"production",deployedAt:(new Date).toISOString()},n=(o?.ws?.config?.serverUrl||o?.api?.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com").replace(/\/$/,""),r=`${n}/thinknsh/proxy/${encodeURIComponent(e.id||id)}/`,t=`${n}/thinknsh/preview/${encodeURIComponent(e.id||id)}`;console.log(chalk.green("\n[OK] Production Release Live! (Zero Docker Daemon Overhead)")),console.log(` Public Gateway : ${chalk.bold.cyan(r)}`),console.log(` Preview URL : ${chalk.cyan(t)}`),console.log(` Live Dashboard : ${chalk.underline(`${n}/thinknsh/sandboxes?env=production${l?"&roomId="+l:""}`)}`),console.log(` PID : ${e.pid}`),console.log(` Isolation Model: ${chalk.magenta(e.isolationLevel)} (Bare-metal cgroup slice)`),e.roomId&&console.log(` Workspace Room : ${e.roomName||e.roomId}`),console.log(chalk.dim("\n Health Check: PASS (100% Availability)\n")),await syncToDashboard(e,"deployed",o);const s=new SandboxTunnel;s.connect(e.id||id,c,o),console.log(chalk.green(" Tunnel : ACTIVE")),console.log(chalk.dim(` Remote preview streams via thinkncollab.com/thinknsh/proxy/${encodeURIComponent(e.id||id)}/\n`)),process.on("SIGINT",()=>{s.stop(),process.exit(0)}),process.on("SIGTERM",()=>{s.stop(),process.exit(0)})}else console.log(chalk.red(`\n[Error] Deployment failed: ${u.message}\n`))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),path=require("path"),fs=require("fs-extra"),net=require("net"),{SandboxEngine}=require("../../core/sandbox"),SandboxTunnel=require("../../core/sandbox/tunnel"),engine=new SandboxEngine;function isPortInUse(e){return new Promise(n=>{const o=net.createServer();o.once("error",e=>{"EADDRINUSE"===e.code?n(!0):n(!1)}),o.once("listening",()=>{o.close(),n(!1)}),o.listen(e)})}async function findFreePort(e=4e3){let n=e;for(;n<65535;){if(!await isPortInUse(n))return n;n++}return 4e3}function detectProjectConfig(e){const n=path.join(e,"package.json");if(fs.existsSync(n))try{const o=fs.readJsonSync(n);let s="node server.js",t=3e3;return o.scripts?.dev?s="npm run dev":o.scripts?.start?s="npm start":fs.existsSync(path.join(e,"server.js"))?s="node server.js":fs.existsSync(path.join(e,"app.js"))?s="node app.js":fs.existsSync(path.join(e,"index.js"))&&(s="node index.js"),o.config?.port&&(t=parseInt(o.config.port,10)),{type:"Node.js",cmd:s,containerPort:t}}catch(e){}return fs.existsSync(path.join(e,"CMakeLists.txt"))?{type:"C++",cmd:"cmake -B build && cmake --build build && (./build/app || ./build/main || ./build/server || true)",containerPort:8080}:fs.existsSync(path.join(e,"Makefile"))?{type:"C++",cmd:"make && (./app || ./main || ./server || true)",containerPort:8080}:fs.existsSync(path.join(e,"main.cpp"))?{type:"C++",cmd:"g++ -std=c++17 main.cpp -o app && ./app",containerPort:8080}:fs.existsSync(path.join(e,"app.py"))?{type:"Python",cmd:"python3 app.py",containerPort:5e3}:fs.existsSync(path.join(e,"main.py"))?{type:"Python",cmd:"python3 main.py",containerPort:8e3}:fs.existsSync(path.join(e,"main.go"))||fs.existsSync(path.join(e,"go.mod"))?{type:"Go",cmd:"go run .",containerPort:8080}:fs.existsSync(path.join(e,"Cargo.toml"))?{type:"Rust",cmd:"cargo run",containerPort:8080}:{type:"Generic",cmd:"node server.js",containerPort:3e3}}function syncToDashboard(e,n,o){if(o?.ws?.isConnected())try{o.ws.emitSandboxSync(e,n)}catch(e){}return new Promise(s=>{let t=!1;const r=()=>{t||(t=!0,s())},a=(o?.ws?.config?.serverUrl||o?.api?.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com").replace(/\/$/,""),c=o?.ws?.getCurrentRoom?.()||o?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID||e?.roomId||null,i=o?.api?.getUser?.()?._id||o?.api?.getUser?.()?.id||o?.api?.userId||o?.ws?.userId||o?.config?.user?._id||o?.config?.userId||process.env.THINKNCOLLAB_USER_ID||e?.userId||null,l=o?.config?.roomName||e?.roomName||null,d=o?.api?.getUser?.()?.name||o?.config?.user?.name||o?.config?.userName||o?.config?.username||e?.userName||process.env.THINKNCOLLAB_USER_NAME||null,p={event:n,sandbox:{...e,roomId:c||e?.roomId||null,roomName:l||e?.roomName||null,userId:i||e?.userId||null,userName:d||e?.userName||null},roomId:c||e?.roomId||null,roomName:l||e?.roomName||null,userId:i||e?.userId||null,userName:d||e?.userName||null,timestamp:(new Date).toISOString()};try{const e=require("socket.io-client")(a+"/thinknsh",{transports:["websocket","polling"],timeout:1200,reconnection:!1});e.on("connect",()=>{e.emit("sandbox:sync",p),setTimeout(()=>{e.disconnect(),r()},60)}),e.on("connect_error",()=>{e.disconnect(),r()})}catch(e){r()}try{const e=a.startsWith("https"),n=e?require("https"):require("http"),o=new URL(a),s=JSON.stringify(p),t=n.request({hostname:o.hostname,port:o.port||(e?443:80),path:"/thinknsh/api/sandboxes/sync",method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(s)},timeout:1e3},()=>r());t.on("error",()=>r()),t.on("timeout",()=>{t.destroy(),r()}),t.write(s),t.end()}catch(e){r()}setTimeout(r,1500)})}module.exports={name:"dev",description:"Zero-config smart auto-detection & sandbox launcher for current directory",aliases:["up","run-app"],requiresAuth:!1,async execute(e,n){const o=process.cwd(),s=path.basename(o).toLowerCase().replace(/[^a-z0-9_-]/g,"-").replace(/^-+|-+$/g,"")||"app";let t=null;const r=[];for(let n=0;n<e.length;n++)"--name"!==e[n]&&"-n"!==e[n]||!e[n+1]?e[n].startsWith("--name=")?t=e[n].slice(7):r.push(e[n]):(t=e[n+1],n++);const a=t||r[0]||s;console.log(chalk.cyan(`\n[Inspect] Project in: ${chalk.bold(o)}`));const c=detectProjectConfig(o);console.log(chalk.dim(` Type Detected : ${chalk.green(c.type)}`)),console.log(chalk.dim(` Launch Command: ${chalk.white(c.cmd)}`));let i=c.containerPort;for(let n=0;n<e.length;n++)if(("-p"===e[n]||"--port"===e[n])&&e[n+1]){const o=e[n+1].split(":");i=o[1]?parseInt(o[1],10):parseInt(o[0],10)}let l=i;await isPortInUse(l)&&(l=await findFreePort(4e3),console.log(chalk.yellow(` [Notice] Port ${i} is busy on host. Auto-routing to Host Port ${chalk.bold(l)}`))),console.log(chalk.dim(` Port Mapping : Host:${chalk.bold(l)} -> Container:${i}`));const d=n?.ws?.getCurrentRoom?.()||n?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID||null,p=n?.api?.getUser?.()?._id||n?.api?.getUser?.()?.id||n?.api?.userId||n?.ws?.userId||n?.config?.user?._id||n?.config?.userId||process.env.THINKNCOLLAB_USER_ID||null,u=n?.config?.roomName||null,m=n?.api?.getUser?.()?.name||n?.config?.user?.name||n?.config?.userName||n?.config?.username||process.env.THINKNCOLLAB_USER_NAME||null;console.log(chalk.cyan(`\n[Launch] Auto-Launching TNC Sandbox [${chalk.bold(a)}]...`));const h=await engine.start(a,{cmd:c.cmd,cwd:o,hostPort:l,containerPort:i,roomId:d,roomName:u,userId:p,userName:m});if(h.success||h.meta&&h.message?.includes("already running")){const o=h.meta,s=!h.success,t={"linux-unshare":chalk.green("linux-unshare (kernel)"),"macos-seatbelt":chalk.magenta("macos-seatbelt (syscall)"),"wsl2-kernel":chalk.blue("wsl2-kernel (linux)"),"host-process":chalk.gray("host-process (basic)")}[o.isolationLevel]||chalk.gray(o.isolationLevel);s?console.log(chalk.green(`\n[OK] Sandbox "${a}" is ALREADY UP and running!`)):console.log(chalk.green(`\n[OK] Sandbox "${a}" is UP and running!`));const r=(n?.ws?.config?.serverUrl||n?.api?.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com").replace(/\/$/,""),c=`${r}/thinknsh/proxy/${encodeURIComponent(a)}/`,i=`${r}/thinknsh/preview/${encodeURIComponent(a)}`;console.log(` App URL : ${chalk.bold.cyan(c)}`),console.log(` Preview URL : ${chalk.cyan(i)}`),console.log(` Web Dashboard : ${chalk.underline(`${r}/thinknsh/sandboxes${d?"?roomId="+d:""}`)}`),console.log(` PID : ${o.pid}`),console.log(` Isolation : ${t}`),o.roomId&&console.log(` Workspace Room : ${o.roomName||o.roomId}`),console.log(chalk.dim("\n Quick Controls:")),console.log(chalk.dim(` Console (3rd Win): thinknsh console ${a} (or thinknsh logs -w ${a})`)),console.log(chalk.dim(` Stream Logs : thinknsh logs -f ${a}`)),console.log(chalk.dim(` Pause / Freeze : thinknsh sandbox freeze ${a}`)),console.log(chalk.dim(` Wakeup : thinknsh sandbox resume ${a}`)),console.log(chalk.dim(` Destroy : thinknsh sandbox destroy ${a}\n`)),e.includes("--no-window")||e.includes("--headless")||require("../../core/sandbox/window-launcher").spawn(a),await syncToDashboard(o,s?"updated":"started",n);const p=new SandboxTunnel;p.connect(a,l,n),console.log(chalk.green(" Tunnel : ACTIVE")),console.log(chalk.dim(` Remote preview streams via thinkncollab.com/thinknsh/proxy/${encodeURIComponent(a)}/`)),process.on("SIGINT",()=>{p.stop(),process.exit(0)}),process.on("SIGTERM",()=>{p.stop(),process.exit(0)})}else console.log(chalk.red(`\n[Error] Failed to start sandbox: ${h.message}\n`))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),{spawnSync}=require("child_process"),{SandboxEngine}=require("../../core/sandbox");module.exports={name:"exec",description:"Execute a command inside a running native sandbox container",requiresAuth:!1,async execute(e,n){if(0===e.length)return void console.log(chalk.yellow("Usage: thinknsh exec [-it] [-e KEY=VAL] [-w /dir] <container-id> <command...>"));let o=0;const r={};let i=null,c=null;for(;o<e.length;){const n=e[o];if("-it"===n||"-i"===n||"-t"===n)o++;else if("-e"===n&&e[o+1]){const[n,i]=e[o+1].split("=");n&&(r[n]=i||""),o+=2}else{if("-w"!==n||!e[o+1]){if(c)break;c=n,o++;break}i=e[o+1],o+=2}}const t=e.slice(o);if(!c||0===t.length)return void console.log(chalk.yellow("Usage: thinknsh exec <container-id> <command...>"));const s=(new SandboxEngine).loadMeta(c);if(!s||"RUNNING"!==s.state)return void console.log(chalk.red(`[FAIL] Container "${c}" is not running (Current State: ${s?s.state:"NOT_FOUND"}).`));const a=i||s.cwd||process.cwd(),l={...process.env,...s.environment,...r,TNC_CONTAINER_ID:c};if(console.log(chalk.dim(` [TNC:Exec] Attaching to container "${c}" (PID: ${s.pid})...\n`)),"macos-microvm-vz"===s.isolationLevel||"linux-microvm-vz"===s.isolationLevel)try{const{getMicroVMManager:e}=require("../../core/sandbox/microvm-manager"),n=e(),o=t.map(e=>e.includes(" ")||e.includes("\t")||e.includes(";")||e.includes('"')||e.includes("$")?`"${e.replace(/(["\\$`])/g,"\\$1")}"`:e).join(" "),r=await n.exec(c,o);return r&&r.ok?void(r.output&&process.stdout.write(r.output)):void console.log(chalk.red(`[FAIL] Exec error: ${r?r.error:"Unknown error"}`))}catch(e){return void console.log(chalk.red(`[FAIL] Exec error: ${e.message}`))}if("linux"===process.platform&&s.pid)try{const e=["-t",String(s.pid),"-m","-u","-i","-n","-p","--",...t];if(0===spawnSync("nsenter",e,{stdio:"inherit",env:l,cwd:a}).status)return}catch(e){}const d=t.join(" "),u=spawnSync("/bin/sh",["-c",d],{stdio:"inherit",cwd:a,env:l});u.error&&console.log(chalk.red(`[FAIL] Execution error: ${u.error.message}`))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const sandboxCmd=require("./sandbox");module.exports={name:"freeze",description:"Freeze a running sandbox (Kills process, 0 RAM, keeps files)",aliases:["stop-sb"],requiresAuth:!1,execute:async(e,s)=>sandboxCmd.execute(["freeze",...e],s)};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),OCIExporter=require("../../core/sandbox/oci-exporter");module.exports={name:"push",aliases:["image-push","export"],description:"Push OCI images to AWS ECR, GCP Artifact Registry, Docker Hub, GHCR",usage:"thinknsh push <target> [options]",examples:["thinknsh push ecr://my-app:latest","thinknsh push gcr://my-project/my-app:v1.0","thinknsh push ghcr://username/my-app:latest","thinknsh push docker.io/username/my-app:latest","thinknsh push --export postgres:16","thinknsh push --export redis:alpine ./redis-oci.tar"],async execute(e=[],o){const s={},r=[];for(let o=0;o<e.length;o++){const t=e[o];if(t.startsWith("--")){const r=t.slice(2);if(r.includes("=")){const[e,o]=r.split("=");s[e]=o}else e[o+1]&&!e[o+1].startsWith("-")?s[r]=e[++o]:s[r]=!0}else if(t.startsWith("-")){const r=t.slice(1);e[o+1]&&!e[o+1].startsWith("-")?s[r]=e[++o]:s[r]=!0}else r.push(t)}return this.run(r,s,o)},async run(e,o={},s){const r=new OCIExporter;if(o.export||o["export-tar"]||"export"===e[0]){const s=!0===o.export?e[0]:o.export||e[1]||e[0],t=o.output||o.o||e[e.length>1?e.length-1:1];if(!s||"export"===s)return void console.log(chalk.red("Usage: thinknsh push --export <image>:<tag> [output.tar]"));try{const e=await r.exportTar(s,t||void 0);e.success&&(console.log(""),console.log(chalk.bold("Import commands:")),console.log(chalk.dim(` docker: docker load -i ${e.file}`)),console.log(chalk.dim(` containerd: ctr images import ${e.file}`)),console.log(chalk.dim(` skopeo: skopeo copy oci-archive:${e.file} docker://registry/repo:tag`)),console.log(chalk.dim(` crane: crane push ${e.file} registry/repo:tag`)))}catch(e){console.log(chalk.red(`[Error] ${e.message}`)),process.exit(1)}return}const t=e[0];if(!t)return console.log(chalk.yellow("Usage: thinknsh push <target>")),console.log(chalk.dim("\nSupported targets:")),console.log(chalk.dim(" ecr://<repo>:<tag> → AWS ECR")),console.log(chalk.dim(" gar://<location>-docker.pkg.dev/..→ Google Artifact Registry")),console.log(chalk.dim(" ghcr://<user>/<app>:<tag> → GitHub Container Registry")),console.log(chalk.dim(" docker.io/<user>/<app>:<tag> → Docker Hub")),console.log(chalk.dim("\nExport only:")),void console.log(chalk.dim(" thinknsh push --export myapp:v1 → OCI tar file"));let a=o.image||o.src,c=t;if(e.length>=2&&!o.image)a=e[0],c=e[1];else if(!a){const{ref:e}=r.parsePushTarget(t);a=e}const l=r.parsePushTarget(c);try{let e;switch(l.type){case"ecr":e=await r.pushToECR(a,l.ref);break;case"gcr":e=await r.pushToGCR(a,l.ref);break;case"ghcr":e=await r.pushToGHCR(a,l.ref,{username:o.username||process.env.GITHUB_ACTOR,password:o.token||process.env.GITHUB_TOKEN});break;case"dockerhub":e=await r.pushToDockerHub(a,l.ref,{username:o.username||process.env.DOCKER_USERNAME,password:o.password||process.env.DOCKER_PASSWORD});break;default:e=await r._pushViaSkopeo(a,l.ref,{username:o.username,password:o.password||o.token})}e.success?console.log(chalk.green(`\n[OK] Pushed: ${e.pushed}`)):e.manual&&(console.log(chalk.yellow("\n[Manual push required] OCI tar exported to:")),console.log(chalk.dim(` ${e.tarFile}`)))}catch(e){console.log(chalk.red(`\n[Error] Push failed: ${e.message}`)),e.message.includes("aws")?console.log(chalk.dim(" Setup: aws configure")):e.message.includes("gcloud")&&console.log(chalk.dim(" Setup: gcloud auth login && gcloud auth configure-docker")),process.exit(1)}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const sandboxCmd=require("./sandbox");module.exports={name:"resume",description:"Resume a frozen sandbox without reinstalling dependencies",aliases:["wake-sb"],requiresAuth:!1,execute:async(e,s)=>sandboxCmd.execute(["resume",...e],s)};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3"),path=require("path"),fs=require("fs-extra"),{SandboxEngine}=require("../../core/sandbox"),SandboxTunnel=require("../../core/sandbox/tunnel"),CgroupsV2=require("../../core/sandbox/cgroups"),engine=new SandboxEngine,cgroups=new CgroupsV2;function syncToDashboard(e,o,n){if(n?.ws?.isConnected())try{n.ws.emitSandboxSync(e,o)}catch(e){}return new Promise(s=>{let a=!1;const l=()=>{a||(a=!0,s())},t=(n?.ws?.config?.serverUrl||n?.api?.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com").replace(/\/$/,""),r=n?.ws?.getCurrentRoom?.()||n?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID||e?.roomId||null,c=n?.api?.getUser?.()?._id||n?.api?.getUser?.()?.id||n?.api?.userId||n?.ws?.userId||n?.config?.user?._id||n?.config?.userId||process.env.THINKNCOLLAB_USER_ID||e?.userId||null,i=n?.config?.roomName||e?.roomName||null,d=n?.api?.getUser?.()?.name||n?.config?.user?.name||n?.config?.userName||n?.config?.username||e?.userName||process.env.THINKNCOLLAB_USER_NAME||null,m={event:o,sandbox:{...e,roomId:r||e?.roomId||null,roomName:i||e?.roomName||null,userId:c||e?.userId||null,userName:d||e?.userName||null},roomId:r||e?.roomId||null,roomName:i||e?.roomName||null,userId:c||e?.userId||null,userName:d||e?.userName||null,timestamp:(new Date).toISOString()};try{const e=require("socket.io-client")(t+"/thinknsh",{transports:["websocket","polling"],timeout:1200,reconnection:!1});e.on("connect",()=>{e.emit("sandbox:sync",m),setTimeout(()=>{e.disconnect(),l()},60)}),e.on("connect_error",()=>{e.disconnect(),l()})}catch(e){l()}try{const e=t.startsWith("https"),o=e?require("https"):require("http"),n=new URL(t),s=JSON.stringify(m),a=o.request({hostname:n.hostname,port:n.port||(e?443:80),path:"/thinknsh/api/sandboxes/sync",method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(s)},timeout:1e3},()=>l());a.on("error",()=>l()),a.on("timeout",()=>{a.destroy(),l()}),a.write(s),a.end()}catch(e){l()}setTimeout(l,1500)})}module.exports={name:"sandbox",description:"Manage isolated lightweight sandboxes (Start, Freeze, Resume, Destroy)",aliases:["sb"],requiresAuth:!1,async execute(e,o){const n=(e[0]||"help").toLowerCase();switch(n){case"up":case"dev":{const n=require("./dev");return await n.execute(e.slice(1),o)}case"start":{const n=e[1]||`app-${Date.now().toString().slice(-4)}`;let s="node server.js",a=null,l=null,t=null;const r=new Set(["-p","--port","--memory","--mem","--ephemeral","--node","--node-version"]);for(let o=2;o<e.length;o++)if("--cmd"===e[o]){const n=[];for(o++;o<e.length&&!r.has(e[o]);)n.push(e[o]),o++;o--,n.length>0&&(s=n.join(" "))}else if("-p"!==e[o]&&"--port"!==e[o]||!e[o+1])"--node"!==e[o]&&"--node-version"!==e[o]||!e[o+1]||(t=e[++o]);else{const n=e[++o].split(":");a=parseInt(n[0],10),l=n[1]?parseInt(n[1],10):a}console.log(chalk.cyan(`\n[Start] Starting TNC Sandbox [${n}]...`)),console.log(chalk.dim(` Command : ${s}`)),a&&console.log(chalk.dim(` Port : Host:${a} -> Container:${l}`)),t&&console.log(chalk.dim(` Node : ${t}`));const c=o?.ws?.getCurrentRoom?.()||o?.config?.roomId||process.env.THINKNCOLLAB_ROOM_ID||null,i=o?.api?.getUser?.()?._id||o?.api?.getUser?.()?.id||o?.api?.userId||o?.ws?.userId||o?.config?.user?._id||o?.config?.userId||process.env.THINKNCOLLAB_USER_ID||null,d=o?.config?.roomName||null,m=o?.api?.getUser?.()?.name||o?.config?.user?.name||o?.config?.userName||o?.config?.username||process.env.THINKNCOLLAB_USER_NAME||null,g=await engine.start(n,{cmd:s,cwd:process.cwd(),hostPort:a,containerPort:l,nodeVersion:t,roomId:c,roomName:d,userId:i,userName:m});if(g.success){const e={"linux-unshare":chalk.green("linux-unshare (kernel)"),"macos-seatbelt":chalk.magenta("macos-seatbelt (syscall)"),"wsl2-kernel":chalk.blue("wsl2-kernel (linux)"),"host-process":chalk.gray("host-process (basic)")}[g.meta.isolationLevel]||chalk.gray(g.meta.isolationLevel);console.log(chalk.green(`\n[OK] ${g.message}`)),console.log(chalk.dim(` PID : ${g.meta.pid}`)),console.log(chalk.dim(` State : ${chalk.green(g.meta.state)}`)),console.log(` Isolation : ${e}`),g.meta.runtime&&g.meta.runtime.node&&console.log(chalk.dim(` Node.js : v${g.meta.runtime.node}${g.meta.runtime.isHermetic?" (hermetic runtime)":" (host)"}`)),g.meta.roomId&&console.log(` Room : ${g.meta.roomName||g.meta.roomId}`),g.meta.memoryLimitMB&&console.log(chalk.dim(` Mem Limit : ${g.meta.memoryLimitMB} MB`)),console.log(chalk.dim(` To freeze later: thinknsh sandbox freeze ${n}\n`)),await syncToDashboard(g.meta,"started",o),(new SandboxTunnel).connect(n,a||g.meta.hostPort,o)}else console.log(chalk.yellow(`\n[Notice] ${g.message}\n`));break}case"freeze":case"stop":{const n=e[1];if(!n)return void console.log(chalk.red("[Error] Usage: thinknsh sandbox freeze <sandbox-id>"));console.log(chalk.cyan(`\n[Freeze] Freezing Sandbox [${n}]...`));const s=await engine.freeze(n);s.success?(console.log(chalk.green(`[OK] ${s.message}`)),console.log(chalk.dim(" RAM released to 0 MB. All project files and node_modules preserved!")),console.log(chalk.dim(` To wake up: thinknsh sandbox resume ${n}\n`)),await syncToDashboard(s.meta,"frozen",o)):console.log(chalk.red(`[Error] ${s.message}\n`));break}case"resume":case"unfreeze":{const n=e[1];if(!n)return void console.log(chalk.red("[Error] Usage: thinknsh sandbox resume <sandbox-id>"));console.log(chalk.cyan(`\n[Resume] Resuming Sandbox [${n}]...`));const s=await engine.resume(n);s.success?(console.log(chalk.green(`[OK] ${s.message}`)),console.log(chalk.dim(` PID: ${s.meta.pid} | State: ${chalk.green(s.meta.state)}\n`)),await syncToDashboard(s.meta,"resumed",o)):console.log(chalk.red(`[Error] ${s.message}\n`));break}case"ps":case"list":case"ls":{const e=engine.list();if(0===e.length)return console.log(chalk.yellow("\nNo active or frozen sandboxes found.")),void console.log(chalk.dim('Start one with: thinknsh sandbox start <name> --cmd "<command>"\n'));const o=new Table({head:[chalk.cyan("ID"),chalk.cyan("ROOM"),chalk.cyan("STATE"),chalk.cyan("PID"),chalk.cyan("PORTS"),chalk.cyan("ISOLATION"),chalk.cyan("COMMAND"),chalk.cyan("STARTED")]}),n={"linux-unshare":chalk.green("unshare"),"macos-seatbelt":chalk.magenta("seatbelt"),"wsl2-kernel":chalk.blue("wsl2"),"host-process":chalk.gray("host"),"macos-microvm-vz":chalk.cyan("microvm-vz"),"linux-microvm-vz":chalk.cyan("microvm-vz"),"linux-crun-oci":chalk.green("crun-oci")};for(const s of e){const e="RUNNING"===s.state?chalk.green(s.state):"FROZEN"===s.state?chalk.blue(s.state):chalk.gray(s.state),a=s.hostPort?`${s.hostPort}:${s.containerPort||s.hostPort}`:"-",l=n[s.isolationLevel]||chalk.gray(s.isolationLevel||"?"),t=s.roomName||(s.roomId?`Room ${s.roomId.slice(-6)}`:"-");o.push([chalk.bold(s.id),t,e,s.pid||chalk.dim("frozen"),a,l,s.cmd||"-",s.startedAt?new Date(s.startedAt).toLocaleTimeString():"-"])}console.log(chalk.cyan("\nTNC Sandboxes:")),console.log(o.toString()),console.log("");break}case"logs":{const o=e[1];if(!o)return void console.log(chalk.red("[Error] Usage: thinknsh sandbox logs <sandbox-id>"));const n=path.join(engine.baseDir,o,"output.log");if(fs.existsSync(n)){const e=fs.readFileSync(n,"utf8");console.log(chalk.dim(`\n--- Logs for ${o} (last 50 lines) ---`)),console.log(e.split("\n").slice(-50).join("\n"))}else console.log(chalk.yellow(`No log file found for sandbox "${o}".`));break}case"destroy":case"rm":case"prune":{const s=e[1];if("--all"===s||"-a"===s||"prune"===n){const e=engine.list();if(0===e.length)return void console.log(chalk.yellow("\nNo active or frozen sandboxes to destroy.\n"));console.log(chalk.yellow(`\n[Destroy] Destroying all ${e.length} sandboxes...`));for(const n of e)await engine.destroy(n.id),await syncToDashboard({id:n.id,state:"DESTROYED"},"destroyed",o),console.log(chalk.green(`[OK] Destroyed "${n.id}"`));return void console.log(chalk.green("\n[OK] All sandboxes cleaned up successfully.\n"))}if(!s)return void console.log(chalk.red("[Error] Usage: thinknsh sandbox destroy <sandbox-id> (or --all)"));console.log(chalk.yellow(`\n[Destroy] Destroying Sandbox [${s}]...`));const a=await engine.destroy(s);console.log(chalk.green(`[OK] ${a.message}\n`)),await syncToDashboard({id:s,state:"DESTROYED"},"destroyed",o);break}case"stats":case"top":{const o=e[1];if(!o)return void console.log(chalk.red("[Error] Usage: thinknsh sandbox stats <sandbox-id>"));const n=engine.loadMeta(o);if(!n)return void console.log(chalk.red(`[Error] Sandbox "${o}" not found.`));if(console.log(chalk.cyan(`\nStats: ${chalk.bold(o)}`)),console.log(chalk.dim("─────────────────────────────────")),n.pid){const e=(new(require("../../core/sandbox/macos-sandbox"))).getMemoryUsage(n.pid);console.log(` PID : ${chalk.yellow(n.pid)}`),console.log(` RAM (RSS) : ${chalk.yellow(e+" MB")} (live)`)}else console.log(` State : ${chalk.blue("FROZEN")} — RAM = 0 MB`);if("linux"===process.platform&&cgroups.isAvailable()){const e=cgroups.getStats(o);e&&(console.log(` cgroup RAM : ${chalk.green(e.memoryMB+" MB")} / ${e.memoryLimitMB?e.memoryLimitMB+" MB":"unlimited"}`),console.log(` CPU time : ${chalk.green(e.cpuUsageMs+" ms")}`),console.log(` PIDs alive : ${chalk.green(e.pids)} / ${e.pidsLimit||"∞"}`),e.oomKills>0?console.log(` OOM kills : ${chalk.red("[Notice] "+e.oomKills)}`):console.log(` OOM kills : ${chalk.dim("0 (healthy)")}`))}else"linux"!==process.platform&&console.log(chalk.dim(` cgroups v2 : Linux only (you're on ${process.platform})`));console.log(` Isolation : ${chalk.magenta(n.isolationLevel||"?")}`),n.roomId&&console.log(` Room : ${n.roomName||n.roomId}`),console.log(` Started : ${n.startedAt?new Date(n.startedAt).toLocaleString():"-"}`),n.frozenAt&&console.log(` Frozen at : ${chalk.blue(new Date(n.frozenAt).toLocaleString())}`),console.log("");break}case"exec":{const n=require("./exec");return await n.execute(e.slice(1),o)}default:console.log(chalk.cyan("\nThinkNCollab Sandbox Manager")),console.log(chalk.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(` ${chalk.green('thinknsh sandbox start <id> [--cmd "..."] [-p host:cont]')}`),console.log(` ${chalk.green("thinknsh sandbox freeze <id>")}`),console.log(` ${chalk.green("thinknsh sandbox resume <id>")}`),console.log(` ${chalk.green("thinknsh sandbox ps")}`),console.log(` ${chalk.green("thinknsh sandbox stats <id>")} ${chalk.dim("<- live memory/CPU/PID stats")}`),console.log(` ${chalk.green("thinknsh sandbox logs <id>")}`),console.log(` ${chalk.green("thinknsh sandbox destroy <id>")}\n`)}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),{SandboxEngine}=require("../../core/sandbox"),engine=new SandboxEngine;module.exports={name:"tunnel",description:"Generate instant encrypted room preview URL & WebSocket tunnel for teammates",aliases:["preview"],requiresAuth:!1,async execute(e,n){const o=engine.list(),t=e[0]||(o.length>0?o[0].id:null);if(!t)return console.log(chalk.red("\n[Error] No active sandboxes found to share.")),void console.log(chalk.dim(" Run: thinknsh dev first to start a sandbox.\n"));const r=o.find(e=>e.id===t);if(!r)return void console.log(chalk.red(`\n[Error] Sandbox "${t}" not found.`));if("RUNNING"!==r.state)return void console.log(chalk.yellow(`\n[Warning] Sandbox "${t}" is currently ${r.state}. Resume it first: thinknsh sandbox resume ${t}`));const s=r.hostPort||3e3,a=Math.random().toString(36).substring(2,10),l=(n?.ws?.config?.serverUrl||n?.api?.apiUrl||process.env.THINKNCOLLAB_SERVER||"https://thinkncollab.com").replace(/\/$/,""),i=`${l}/thinknsh/preview/${encodeURIComponent(t)}?token=${a}`,c=`${l}/thinknsh/proxy/${encodeURIComponent(t)}/?token=${a}`;if(console.log(chalk.cyan(`\n[Tunnel] Generating Collaborative Live Tunnel for [${chalk.bold(t)}]...`)),console.log(chalk.green("\n[OK] Live Tunnel Active!")),console.log(` Sandbox ID : ${chalk.bold(t)}`),console.log(` Proxy Stream : ${chalk.cyan(c)}`),console.log(` Team Preview : ${chalk.bold.underline(i)}`),console.log(" Room Members : Instant access enabled with live hot-reload sync"),console.log(chalk.dim("\n Share this URL with your teammates to inspect your app in real time!\n")),n?.ws?.isConnected())try{n.ws.socket.emit("sandbox:share-created",{sandboxId:t,previewUrl:i,hostPort:s})}catch(e){}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),Table=require("cli-table3"),SnapshotManager=require("../../core/sandbox/snapshot-manager");module.exports={name:"snapshot",aliases:["snap"],description:"Instant volume snapshots with CoW clones (APFS / btrfs / reflink)",usage:"thinknsh snapshot <subcommand> [options]",examples:["thinknsh snapshot create myapp-v1","thinknsh snapshot create myapp-v1 ./data","thinknsh snapshot list","thinknsh snapshot restore myapp-v1-abc123","thinknsh snapshot diff snap1-id snap2-id","thinknsh snapshot delete snap1-id","thinknsh snapshot prune --keep 5","thinknsh snapshot info"],async execute(e=[],s){const o={},n=[];for(let s=0;s<e.length;s++){const a=e[s];if(a.startsWith("--")){const n=a.slice(2);if(n.includes("=")){const[e,s]=n.split("=");o[e]=s}else e[s+1]&&!e[s+1].startsWith("-")?o[n]=e[++s]:o[n]=!0}else if(a.startsWith("-")){const n=a.slice(1);e[s+1]&&!e[s+1].startsWith("-")?o[n]=e[++s]:o[n]=!0}else n.push(a)}return this.run(n,o,s)},async run(e,s={},o){const n=new SnapshotManager,a=e[0]||"list";switch(a){case"create":case"take":case"new":{const o=e[1];if(!o)return void console.log(chalk.red("Usage: thinknsh snapshot create <name> [path]"));const a=e[2]||process.cwd(),t=s.container||s.c||null;try{let e;if(t){const{SandboxEngine:l}=require("../../core/sandbox"),c=new l;e=await n.snapshotSafe(a,o,c,t,{description:s.desc||s.description||"",tags:s.tag?{tag:s.tag}:{}})}else e=await n.snapshot(a,o,{description:s.desc||s.description||"",tags:s.tag?{tag:s.tag}:{}});console.log(chalk.dim(`\n Snapshot ID: ${e.id}`)),console.log(chalk.dim(` Strategy: ${e.strategy} (${e.isCoW?"Copy-on-Write ✓":"full copy"})`)),console.log(chalk.dim(` Created in: ${e.elapsedMs}ms`))}catch(e){console.log(chalk.red(`[Error] ${e.message}`))}break}case"list":case"ls":{const e=n.list({name:s.name||s.filter});if(0===e.length)return console.log(chalk.yellow("\nNo snapshots found.")),void console.log(chalk.dim(" Try: thinknsh snapshot create mysnap"));const o=new Table({head:[chalk.cyan("ID"),chalk.cyan("Name"),chalk.cyan("Strategy"),chalk.cyan("CoW"),chalk.cyan("Size"),chalk.cyan("Created")],style:{head:[],border:[]}});for(const s of e)o.push([s.id.slice(-12),s.name,s.strategy,s.isCoW?chalk.green("✓"):chalk.dim("✗"),`${s.sizeMB}MB`,new Date(s.createdAt).toLocaleDateString()]);console.log(chalk.bold(`\nSnapshots (${e.length}):`)),console.log(o.toString());break}case"restore":{const o=e[1];if(!o)return void console.log(chalk.red("Usage: thinknsh snapshot restore <id> [target-path]"));const a=n.list().find(e=>e.id===o||e.id.endsWith(o)||e.name===o);if(!a)return void console.log(chalk.red(`Snapshot "${o}" not found.`));try{const o=await n.restore(a.id,e[2],{backup:s.backup});console.log(chalk.green(`[OK] Restored to: ${o.target}`))}catch(e){console.log(chalk.red(`[Error] ${e.message}`))}break}case"diff":{const s=e[1],o=e[2];if(!s||!o)return void console.log(chalk.red("Usage: thinknsh snapshot diff <id1> <id2>"));try{const e=n.diff(s,o);e.error||e.note?console.log(chalk.yellow(`[Diff] ${e.error||e.note}`)):(console.log(chalk.bold(`\nDiff: ${e.snapshot1} → ${e.snapshot2}`)),console.log(chalk.dim(` Changed files: ${e.changedFiles}`)),e.details?.length&&(console.log(chalk.dim("\n Changes:")),e.details.forEach(e=>console.log(chalk.dim(` ${e}`)))))}catch(e){console.log(chalk.red(`[Error] ${e.message}`))}break}case"delete":case"rm":case"remove":{const s=e[1];if(!s)return void console.log(chalk.red("Usage: thinknsh snapshot delete <id>"));const o=n.list().find(e=>e.id===s||e.id.endsWith(s)||e.name===s),a=o?o.id:s;try{n.delete(a),console.log(chalk.green(`[OK] Snapshot deleted: ${a}`))}catch(e){console.log(chalk.red(`[Error] ${e.message}`))}break}case"prune":{const o=parseInt(s.keep||e[1]||"3",10),a=n.prune(o);console.log(chalk.green(`[OK] Pruned ${a.pruned} old snapshots (keeping last ${o} per name)`));break}case"inspect":{const s=e[1],o=n.inspect(s);if(!o)return void console.log(chalk.red(`Snapshot "${s}" not found.`));console.log(JSON.stringify(o,null,2));break}case"info":case"status":case"system":{const e=n.systemInfo();console.log(chalk.bold("\nSnapshot System Info:")),console.log(chalk.dim(` Platform: ${e.platform}`)),console.log(chalk.dim(` Filesystem: ${e.fsType}`)),console.log(chalk.dim(` Strategy: ${e.strategy}`)),console.log(chalk.dim(` Copy-on-Write: ${e.isCoW?chalk.green("YES (instant, zero-disk)"):chalk.yellow("No (full copy)")}`)),console.log(chalk.dim(` Snapshot store: ${e.snapshotBase}`)),console.log(chalk.dim(` Total snapshots: ${e.totalSnapshots}`));break}default:console.log(chalk.yellow(`Unknown subcommand: ${a}`)),console.log(chalk.dim("Subcommands: create, list, restore, diff, delete, prune, info"))}}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const chalk=require("chalk"),fs=require("fs-extra"),path=require("path"),{execSync}=require("child_process"),DependencyTracker=require("../../core/dependency-tracker");let getDepStore;try{getDepStore=require("../../core/dep-store").getDepStore}catch(e){getDepStore=null}module.exports={name:"sync-deps",description:"Sync and auto-install all missing project dependencies recorded in thinkncollab.yml across C++, Python, Node, Rust, Go",aliases:["install-deps","bootstrap"],requiresAuth:!1,async execute(e,n){const o=process.cwd(),c=new DependencyTracker(o),l=await c.scanAndRecord(n)||c.loadConfig();console.log(chalk.cyan("\n Multi-Language Dependency Sync (thinkncollab.yml)")),console.log(` Project : ${chalk.bold(l.project)}`),console.log(` Runtimes: ${chalk.green((l.runtime?.runtimes||[l.runtime?.primary||"node"]).join(", "))}\n`);const t=l.dependencies?.npm||[],s=l.dependencies?.python||[],r=l.dependencies?.cpp||[],i=l.dependencies?.rust||[],a=l.dependencies?.go||[],d=l.dependencies?.system||[];if(t.length>0){console.log(chalk.yellow(` [Node.js] Syncing ${t.length} NPM packages...`));try{execSync("npm install",{stdio:"inherit",cwd:o}),console.log(chalk.green("[OK] Node.js dependencies synchronized."))}catch(e){console.log(chalk.red(`[FAIL] NPM install error: ${e.message}`))}}if(s.length>0){console.log(chalk.yellow(`\n [Python] Syncing ${s.length} Python packages...`));try{const e="win32"===process.platform?"pip":"pip3",n="darwin"===process.platform||"linux"===process.platform?"--break-system-packages":"";execSync(`${e} install ${n} ${s.join(" ")}`,{stdio:"inherit",cwd:o}),console.log(chalk.green("[OK] Python dependencies synchronized."))}catch(e){console.log(chalk.yellow(`ℹ️ Note: Python install notice: ${e.message.split("\n")[0]}`))}}if(r.length>0)if(console.log(chalk.yellow(`\n [C / C++] Checking ${r.length} C++ packages & headers (${r.join(", ")})...`)),fs.existsSync(path.join(o,"CMakeLists.txt")))try{console.log(chalk.dim(" Configuring CMake build directory...")),execSync("cmake -B build 2>/dev/null || true",{stdio:"inherit",cwd:o}),console.log(chalk.green("[OK] CMake build directory configured."))}catch(e){}else console.log(chalk.green(`[OK] C++ packages (${r.join(", ")}) registered in blueprint.`));if(i.length>0){console.log(chalk.yellow(`\n [Rust] Syncing ${i.length} Crates...`));try{execSync("cargo fetch 2>/dev/null || true",{stdio:"inherit",cwd:o}),console.log(chalk.green("[OK] Rust crates synchronized."))}catch(e){}}if(a.length>0){console.log(chalk.yellow(`\n [Go] Syncing ${a.length} Go Modules...`));try{execSync("go mod download 2>/dev/null || true",{stdio:"inherit",cwd:o}),console.log(chalk.green("[OK] Go modules synchronized."))}catch(e){}}if(d.length>0&&console.log(chalk.yellow(`\n [System] Registered system libraries: ${d.join(", ")}`)),getDepStore)try{getDepStore().recordFromConfig(l,{sandboxId:n?.activeSandbox?.id||null}),console.log(chalk.green("[OK] Dependency records updated in SQLite store (~/.tnc/deps.db)"))}catch(e){}console.log(chalk.green("\n[OK] All multi-language dependencies are synchronized with room blueprint!\n"))}};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license ThinkNCollab Enterprise & Open Core Ecosystem
3
+ * Copyright (c) 2024-2026 ThinkNCollab Systems Inc. All rights reserved.
4
+ * PROPRIETARY INTELLECTUAL PROPERTY & TRADE SECRETS.
5
+ * UNAUTHORIZED REVERSE ENGINEERING, DECOMPILATION, OR RE-DISTRIBUTION IS STRICTLY PROHIBITED.
6
+ */
7
+ const os=require("os"),fs=require("fs-extra"),path=require("path"),{spawnSync}=require("child_process"),chalk=require("chalk"),Table=require("cli-table3");module.exports={name:"doctor",aliases:["health","check-system"],description:"Run comprehensive system diagnostic check (cgroups, CoW, runtimes, memory)",usage:"thinknsh doctor",examples:["thinknsh doctor"],async execute(e=[],s){console.log(chalk.bold.cyan("\n🔍 Running ThinkNCollab System Diagnostics...\n"));const t=[],o=process.platform,a=process.arch;t.push({category:"System Platform",item:"OS & Architecture",status:chalk.green("✓ PASS"),details:`${o} / ${a} (${os.release()})`});const i=(new(require("../../core/sandbox/snapshot-manager"))).systemInfo(),n=i.isCoW;t.push({category:"Filesystem Storage",item:`CoW Support (${i.fsType.toUpperCase()})`,status:n?chalk.green("✓ PASS"):chalk.yellow("⚠ FALLBACK"),details:n?`CoW Active via ${i.strategy} (instant, 0-disk)`:`Standard copy fallback active on ${i.fsType}`});const c=this._cmdExists("crun"),r=(this._cmdExists("runc"),this._cmdExists("skopeo")),l=this._cmdExists("zstd");t.push({category:"OCI Runtime",item:"crun (Fast C-based OCI runtime)",status:c?chalk.green("✓ INSTALLED"):chalk.dim("○ OPTIONAL"),details:c?"Available for native Linux execution":"crun not found (uses native process sandboxing)"}),t.push({category:"OCI Tools",item:"skopeo & zstd support",status:r||l?chalk.green("✓ READY"):chalk.yellow("○ PARTIAL"),details:`skopeo: ${r?"yes":"no"}, zstd: ${l?"yes":"no"}`});const h=(os.totalmem()/1024/1024/1024).toFixed(1),d=(os.freemem()/1024/1024/1024).toFixed(1),u=parseFloat(d)<.5;t.push({category:"Host Resources",item:"Memory Headroom",status:u?chalk.red("✗ LOW RAM"):chalk.green("✓ PASS"),details:`${d} GB free of ${h} GB total`});const{dockPaths:m}=require("../../dock/paths"),{ping:p}=require("../../dock/client"),y=await p(m().socket),k=fs.existsSync(path.join(os.homedir(),".tnc","dock","runtime.json"));t.push({category:"Container Engine",item:"dock runtime",status:k?chalk.green("✓ INSTALLED"):chalk.yellow("○ MISSING"),details:k?"Linux runtime for this machine is installed":'Run "thinknsh dock setup"'}),t.push({category:"Container Engine",item:"dock daemon",status:y?chalk.green("✓ RUNNING"):chalk.dim("○ STOPPED"),details:y?m().socket:"Starts automatically on the first container command"});const g=(new(require("../../core/sandbox/policy-engine"))).getPolicy();t.push({category:"Security Policy",item:"Enterprise Policy Engine",status:g.enabled?chalk.green("✓ ENFORCING"):chalk.dim("○ DISABLED (Permissive)"),details:g.enabled?`Allowed Registries: ${g.allowedRegistries.join(", ")}`:"Permissive mode (all public registries allowed)"});const S=new Table({head:[chalk.cyan("Category"),chalk.cyan("Diagnostic Check"),chalk.cyan("Status"),chalk.cyan("Details")],style:{head:[],border:[]}});for(const e of t)S.push([e.category,e.item,e.status,e.details]);console.log(S.toString()),console.log(chalk.bold.green("\n[OK] ThinkNCollab is healthy and operational.\n"))},_cmdExists(e){try{return 0===spawnSync("which",[e],{stdio:"pipe"}).status}catch{return!1}}};