@lamplitisles/dsh-nanocodex 0.1.0-beta.0

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 (276) hide show
  1. package/LICENSE +65 -0
  2. package/NOTICE +2 -0
  3. package/README.md +182 -0
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/cordis.patch.yml +52 -0
  6. package/dist/index.d.ts +435 -0
  7. package/dist/index.js +3405 -0
  8. package/dist/standard-preset.d.ts +7 -0
  9. package/dist/standard-preset.js +25 -0
  10. package/engine-release.json +14 -0
  11. package/package.json +119 -0
  12. package/presets/standard/agent.cordis.yml +6 -0
  13. package/presets/standard/preset.yml +2 -0
  14. package/vendor/nanocodex/README.md +1344 -0
  15. package/vendor/nanocodex/actions/events.d.mts +10 -0
  16. package/vendor/nanocodex/actions/events.mjs +163 -0
  17. package/vendor/nanocodex/actions/index.d.mts +13 -0
  18. package/vendor/nanocodex/actions/index.mjs +35 -0
  19. package/vendor/nanocodex/actions/session.d.mts +66 -0
  20. package/vendor/nanocodex/actions/session.mjs +59 -0
  21. package/vendor/nanocodex/actions/turn.d.mts +59 -0
  22. package/vendor/nanocodex/actions/turn.mjs +37 -0
  23. package/vendor/nanocodex/actions/voice.d.mts +22 -0
  24. package/vendor/nanocodex/actions/voice.mjs +50 -0
  25. package/vendor/nanocodex/browser/Agent.d.mts +55 -0
  26. package/vendor/nanocodex/browser/Agent.mjs +11 -0
  27. package/vendor/nanocodex/browser/ChatGptSubscription.d.mts +7 -0
  28. package/vendor/nanocodex/browser/ChatGptSubscription.mjs +19 -0
  29. package/vendor/nanocodex/browser/InlineAgent.mjs +266 -0
  30. package/vendor/nanocodex/browser/Transport.d.mts +74 -0
  31. package/vendor/nanocodex/browser/Transport.mjs +61 -0
  32. package/vendor/nanocodex/browser/Voice.d.mts +71 -0
  33. package/vendor/nanocodex/browser/Voice.mjs +291 -0
  34. package/vendor/nanocodex/browser/VoiceSession.mjs +688 -0
  35. package/vendor/nanocodex/browser/WorkerAgent.d.mts +65 -0
  36. package/vendor/nanocodex/browser/WorkerAgent.mjs +1472 -0
  37. package/vendor/nanocodex/browser/agent.worker.mjs +3 -0
  38. package/vendor/nanocodex/browser/config.d.mts +36 -0
  39. package/vendor/nanocodex/browser/config.mjs +439 -0
  40. package/vendor/nanocodex/browser/engine.mjs +13 -0
  41. package/vendor/nanocodex/browser/harness.mjs +55 -0
  42. package/vendor/nanocodex/browser/host.d.mts +83 -0
  43. package/vendor/nanocodex/browser/host.mjs +555 -0
  44. package/vendor/nanocodex/browser/hostManagedWebSocket.d.mts +14 -0
  45. package/vendor/nanocodex/browser/hostManagedWebSocket.mjs +110 -0
  46. package/vendor/nanocodex/browser/index.d.mts +92 -0
  47. package/vendor/nanocodex/browser/index.mjs +23 -0
  48. package/vendor/nanocodex/browser/indexeddb-durability-store.mjs +197 -0
  49. package/vendor/nanocodex/browser/workspace.d.mts +16 -0
  50. package/vendor/nanocodex/browser/workspace.mjs +107 -0
  51. package/vendor/nanocodex/cloud/Client.d.mts +83 -0
  52. package/vendor/nanocodex/cloud/Client.mjs +231 -0
  53. package/vendor/nanocodex/cloud/Decorator.d.mts +31 -0
  54. package/vendor/nanocodex/cloud/Decorator.mjs +37 -0
  55. package/vendor/nanocodex/cloud/Dialog.d.mts +113 -0
  56. package/vendor/nanocodex/cloud/Dialog.mjs +366 -0
  57. package/vendor/nanocodex/cloud/Errors.d.mts +22 -0
  58. package/vendor/nanocodex/cloud/Errors.mjs +39 -0
  59. package/vendor/nanocodex/cloud/Principal.d.mts +26 -0
  60. package/vendor/nanocodex/cloud/Principal.mjs +88 -0
  61. package/vendor/nanocodex/cloud/RemoteProvider.mjs +88 -0
  62. package/vendor/nanocodex/cloud/Transport.d.mts +47 -0
  63. package/vendor/nanocodex/cloud/Transport.mjs +454 -0
  64. package/vendor/nanocodex/cloud/actions/account.d.mts +9 -0
  65. package/vendor/nanocodex/cloud/actions/account.mjs +19 -0
  66. package/vendor/nanocodex/cloud/actions/agent.d.mts +18 -0
  67. package/vendor/nanocodex/cloud/actions/agent.mjs +428 -0
  68. package/vendor/nanocodex/cloud/actions/connection.d.mts +133 -0
  69. package/vendor/nanocodex/cloud/actions/connection.mjs +580 -0
  70. package/vendor/nanocodex/cloud/actions/grant.d.mts +10 -0
  71. package/vendor/nanocodex/cloud/actions/grant.mjs +12 -0
  72. package/vendor/nanocodex/cloud/actions/index.d.mts +7 -0
  73. package/vendor/nanocodex/cloud/actions/index.mjs +7 -0
  74. package/vendor/nanocodex/cloud/actions/machineUsd.d.mts +23 -0
  75. package/vendor/nanocodex/cloud/actions/machineUsd.mjs +37 -0
  76. package/vendor/nanocodex/cloud/actions/model.d.mts +12 -0
  77. package/vendor/nanocodex/cloud/actions/model.mjs +50 -0
  78. package/vendor/nanocodex/cloud/actions/mpp.d.mts +28 -0
  79. package/vendor/nanocodex/cloud/actions/mpp.mjs +39 -0
  80. package/vendor/nanocodex/cloud/index.d.mts +30 -0
  81. package/vendor/nanocodex/cloud/index.mjs +9 -0
  82. package/vendor/nanocodex/cloud/internal.mjs +533 -0
  83. package/vendor/nanocodex/cloud/mercator.mjs +108 -0
  84. package/vendor/nanocodex/cloud/server/HostPrincipal.d.mts +34 -0
  85. package/vendor/nanocodex/cloud/server/HostPrincipal.mjs +202 -0
  86. package/vendor/nanocodex/cloud/server/index.d.mts +1 -0
  87. package/vendor/nanocodex/cloud/server/index.mjs +1 -0
  88. package/vendor/nanocodex/cloud/types.d.mts +211 -0
  89. package/vendor/nanocodex/cloudflare/Agent.d.mts +133 -0
  90. package/vendor/nanocodex/cloudflare/Agent.mjs +811 -0
  91. package/vendor/nanocodex/cloudflare/egress-subject.mjs +19 -0
  92. package/vendor/nanocodex/cloudflare/egress.d.mts +41 -0
  93. package/vendor/nanocodex/cloudflare/egress.mjs +119 -0
  94. package/vendor/nanocodex/cloudflare/event-socket.mjs +316 -0
  95. package/vendor/nanocodex/cloudflare/index.d.mts +7 -0
  96. package/vendor/nanocodex/cloudflare/index.mjs +6 -0
  97. package/vendor/nanocodex/host/Agent.d.mts +55 -0
  98. package/vendor/nanocodex/host/Agent.mjs +1 -0
  99. package/vendor/nanocodex/host/index.d.mts +82 -0
  100. package/vendor/nanocodex/host/index.mjs +10 -0
  101. package/vendor/nanocodex/index.d.mts +81 -0
  102. package/vendor/nanocodex/index.mjs +12 -0
  103. package/vendor/nanocodex/internal.mjs +1275 -0
  104. package/vendor/nanocodex/managed/Agent.d.mts +380 -0
  105. package/vendor/nanocodex/managed/Agent.mjs +1694 -0
  106. package/vendor/nanocodex/managed/ManagedError.d.mts +9 -0
  107. package/vendor/nanocodex/managed/ManagedError.mjs +8 -0
  108. package/vendor/nanocodex/managed/README.md +241 -0
  109. package/vendor/nanocodex/managed/Voice.mjs +202 -0
  110. package/vendor/nanocodex/managed/index.d.mts +20 -0
  111. package/vendor/nanocodex/managed/index.mjs +2 -0
  112. package/vendor/nanocodex/managed/internal.mjs +119 -0
  113. package/vendor/nanocodex/node/Agent.d.mts +50 -0
  114. package/vendor/nanocodex/node/Agent.mjs +203 -0
  115. package/vendor/nanocodex/node/ChatGptSubscription.d.mts +9 -0
  116. package/vendor/nanocodex/node/ChatGptSubscription.mjs +17 -0
  117. package/vendor/nanocodex/node/Transport.d.mts +44 -0
  118. package/vendor/nanocodex/node/Transport.mjs +46 -0
  119. package/vendor/nanocodex/node/host.mjs +731 -0
  120. package/vendor/nanocodex/node/index.d.mts +73 -0
  121. package/vendor/nanocodex/node/index.mjs +17 -0
  122. package/vendor/nanocodex/node/workspace.d.mts +10 -0
  123. package/vendor/nanocodex/node/workspace.mjs +198 -0
  124. package/vendor/nanocodex/package.json +200 -0
  125. package/vendor/nanocodex/pkg-node/nanocodex.d.ts +675 -0
  126. package/vendor/nanocodex/pkg-node/nanocodex.js +2628 -0
  127. package/vendor/nanocodex/pkg-node/nanocodex_bg.wasm.d.ts +105 -0
  128. package/vendor/nanocodex/pkg-node/package.json +1 -0
  129. package/vendor/nanocodex/pkg-web/.nanocodex-bindgen-stamp +6 -0
  130. package/vendor/nanocodex/pkg-web/nanocodex-build.json +1 -0
  131. package/vendor/nanocodex/pkg-web/nanocodex.d.ts +805 -0
  132. package/vendor/nanocodex/pkg-web/nanocodex.js +2714 -0
  133. package/vendor/nanocodex/pkg-web/nanocodex_bg.js +2615 -0
  134. package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm +0 -0
  135. package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm.d.ts +105 -0
  136. package/vendor/nanocodex/pkg-web/nanocodex_worker.js +9 -0
  137. package/vendor/nanocodex/pkg-web/package.json +1 -0
  138. package/vendor/nanocodex/runtime/chatgpt-subscription.mjs +212 -0
  139. package/vendor/nanocodex/runtime/cloudflare-durability-store.d.mts +26 -0
  140. package/vendor/nanocodex/runtime/cloudflare-durability-store.mjs +168 -0
  141. package/vendor/nanocodex/runtime/code-evaluator.worker.mjs +137 -0
  142. package/vendor/nanocodex/runtime/code-runtime.mjs +1 -0
  143. package/vendor/nanocodex/runtime/durability-store.d.mts +85 -0
  144. package/vendor/nanocodex/runtime/durability-store.mjs +631 -0
  145. package/vendor/nanocodex/runtime/durability.mjs +153 -0
  146. package/vendor/nanocodex/runtime/managed-transport.mjs +460 -0
  147. package/vendor/nanocodex/runtime/mcp-runtime.mjs +534 -0
  148. package/vendor/nanocodex/runtime/postgres-durability-store.d.mts +64 -0
  149. package/vendor/nanocodex/runtime/postgres-durability-store.mjs +532 -0
  150. package/vendor/nanocodex/runtime/quickjs-evaluator.d.mts +17 -0
  151. package/vendor/nanocodex/runtime/quickjs-evaluator.mjs +236 -0
  152. package/vendor/nanocodex/runtime/responses-transport.mjs +22 -0
  153. package/vendor/nanocodex/runtime/subagents.d.mts +107 -0
  154. package/vendor/nanocodex/runtime/subagents.mjs +54 -0
  155. package/vendor/nanocodex/runtime/subscription-store.d.mts +8 -0
  156. package/vendor/nanocodex/runtime/subscription-store.mjs +42 -0
  157. package/vendor/nanocodex/runtime/tempo-provider.d.mts +125 -0
  158. package/vendor/nanocodex/runtime/tempo-provider.mjs +264 -0
  159. package/vendor/nanocodex/runtime/tool-configuration.mjs +1 -0
  160. package/vendor/nanocodex/runtime/tool-router.mjs +1 -0
  161. package/vendor/nanocodex/runtime/utf8.mjs +1 -0
  162. package/vendor/nanocodex/runtime/worker-evaluator.mjs +162 -0
  163. package/vendor/nanocodex/runtime/workspace.d.mts +1 -0
  164. package/vendor/nanocodex/runtime/workspace.mjs +1 -0
  165. package/vendor/nanocodex/tools/Tools.d.mts +56 -0
  166. package/vendor/nanocodex/tools/Tools.mjs +136 -0
  167. package/vendor/nanocodex/tools/artifact.d.mts +1 -0
  168. package/vendor/nanocodex/tools/artifact.mjs +1 -0
  169. package/vendor/nanocodex/tools/attachment.mjs +1 -0
  170. package/vendor/nanocodex/tools/bash.d.mts +1 -0
  171. package/vendor/nanocodex/tools/bash.mjs +1 -0
  172. package/vendor/nanocodex/tools/browser/accountInfo.mjs +795 -0
  173. package/vendor/nanocodex/tools/browser/browserBuffer.mjs +18 -0
  174. package/vendor/nanocodex/tools/browser/browserCompiler.mjs +155 -0
  175. package/vendor/nanocodex/tools/browser/browserEgress.mjs +161 -0
  176. package/vendor/nanocodex/tools/browser/browserPython.mjs +133 -0
  177. package/vendor/nanocodex/tools/browser/browserShell.mjs +1075 -0
  178. package/vendor/nanocodex/tools/browser/browserSprintf.mjs +4 -0
  179. package/vendor/nanocodex/tools/browser/browserSsh.mjs +201 -0
  180. package/vendor/nanocodex/tools/browser/browserZlib.mjs +136 -0
  181. package/vendor/nanocodex/tools/browser/compiler.worker.mjs +160 -0
  182. package/vendor/nanocodex/tools/browser/devTunnelsSshBrowser.mjs +13 -0
  183. package/vendor/nanocodex/tools/browser/index.d.mts +209 -0
  184. package/vendor/nanocodex/tools/browser/index.mjs +174 -0
  185. package/vendor/nanocodex/tools/browser/opfsGit.mjs +248 -0
  186. package/vendor/nanocodex/tools/browser/python.worker.mjs +114 -0
  187. package/vendor/nanocodex/tools/browser/threadGit.mjs +197 -0
  188. package/vendor/nanocodex/tools/browser/unsupportedNodeRsa.mjs +5 -0
  189. package/vendor/nanocodex/tools/browser/workspace.mjs +83 -0
  190. package/vendor/nanocodex/tools/dataset.d.mts +1 -0
  191. package/vendor/nanocodex/tools/dataset.mjs +1 -0
  192. package/vendor/nanocodex/tools/datasetContract.mjs +1 -0
  193. package/vendor/nanocodex/tools/datasetEngine.mjs +1 -0
  194. package/vendor/nanocodex/tools/hostedCatalog.d.mts +1 -0
  195. package/vendor/nanocodex/tools/hostedCatalog.mjs +1 -0
  196. package/vendor/nanocodex/tools/index.d.mts +49 -0
  197. package/vendor/nanocodex/tools/index.mjs +19 -0
  198. package/vendor/nanocodex/tools/namedTool.mjs +1 -0
  199. package/vendor/nanocodex/tools/repository-workspace.d.mts +1 -0
  200. package/vendor/nanocodex/tools/repository-workspace.mjs +1 -0
  201. package/vendor/nanocodex/tools/ssh.d.mts +1 -0
  202. package/vendor/nanocodex/tools/ssh.mjs +1 -0
  203. package/vendor/nanocodex/tools/standard.mjs +1 -0
  204. package/vendor/nanocodex/tools/standardDescriptions.mjs +1 -0
  205. package/vendor/nanocodex/types.d.mts +663 -0
  206. package/vendor/nanocodex/wasm.d.mts +4 -0
  207. package/vendor/nanocodex/worker/ChatGptSubscription.d.mts +9 -0
  208. package/vendor/nanocodex/worker/ChatGptSubscription.mjs +29 -0
  209. package/vendor/nanocodex/worker/index.d.mts +18 -0
  210. package/vendor/nanocodex/worker/index.mjs +5 -0
  211. package/vendor/nanocodex-tools/README.md +65 -0
  212. package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.d.ts +7 -0
  213. package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.js +14 -0
  214. package/vendor/nanocodex-tools/dist/hosted/broker-core.d.ts +172 -0
  215. package/vendor/nanocodex-tools/dist/hosted/broker-core.js +1278 -0
  216. package/vendor/nanocodex-tools/dist/hosted/index.d.ts +3 -0
  217. package/vendor/nanocodex-tools/dist/hosted/index.js +3 -0
  218. package/vendor/nanocodex-tools/dist/hosted/protocol.d.ts +120 -0
  219. package/vendor/nanocodex-tools/dist/hosted/protocol.js +415 -0
  220. package/vendor/nanocodex-tools/dist/index.d.ts +19 -0
  221. package/vendor/nanocodex-tools/dist/index.js +14 -0
  222. package/vendor/nanocodex-tools/dist/memory.d.ts +204 -0
  223. package/vendor/nanocodex-tools/dist/memory.js +411 -0
  224. package/vendor/nanocodex-tools/dist/namespace.d.ts +87 -0
  225. package/vendor/nanocodex-tools/dist/namespace.js +338 -0
  226. package/vendor/nanocodex-tools/dist/repository-archive.d.ts +4 -0
  227. package/vendor/nanocodex-tools/dist/repository-archive.js +104 -0
  228. package/vendor/nanocodex-tools/dist/runtime.d.ts +30 -0
  229. package/vendor/nanocodex-tools/dist/runtime.js +37 -0
  230. package/vendor/nanocodex-tools/dist/session.d.ts +167 -0
  231. package/vendor/nanocodex-tools/dist/session.js +286 -0
  232. package/vendor/nanocodex-tools/dist/shell.d.ts +51 -0
  233. package/vendor/nanocodex-tools/dist/shell.js +553 -0
  234. package/vendor/nanocodex-tools/dist/ssh.d.ts +29 -0
  235. package/vendor/nanocodex-tools/dist/ssh.js +66 -0
  236. package/vendor/nanocodex-tools/dist/workspace.d.ts +45 -0
  237. package/vendor/nanocodex-tools/dist/workspace.js +237 -0
  238. package/vendor/nanocodex-tools/package.json +122 -0
  239. package/vendor/nanocodex-tools/runtime/code-runtime.mjs +817 -0
  240. package/vendor/nanocodex-tools/runtime/tool-configuration.mjs +50 -0
  241. package/vendor/nanocodex-tools/runtime/tool-router.mjs +730 -0
  242. package/vendor/nanocodex-tools/runtime/utf8.d.mts +2 -0
  243. package/vendor/nanocodex-tools/runtime/utf8.mjs +25 -0
  244. package/vendor/nanocodex-tools/tools/artifact.d.mts +69 -0
  245. package/vendor/nanocodex-tools/tools/artifact.mjs +270 -0
  246. package/vendor/nanocodex-tools/tools/attachment.mjs +603 -0
  247. package/vendor/nanocodex-tools/tools/bash.d.mts +90 -0
  248. package/vendor/nanocodex-tools/tools/bash.mjs +742 -0
  249. package/vendor/nanocodex-tools/tools/dataset.d.mts +9 -0
  250. package/vendor/nanocodex-tools/tools/dataset.mjs +47 -0
  251. package/vendor/nanocodex-tools/tools/datasetContract.mjs +54 -0
  252. package/vendor/nanocodex-tools/tools/datasetEngine.mjs +1167 -0
  253. package/vendor/nanocodex-tools/tools/execution-contract.d.mts +5 -0
  254. package/vendor/nanocodex-tools/tools/execution-contract.mjs +63 -0
  255. package/vendor/nanocodex-tools/tools/hostedCatalog.d.mts +20 -0
  256. package/vendor/nanocodex-tools/tools/hostedCatalog.mjs +67 -0
  257. package/vendor/nanocodex-tools/tools/hostedMachine.d.mts +10 -0
  258. package/vendor/nanocodex-tools/tools/hostedMachine.mjs +56 -0
  259. package/vendor/nanocodex-tools/tools/just-bash-browser.d.mts +1 -0
  260. package/vendor/nanocodex-tools/tools/just-bash-browser.mjs +1 -0
  261. package/vendor/nanocodex-tools/tools/namedTool.d.mts +3 -0
  262. package/vendor/nanocodex-tools/tools/namedTool.mjs +3 -0
  263. package/vendor/nanocodex-tools/tools/nodeProcess.d.mts +10 -0
  264. package/vendor/nanocodex-tools/tools/nodeProcess.mjs +314 -0
  265. package/vendor/nanocodex-tools/tools/processOutput.mjs +56 -0
  266. package/vendor/nanocodex-tools/tools/repository-workspace.d.mts +55 -0
  267. package/vendor/nanocodex-tools/tools/repository-workspace.mjs +397 -0
  268. package/vendor/nanocodex-tools/tools/ssh.d.mts +56 -0
  269. package/vendor/nanocodex-tools/tools/ssh.mjs +503 -0
  270. package/vendor/nanocodex-tools/tools/standard.mjs +458 -0
  271. package/vendor/nanocodex-tools/tools/standardDescriptions.mjs +3 -0
  272. package/vendor/nanocodex-tools/tools/types.d.mts +83 -0
  273. package/vendor/nanocodex-tools/tools/workspace.d.mts +25 -0
  274. package/vendor/nanocodex-tools/tools/workspace.mjs +282 -0
  275. package/vendor/nanocodex-tools/tools/x.d.mts +30 -0
  276. package/vendor/nanocodex-tools/tools/x.mjs +91 -0
@@ -0,0 +1,4 @@
1
+ import sprintfJs from "sprintf-js";
2
+
3
+ export const { sprintf, vsprintf } = sprintfJs;
4
+ export default sprintfJs;
@@ -0,0 +1,201 @@
1
+ import { Buffer } from "./browserBuffer.mjs";
2
+ import { CancellationTokenSource, CommandRequestMessage, SshAuthenticationType, SshClientSession, SshSessionConfiguration, WebSocketStream, } from "./devTunnelsSshBrowser.mjs";
3
+ import { importKey } from "@microsoft/dev-tunnels-ssh-keys";
4
+ import { defineCommand } from "../../../nanocodex-tools/tools/just-bash-browser.mjs";
5
+ export function createSshCommand(filesystem) {
6
+ return defineCommand("ssh", async (args, context) => {
7
+ if (args[0] === "--help")
8
+ return ok(`${usage()}\n`);
9
+ const parsed = parseArguments(args);
10
+ if ("error" in parsed)
11
+ return fail(`${parsed.error}\n`, 2);
12
+ if (String(context.stdin)) {
13
+ return fail("ssh: piped stdin is not supported by the browser WebSocket transport\n", 2);
14
+ }
15
+ try {
16
+ return await executeSsh(parsed, filesystem, context);
17
+ }
18
+ catch (error) {
19
+ return fail(`ssh: ${error instanceof Error ? error.message : String(error)}\n`, 255);
20
+ }
21
+ });
22
+ }
23
+ async function executeSsh(args, filesystem, context) {
24
+ const keyPath = filesystem.resolvePath(context.cwd, args.identityFile);
25
+ const keySource = await filesystem.readFile(keyPath);
26
+ const privateKey = await importKey(keySource);
27
+ const websocket = new WebSocket(args.endpoint);
28
+ websocket.binaryType = "arraybuffer";
29
+ const cancellation = new CancellationTokenSource();
30
+ const abort = () => {
31
+ cancellation.cancel();
32
+ websocket.close(1000, "command cancelled");
33
+ };
34
+ context.signal?.addEventListener("abort", abort, { once: true });
35
+ const session = new SshClientSession(new SshSessionConfiguration());
36
+ const authentication = session.onAuthenticating((event) => {
37
+ if (event.authenticationType !== SshAuthenticationType.serverPublicKey || !event.publicKey) {
38
+ event.authenticationPromise = Promise.resolve(null);
39
+ return;
40
+ }
41
+ event.authenticationPromise = authenticateHost(event.publicKey, args.hostKeySha256, args.acceptUnknownHost);
42
+ });
43
+ try {
44
+ await waitForWebSocket(websocket, context.signal);
45
+ await session.connect(new WebSocketStream(websocket), cancellation.token);
46
+ const authenticated = await session.authenticate({
47
+ username: args.username,
48
+ publicKeys: [privateKey],
49
+ }, cancellation.token);
50
+ if (!authenticated)
51
+ throw new Error("authentication failed");
52
+ const channel = await session.openChannel("session", cancellation.token);
53
+ let stdout = "";
54
+ let stderr = "";
55
+ channel.onDataReceived((data) => {
56
+ stdout += data.toString("utf8");
57
+ channel.adjustWindow(data.length);
58
+ });
59
+ channel.onExtendedDataReceived((event) => {
60
+ stderr += event.data.toString("utf8");
61
+ channel.adjustWindow(event.data.length);
62
+ });
63
+ const closed = new Promise((resolve) => channel.onClosed(resolve));
64
+ const request = new CommandRequestMessage();
65
+ request.command = args.command;
66
+ request.wantReply = true;
67
+ if (!await channel.request(request, cancellation.token)) {
68
+ throw new Error("remote server rejected the command");
69
+ }
70
+ const result = await closed;
71
+ if (result.error)
72
+ throw result.error;
73
+ if (result.exitSignal)
74
+ stderr += `ssh: remote command exited on ${result.exitSignal}\n`;
75
+ return { stdout, stderr, exitCode: result.exitStatus ?? (result.exitSignal ? 128 : 0) };
76
+ }
77
+ finally {
78
+ context.signal?.removeEventListener("abort", abort);
79
+ authentication.dispose();
80
+ privateKey.dispose();
81
+ session.dispose();
82
+ cancellation.dispose();
83
+ if (websocket.readyState === WebSocket.OPEN)
84
+ websocket.close(1000, "command complete");
85
+ }
86
+ }
87
+ async function authenticateHost(publicKey, expected, acceptUnknown) {
88
+ if (acceptUnknown)
89
+ return {};
90
+ const bytes = await publicKey.getPublicKeyBytes();
91
+ if (!bytes || !expected)
92
+ return null;
93
+ const keyBytes = new Uint8Array(bytes.byteLength);
94
+ keyBytes.set(bytes);
95
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", keyBytes));
96
+ let binary = "";
97
+ for (const byte of digest)
98
+ binary += String.fromCharCode(byte);
99
+ const actual = btoa(binary).replace(/=+$/, "");
100
+ const normalized = expected.replace(/^SHA256:/, "").replace(/=+$/, "");
101
+ return actual === normalized ? {} : null;
102
+ }
103
+ function parseArguments(args) {
104
+ if (!args.length)
105
+ return { error: usage() };
106
+ let username = "";
107
+ let identityFile = "";
108
+ let hostKeySha256;
109
+ let acceptUnknownHost = false;
110
+ let index = 0;
111
+ for (; index < args.length; index += 1) {
112
+ const arg = args[index];
113
+ if (arg === "--") {
114
+ index += 1;
115
+ break;
116
+ }
117
+ if (!arg.startsWith("-"))
118
+ break;
119
+ if (arg === "-l" || arg === "-i" || arg === "-o") {
120
+ const value = args[++index];
121
+ if (!value)
122
+ return { error: `ssh: ${arg} requires an argument` };
123
+ if (arg === "-l")
124
+ username = value;
125
+ else if (arg === "-i")
126
+ identityFile = value;
127
+ else if (value === "StrictHostKeyChecking=no")
128
+ acceptUnknownHost = true;
129
+ else if (value.startsWith("HostKeySHA256="))
130
+ hostKeySha256 = value.slice("HostKeySHA256=".length);
131
+ else
132
+ return { error: `ssh: unsupported browser option '${value}'` };
133
+ continue;
134
+ }
135
+ return { error: `ssh: unsupported browser option '${arg}'` };
136
+ }
137
+ const endpointText = args[index++];
138
+ if (!endpointText)
139
+ return { error: usage() };
140
+ let endpoint;
141
+ try {
142
+ endpoint = new URL(endpointText);
143
+ }
144
+ catch {
145
+ return { error: "ssh: endpoint must be a ws:// or wss:// URL" };
146
+ }
147
+ if (!["ws:", "wss:"].includes(endpoint.protocol) || endpoint.username || endpoint.password) {
148
+ return { error: "ssh: endpoint must be a credential-free ws:// or wss:// URL" };
149
+ }
150
+ if (!username)
151
+ return { error: "ssh: -l USER is required" };
152
+ if (!identityFile)
153
+ return { error: "ssh: -i PRIVATE_KEY is required" };
154
+ if (!hostKeySha256 && !acceptUnknownHost) {
155
+ return { error: "ssh: provide -o HostKeySHA256=SHA256:... or explicitly -o StrictHostKeyChecking=no" };
156
+ }
157
+ const commandArgs = args.slice(index);
158
+ if (!commandArgs.length)
159
+ return { error: "ssh: an explicit remote command is required (interactive PTYs are unavailable)" };
160
+ return {
161
+ endpoint,
162
+ username,
163
+ identityFile,
164
+ command: commandArgs.map(shellQuote).join(" "),
165
+ hostKeySha256,
166
+ acceptUnknownHost,
167
+ };
168
+ }
169
+ function shellQuote(value) {
170
+ return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
171
+ }
172
+ function waitForWebSocket(websocket, signal) {
173
+ return new Promise((resolve, reject) => {
174
+ const cleanup = () => {
175
+ websocket.removeEventListener("open", onOpen);
176
+ websocket.removeEventListener("error", onError);
177
+ signal?.removeEventListener("abort", onAbort);
178
+ };
179
+ const onOpen = () => { cleanup(); resolve(); };
180
+ const onError = () => { cleanup(); reject(new Error("WebSocket connection failed")); };
181
+ const onAbort = () => { cleanup(); reject(signal?.reason ?? new Error("command cancelled")); };
182
+ websocket.addEventListener("open", onOpen, { once: true });
183
+ websocket.addEventListener("error", onError, { once: true });
184
+ signal?.addEventListener("abort", onAbort, { once: true });
185
+ if (signal?.aborted)
186
+ onAbort();
187
+ });
188
+ }
189
+ function usage() {
190
+ return [
191
+ "usage: ssh -l USER -i PRIVATE_KEY (-o HostKeySHA256=SHA256:... |",
192
+ " -o StrictHostKeyChecking=no) wss://SSH-GATEWAY -- COMMAND [ARG...]",
193
+ "Browser SSH requires a server-provided WebSocket carrying raw SSH; browsers cannot open TCP port 22.",
194
+ ].join("\n");
195
+ }
196
+ function fail(stderr, exitCode) {
197
+ return { stdout: "", stderr, exitCode };
198
+ }
199
+ function ok(stdout) {
200
+ return { stdout, stderr: "", exitCode: 0 };
201
+ }
@@ -0,0 +1,136 @@
1
+ import { Buffer } from "./browserBuffer.mjs";
2
+ import { Deflate, Inflate, constants as pakoConstants } from "pako";
3
+
4
+ const DEFAULT_CHUNK_BYTES = 64 * 1024;
5
+
6
+ export const constants = Object.freeze({
7
+ Z_BEST_COMPRESSION: pakoConstants.Z_BEST_COMPRESSION,
8
+ Z_BEST_SPEED: pakoConstants.Z_BEST_SPEED,
9
+ Z_DEFAULT_COMPRESSION: pakoConstants.Z_DEFAULT_COMPRESSION,
10
+ });
11
+
12
+ export const {
13
+ Z_BEST_COMPRESSION,
14
+ Z_BEST_SPEED,
15
+ Z_DEFAULT_COMPRESSION,
16
+ } = constants;
17
+
18
+ export function gzipSync(input, options = undefined) {
19
+ const bytes = inputBytes(input);
20
+ const normalized = compressionOptions(options);
21
+ return transform(
22
+ new Deflate({ ...normalized.pako, gzip: true, chunkSize: normalized.chunkSize }),
23
+ bytes,
24
+ normalized.maxOutputLength,
25
+ );
26
+ }
27
+
28
+ export function gunzipSync(input, options = undefined) {
29
+ const bytes = inputBytes(input);
30
+ const normalized = compressionOptions(options);
31
+ return transform(
32
+ new Inflate({ ...normalized.pako, chunkSize: normalized.chunkSize }),
33
+ bytes,
34
+ normalized.maxOutputLength,
35
+ );
36
+ }
37
+
38
+ function transform(stream, input, maxOutputLength) {
39
+ const chunks = [];
40
+ let outputLength = 0;
41
+ stream.onData = (chunk) => {
42
+ const nextLength = outputLength + chunk.byteLength;
43
+ if (!Number.isSafeInteger(nextLength) || nextLength > maxOutputLength) {
44
+ throw bufferTooLarge(maxOutputLength);
45
+ }
46
+ chunks.push(chunk);
47
+ outputLength = nextLength;
48
+ };
49
+ stream.push(input, true);
50
+ if (stream.err) throw zlibError(stream.err, stream.msg);
51
+ if (chunks.length === 0) return Buffer.alloc(0);
52
+ if (chunks.length === 1) {
53
+ const [chunk] = chunks;
54
+ return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
55
+ }
56
+ return Buffer.concat(
57
+ chunks.map((chunk) => Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength)),
58
+ outputLength,
59
+ );
60
+ }
61
+
62
+ function compressionOptions(options) {
63
+ if (options !== undefined && (options === null || typeof options !== "object")) {
64
+ throw invalidOptions(options);
65
+ }
66
+ const { maxOutputLength, ...pako } = options ?? {};
67
+ const maximum = validateMaxOutputLength(maxOutputLength);
68
+ return {
69
+ maxOutputLength: maximum,
70
+ // pako emits incrementally at this boundary. For a very small caller limit,
71
+ // ask it to stop at the first byte beyond that limit instead of materializing
72
+ // the complete decompressed payload before the compatibility layer sees it.
73
+ chunkSize: Math.max(2, Math.min(DEFAULT_CHUNK_BYTES, Math.floor(maximum) + 1)),
74
+ pako,
75
+ };
76
+ }
77
+
78
+ function validateMaxOutputLength(value) {
79
+ if (value === undefined || Number.isNaN(value)) return Number.MAX_SAFE_INTEGER;
80
+ if (typeof value !== "number") {
81
+ const error = new TypeError(
82
+ `The "options.maxOutputLength" property must be of type number. Received type ${typeof value}`,
83
+ );
84
+ error.code = "ERR_INVALID_ARG_TYPE";
85
+ throw error;
86
+ }
87
+ if (!Number.isFinite(value) || value < 1 || value > Number.MAX_SAFE_INTEGER) {
88
+ const error = new RangeError(
89
+ `The value of "options.maxOutputLength" is out of range. It must be >= 1 and <= ${Number.MAX_SAFE_INTEGER}. Received ${value}`,
90
+ );
91
+ error.code = "ERR_OUT_OF_RANGE";
92
+ throw error;
93
+ }
94
+ return value;
95
+ }
96
+
97
+ function inputBytes(input) {
98
+ if (typeof input === "string") return new TextEncoder().encode(input);
99
+ if (ArrayBuffer.isView(input)) {
100
+ return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
101
+ }
102
+ if (input instanceof ArrayBuffer || isSharedArrayBuffer(input)) {
103
+ return new Uint8Array(input);
104
+ }
105
+ const received = input === null ? "null" : typeof input;
106
+ const error = new TypeError(
107
+ `The "buffer" argument must be of type string or an instance of Buffer, TypedArray, DataView, or ArrayBuffer. Received ${received}`,
108
+ );
109
+ error.code = "ERR_INVALID_ARG_TYPE";
110
+ throw error;
111
+ }
112
+
113
+ function isSharedArrayBuffer(input) {
114
+ return typeof SharedArrayBuffer !== "undefined" && input instanceof SharedArrayBuffer;
115
+ }
116
+
117
+ function invalidOptions(options) {
118
+ const error = new TypeError(
119
+ `The "options" argument must be of type object. Received ${options === null ? "null" : typeof options}`,
120
+ );
121
+ error.code = "ERR_INVALID_ARG_TYPE";
122
+ return error;
123
+ }
124
+
125
+ function bufferTooLarge(maximum) {
126
+ const error = new RangeError(`Cannot create a Buffer larger than ${maximum} bytes`);
127
+ error.code = "ERR_BUFFER_TOO_LARGE";
128
+ return error;
129
+ }
130
+
131
+ function zlibError(errno, message) {
132
+ const error = new Error(message || "zlib operation failed");
133
+ error.code = errno === pakoConstants.Z_DATA_ERROR ? "Z_DATA_ERROR" : "Z_BUF_ERROR";
134
+ error.errno = errno;
135
+ return error;
136
+ }
@@ -0,0 +1,160 @@
1
+ /// <reference lib="webworker" />
2
+ import { API } from "@eduoj/wasm-clang";
3
+ import { installBrowserEgressFetch } from "./browserEgress.mjs";
4
+ let apiPromise;
5
+ let workerFetch;
6
+ let diagnostics = "";
7
+ const knownDirectories = new WeakMap();
8
+ const workerScope = globalThis.self;
9
+ workerScope?.addEventListener("message", (event) => {
10
+ const message = event.data;
11
+ if (message.type === "initialize") {
12
+ workerFetch = installBrowserEgressFetch({
13
+ ...message.egress,
14
+ fetch: globalThis.fetch,
15
+ });
16
+ return;
17
+ }
18
+ if (message.type !== "compile" || typeof message.id !== "number")
19
+ return;
20
+ void compile(message.id, message.input);
21
+ });
22
+ async function compile(id, input) {
23
+ diagnostics = "";
24
+ try {
25
+ const api = await runtime();
26
+ await api.ready;
27
+ const bytes = await compileInput(api, id, input);
28
+ const result = {
29
+ stdout: "",
30
+ stderr: diagnostics,
31
+ exitCode: 0,
32
+ output: bytes,
33
+ };
34
+ workerScope.postMessage({ id, result }, [bytes.buffer]);
35
+ }
36
+ catch (error) {
37
+ workerScope.postMessage({
38
+ id,
39
+ result: {
40
+ stdout: "",
41
+ stderr: `${diagnostics}${error instanceof Error ? error.message : String(error)}\n`,
42
+ exitCode: 1,
43
+ },
44
+ });
45
+ }
46
+ }
47
+ export async function compileInput(api, id, input) {
48
+ const prefix = `.nanocodex-runs/run-${id}`;
49
+ try {
50
+ addDirectories(api, [`${prefix}/.keep`, ...input.files.map((file) => `${prefix}/${file.path}`)]);
51
+ for (const file of input.files)
52
+ api.memfs.addFile(`${prefix}/${file.path}`, file.contents);
53
+ addDirectories(api, [`${prefix}/objects/.keep`]);
54
+ const objects = [];
55
+ for (let index = 0; index < input.sources.length; index += 1) {
56
+ const relativeSource = workspaceRelative(input.sources[index]);
57
+ const file = input.files.find((candidate) => candidate.path === relativeSource);
58
+ if (!file)
59
+ throw new Error(`input file not found: ${relativeSource}`);
60
+ const source = `${prefix}/${relativeSource}`;
61
+ const object = `${prefix}/objects/${index}.o`;
62
+ await api.compile({
63
+ input: source,
64
+ contents: file.contents,
65
+ obj: object,
66
+ opt: input.optimize,
67
+ clangFlags: ["-triple", "wasm32-unknown-wasi"],
68
+ });
69
+ objects.push(object);
70
+ }
71
+ const generated = input.compileOnly
72
+ ? objects[0]
73
+ : await link(api, objects, prefix);
74
+ return api.memfs.getFileContents(generated).slice();
75
+ }
76
+ finally {
77
+ removeRun(api.memfs, prefix);
78
+ }
79
+ }
80
+ async function runtime() {
81
+ if (!apiPromise) {
82
+ if (!workerFetch)
83
+ throw new Error("compiler worker egress was not initialized");
84
+ apiPromise = Promise.resolve(new API({
85
+ hostWrite: (message) => diagnostics += message,
86
+ readBuffer: async (url) => {
87
+ const response = await workerFetch(url);
88
+ if (!response.ok)
89
+ throw new Error(`compiler asset failed: HTTP ${response.status}`);
90
+ return response.arrayBuffer();
91
+ },
92
+ compileStreaming: async (url) => {
93
+ const response = await workerFetch(url);
94
+ if (!response.ok)
95
+ throw new Error(`compiler asset failed: HTTP ${response.status}`);
96
+ return WebAssembly.compile(await response.arrayBuffer());
97
+ },
98
+ }));
99
+ }
100
+ return apiPromise;
101
+ }
102
+ async function link(api, objects, prefix) {
103
+ const output = `${prefix}/output.wasm`;
104
+ const libdir = "lib/wasm32-wasi";
105
+ const lld = await api.getModule(api.cdnUrl + api.lldFilename);
106
+ await api.run(lld, "wasm-ld", "--no-threads", "--export-dynamic", "-z", "stack-size=1048576", `-L${libdir}`, `${libdir}/crt1.o`, ...objects, "-lc", "-lc++", "-lc++abi", "-lcanvas", "-o", output);
107
+ return output;
108
+ }
109
+ function addDirectories(api, paths) {
110
+ const known = directoriesFor(api.memfs);
111
+ const directories = new Set();
112
+ for (const path of paths) {
113
+ const parts = path.split("/").slice(0, -1);
114
+ for (let index = 1; index <= parts.length; index += 1) {
115
+ directories.add(parts.slice(0, index).join("/"));
116
+ }
117
+ }
118
+ for (const directory of [...directories].sort()) {
119
+ if (known.has(directory))
120
+ continue;
121
+ api.memfs.addDirectory(directory);
122
+ known.add(directory);
123
+ }
124
+ }
125
+ function removeRun(memfs, prefix) {
126
+ try {
127
+ memfs.mem.check();
128
+ const pathBuffer = memfs.exports.GetPathBuf();
129
+ memfs.mem.write(pathBuffer, prefix);
130
+ const previousHostMemory = memfs.hostMem_;
131
+ memfs.hostMem = memfs.mem;
132
+ let errno;
133
+ try {
134
+ errno = memfs.exports.path_unlink_file(3, pathBuffer, prefix.length);
135
+ }
136
+ finally {
137
+ memfs.hostMem = previousHostMemory;
138
+ }
139
+ if (errno !== 0 && errno !== 44)
140
+ throw new Error(`compiler memfs cleanup failed with WASI errno ${errno}`);
141
+ }
142
+ finally {
143
+ const known = directoriesFor(memfs);
144
+ for (const directory of known) {
145
+ if (directory === prefix || directory.startsWith(`${prefix}/`))
146
+ known.delete(directory);
147
+ }
148
+ }
149
+ }
150
+ function directoriesFor(memfs) {
151
+ let directories = knownDirectories.get(memfs);
152
+ if (!directories) {
153
+ directories = new Set();
154
+ knownDirectories.set(memfs, directories);
155
+ }
156
+ return directories;
157
+ }
158
+ function workspaceRelative(path) {
159
+ return path.replace(/^\/workspace\//, "").replace(/^\/+/, "");
160
+ }
@@ -0,0 +1,13 @@
1
+ // Browser-only barrel for dev-tunnels-ssh. The upstream CommonJS root eagerly
2
+ // evaluates Node stream classes even though its crypto implementation correctly
3
+ // selects Web Crypto. Export only the browser-safe protocol surface we use.
4
+ export { SshAlgorithms, Encryption, ECDsa, Rsa, } from "@microsoft/dev-tunnels-ssh/algorithms/sshAlgorithms.js";
5
+ export { SshDataReader } from "@microsoft/dev-tunnels-ssh/io/sshData.js";
6
+ export { DerReader, DerWriter } from "@microsoft/dev-tunnels-ssh/io/derData.js";
7
+ export { BigInt } from "@microsoft/dev-tunnels-ssh/io/bigInt.js";
8
+ export { CancellationToken, CancellationTokenSource, } from "@microsoft/dev-tunnels-ssh/util/cancellation.js";
9
+ export { CommandRequestMessage } from "@microsoft/dev-tunnels-ssh/messages/connectionMessages.js";
10
+ export { SshAuthenticationType } from "@microsoft/dev-tunnels-ssh/events/sshAuthenticatingEventArgs.js";
11
+ export { SshClientSession } from "@microsoft/dev-tunnels-ssh/sshClientSession.js";
12
+ export { SshSessionConfiguration } from "@microsoft/dev-tunnels-ssh/sshSessionConfiguration.js";
13
+ export { WebSocketStream } from "@microsoft/dev-tunnels-ssh/streams.js";