ssh-mcp-pro 1.4.3 → 1.6.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 (125) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/MIGRATION.md +1 -1
  3. package/README.md +1 -1
  4. package/dist/agent-bin.js +2 -2
  5. package/dist/agent-bin.js.map +1 -1
  6. package/dist/mcp.d.ts +1 -1
  7. package/dist/mcp.js +1 -1
  8. package/dist/remote/action-record-sanitize.d.ts +4 -0
  9. package/dist/remote/action-record-sanitize.d.ts.map +1 -0
  10. package/dist/remote/action-record-sanitize.js +11 -0
  11. package/dist/remote/action-record-sanitize.js.map +1 -0
  12. package/dist/remote/agent-bounded-io.d.ts +30 -0
  13. package/dist/remote/agent-bounded-io.d.ts.map +1 -0
  14. package/dist/remote/agent-bounded-io.js +135 -0
  15. package/dist/remote/agent-bounded-io.js.map +1 -0
  16. package/dist/remote/agent-browser-enrollment.d.ts +16 -0
  17. package/dist/remote/agent-browser-enrollment.d.ts.map +1 -0
  18. package/dist/remote/agent-browser-enrollment.js +190 -0
  19. package/dist/remote/agent-browser-enrollment.js.map +1 -0
  20. package/dist/remote/agent-cli.d.ts +5 -0
  21. package/dist/remote/agent-cli.d.ts.map +1 -1
  22. package/dist/remote/agent-cli.js +91 -14
  23. package/dist/remote/agent-cli.js.map +1 -1
  24. package/dist/remote/agent-content-search.d.ts +20 -0
  25. package/dist/remote/agent-content-search.d.ts.map +1 -0
  26. package/dist/remote/agent-content-search.js +61 -0
  27. package/dist/remote/agent-content-search.js.map +1 -0
  28. package/dist/remote/agent-enrollment.d.ts +12 -0
  29. package/dist/remote/agent-enrollment.d.ts.map +1 -0
  30. package/dist/remote/agent-enrollment.js +87 -0
  31. package/dist/remote/agent-enrollment.js.map +1 -0
  32. package/dist/remote/agent-executor.d.ts +5 -0
  33. package/dist/remote/agent-executor.d.ts.map +1 -1
  34. package/dist/remote/agent-executor.js +96 -107
  35. package/dist/remote/agent-executor.js.map +1 -1
  36. package/dist/remote/agent-file-search.d.ts +22 -0
  37. package/dist/remote/agent-file-search.d.ts.map +1 -0
  38. package/dist/remote/agent-file-search.js +243 -0
  39. package/dist/remote/agent-file-search.js.map +1 -0
  40. package/dist/remote/agent-managed-process.d.ts +43 -0
  41. package/dist/remote/agent-managed-process.d.ts.map +1 -0
  42. package/dist/remote/agent-managed-process.js +291 -0
  43. package/dist/remote/agent-managed-process.js.map +1 -0
  44. package/dist/remote/control-plane.d.ts +3 -2
  45. package/dist/remote/control-plane.d.ts.map +1 -1
  46. package/dist/remote/control-plane.js +24 -80
  47. package/dist/remote/control-plane.js.map +1 -1
  48. package/dist/remote/dashboard-enrollment-commands.d.ts +8 -0
  49. package/dist/remote/dashboard-enrollment-commands.d.ts.map +1 -0
  50. package/dist/remote/dashboard-enrollment-commands.js +23 -0
  51. package/dist/remote/dashboard-enrollment-commands.js.map +1 -0
  52. package/dist/remote/dashboard-enrollment-feedback-script.d.ts +3 -0
  53. package/dist/remote/dashboard-enrollment-feedback-script.d.ts.map +1 -0
  54. package/dist/remote/dashboard-enrollment-feedback-script.js +227 -0
  55. package/dist/remote/dashboard-enrollment-feedback-script.js.map +1 -0
  56. package/dist/remote/mcp-tools.d.ts +1 -0
  57. package/dist/remote/mcp-tools.d.ts.map +1 -1
  58. package/dist/remote/mcp-tools.js +207 -3
  59. package/dist/remote/mcp-tools.js.map +1 -1
  60. package/dist/remote/oauth-handler.d.ts +5 -0
  61. package/dist/remote/oauth-handler.d.ts.map +1 -1
  62. package/dist/remote/oauth-handler.js +110 -65
  63. package/dist/remote/oauth-handler.js.map +1 -1
  64. package/dist/remote/oauth-provider-exchange.d.ts +11 -0
  65. package/dist/remote/oauth-provider-exchange.d.ts.map +1 -0
  66. package/dist/remote/oauth-provider-exchange.js +73 -0
  67. package/dist/remote/oauth-provider-exchange.js.map +1 -0
  68. package/dist/remote/safe-file.d.ts +19 -1
  69. package/dist/remote/safe-file.d.ts.map +1 -1
  70. package/dist/remote/safe-file.js +77 -3
  71. package/dist/remote/safe-file.js.map +1 -1
  72. package/dist/remote/schemas.d.ts +16 -0
  73. package/dist/remote/schemas.d.ts.map +1 -1
  74. package/dist/remote/schemas.js +1 -0
  75. package/dist/remote/schemas.js.map +1 -1
  76. package/dist/remote/store-schema.d.ts +4 -0
  77. package/dist/remote/store-schema.d.ts.map +1 -0
  78. package/dist/remote/store-schema.js +147 -0
  79. package/dist/remote/store-schema.js.map +1 -0
  80. package/dist/remote/store.d.ts +9 -5
  81. package/dist/remote/store.d.ts.map +1 -1
  82. package/dist/remote/store.js +96 -133
  83. package/dist/remote/store.js.map +1 -1
  84. package/dist/remote/types.d.ts +16 -2
  85. package/dist/remote/types.d.ts.map +1 -1
  86. package/dist/remote/types.js +15 -0
  87. package/dist/remote/types.js.map +1 -1
  88. package/dist/remote/web-dashboard-html.d.ts.map +1 -1
  89. package/dist/remote/web-dashboard-html.js +25 -27
  90. package/dist/remote/web-dashboard-html.js.map +1 -1
  91. package/dist/remote/web-dashboard-oauth-users.d.ts.map +1 -1
  92. package/dist/remote/web-dashboard-oauth-users.js +4 -38
  93. package/dist/remote/web-dashboard-oauth-users.js.map +1 -1
  94. package/dist/remote/web-dashboard-styles.d.ts +1 -1
  95. package/dist/remote/web-dashboard-styles.d.ts.map +1 -1
  96. package/dist/remote/web-dashboard-styles.js +2 -0
  97. package/dist/remote/web-dashboard-styles.js.map +1 -1
  98. package/dist/remote/web-dashboard.d.ts +0 -2
  99. package/dist/remote/web-dashboard.d.ts.map +1 -1
  100. package/dist/remote/web-dashboard.js +12 -20
  101. package/dist/remote/web-dashboard.js.map +1 -1
  102. package/dist/session-auth-config.d.ts +8 -0
  103. package/dist/session-auth-config.d.ts.map +1 -0
  104. package/dist/session-auth-config.js +67 -0
  105. package/dist/session-auth-config.js.map +1 -0
  106. package/dist/session.d.ts +0 -12
  107. package/dist/session.d.ts.map +1 -1
  108. package/dist/session.js +3 -64
  109. package/dist/session.js.map +1 -1
  110. package/dist/types.d.ts +1 -1
  111. package/docs/adding-a-device.md +187 -11
  112. package/docs/api-overview.md +67 -0
  113. package/docs/backup-restore-verification.md +45 -0
  114. package/docs/coolify.md +9 -0
  115. package/docs/development/local-setup.md +1 -1
  116. package/docs/reference/compatibility.md +1 -1
  117. package/docs/security/hosted-data-inventory.md +3 -1
  118. package/docs/theme/favicon.svg +12 -0
  119. package/docs/theme/ssh-docs.css +670 -0
  120. package/docs/theme/ssh-docs.js +58 -0
  121. package/docs/tutorials/getting-started.md +1 -1
  122. package/mcp.json +1 -1
  123. package/package.json +12 -12
  124. package/registry/ssh-mcp-pro/mcp.json +1 -1
  125. package/server.json +3 -3
package/CHANGELOG.md CHANGED
@@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.6.0](https://github.com/oaslananka/ssh-mcp-pro/compare/ssh-mcp-pro-v1.5.0...ssh-mcp-pro-v1.6.0) (2026-11-12)
9
+
10
+
11
+ ### Features
12
+
13
+ * **agent:** approve Linux enrollment in local browser ([#239](https://github.com/oaslananka/ssh-mcp-pro/issues/239)) ([7ba75d4](https://github.com/oaslananka/ssh-mcp-pro/commit/7ba75d42a19a07ae2de18a7872d2fa54eb0415b8))
14
+ * **agent:** install Node LTS on first Windows enrollment ([#219](https://github.com/oaslananka/ssh-mcp-pro/issues/219)) ([8d2f82f](https://github.com/oaslananka/ssh-mcp-pro/commit/8d2f82f8696751bcf469fd42245327d5ed4007e7))
15
+ * **dashboard:** confirm first device is Live Online during setup ([#227](https://github.com/oaslananka/ssh-mcp-pro/issues/227)) ([7447971](https://github.com/oaslananka/ssh-mcp-pro/commit/74479716133c8d34f7233d681d58d3881b3e5f47))
16
+ * **install:** verified Node LTS bootstrap for clean Linux and WSL ([#237](https://github.com/oaslananka/ssh-mcp-pro/issues/237)) ([600b6f3](https://github.com/oaslananka/ssh-mcp-pro/commit/600b6f3f67ffd522817719be70c7839cb864d59e))
17
+ * **recovery:** verify encrypted backup restore offline ([#233](https://github.com/oaslananka/ssh-mcp-pro/issues/233)) ([4187749](https://github.com/oaslananka/ssh-mcp-pro/commit/41877496c8233c1c02958fc1579ba96d0745fb7c))
18
+ * **remote:** discover allowlisted files by name ([#217](https://github.com/oaslananka/ssh-mcp-pro/issues/217)) ([0f04209](https://github.com/oaslananka/ssh-mcp-pro/commit/0f04209464fd83b2d34ca8713b244969c8aeba80))
19
+ * **remote:** manage interactive agent processes with bounded output ([#221](https://github.com/oaslananka/ssh-mcp-pro/issues/221)) ([1beaddb](https://github.com/oaslananka/ssh-mcp-pro/commit/1beaddb1ff96f3d2bcbeb407322b0a65aa87f218))
20
+ * **remote:** page bounded file reads with UTF-8 safe cursors ([#215](https://github.com/oaslananka/ssh-mcp-pro/issues/215)) ([cce420b](https://github.com/oaslananka/ssh-mcp-pro/commit/cce420bcda302289fc92638e778f42848218cad1))
21
+ * **remote:** preview and apply guarded file text replacements ([#220](https://github.com/oaslananka/ssh-mcp-pro/issues/220)) ([eb3a837](https://github.com/oaslananka/ssh-mcp-pro/commit/eb3a8374942c1fe939a71f1abf3ccd130e0d9d48))
22
+ * **remote:** search allowed file contents by literal phrase ([#223](https://github.com/oaslananka/ssh-mcp-pro/issues/223)) ([f82034d](https://github.com/oaslananka/ssh-mcp-pro/commit/f82034d1c2cbad1706effc398c8666b48f9c1df7))
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * **agent:** make Windows enrollment work with restricted PowerShell ([#218](https://github.com/oaslananka/ssh-mcp-pro/issues/218)) ([de97766](https://github.com/oaslananka/ssh-mcp-pro/commit/de977665266ea7437ad885134d37b2ccb2f69025))
28
+ * **agent:** reconnect safely after transient remote socket loss ([#230](https://github.com/oaslananka/ssh-mcp-pro/issues/230)) ([1f79e6e](https://github.com/oaslananka/ssh-mcp-pro/commit/1f79e6ec3a915eef66668c2dda90e7afe9be706b))
29
+ * **agent:** remove Windows scheduled task runtime cap ([#229](https://github.com/oaslananka/ssh-mcp-pro/issues/229)) ([e0956bf](https://github.com/oaslananka/ssh-mcp-pro/commit/e0956bf084b4133b278ee5d3aaf8b315f95d3b92))
30
+ * **agent:** report failure to persist Linux user service ([#224](https://github.com/oaslananka/ssh-mcp-pro/issues/224)) ([5976050](https://github.com/oaslananka/ssh-mcp-pro/commit/59760503acc5576c49bb7d48cea9220acff5f291))
31
+ * **agent:** report Linux status without uptime utility ([#231](https://github.com/oaslananka/ssh-mcp-pro/issues/231)) ([8868741](https://github.com/oaslananka/ssh-mcp-pro/commit/8868741439407a3dbe6d10cb57a3b06efdfd865e))
32
+ * **dashboard:** allow browser enrollment callback to loopback ([#242](https://github.com/oaslananka/ssh-mcp-pro/issues/242)) ([7ccf4d1](https://github.com/oaslananka/ssh-mcp-pro/commit/7ccf4d13485ca99aaff9142cf0a50f9fb656c8d1))
33
+ * **dashboard:** explain provider-scoped device inventory ([#234](https://github.com/oaslananka/ssh-mcp-pro/issues/234)) ([ac5a10c](https://github.com/oaslananka/ssh-mcp-pro/commit/ac5a10c10ee81aae54e8c1dfae03d61e66639d6a))
34
+ * **dashboard:** show tenant-scoped device names in audit history ([#232](https://github.com/oaslananka/ssh-mcp-pro/issues/232)) ([ef0b8eb](https://github.com/oaslananka/ssh-mcp-pro/commit/ef0b8eb9398216cc88b0deaa4c8de80e58f77665))
35
+ * **docker:** bundle installer scripts in standard runtime image ([#226](https://github.com/oaslananka/ssh-mcp-pro/issues/226)) ([ba6fffe](https://github.com/oaslananka/ssh-mcp-pro/commit/ba6fffe78877da2b7abaf2676663f15ebde36e7b))
36
+ * **install:** clarify WSL agent lifetime after setup ([#241](https://github.com/oaslananka/ssh-mcp-pro/issues/241)) ([e1215b1](https://github.com/oaslananka/ssh-mcp-pro/commit/e1215b19d5f4870ccaf99c938f12b5525f5ee2d0))
37
+ * **install:** explain missing system Node and npm ([#240](https://github.com/oaslananka/ssh-mcp-pro/issues/240)) ([249ee4c](https://github.com/oaslananka/ssh-mcp-pro/commit/249ee4c8f4327bfaa20e90acb09ee6c66f8208cb))
38
+ * **remote:** describe mutation risks and output schemas ([#213](https://github.com/oaslananka/ssh-mcp-pro/issues/213)) ([c7d18f4](https://github.com/oaslananka/ssh-mcp-pro/commit/c7d18f4bcb0f9c69537277db23ce971ad051f9ec))
39
+ * **remote:** expire abandoned pending agents ([#225](https://github.com/oaslananka/ssh-mcp-pro/issues/225)) ([43a730b](https://github.com/oaslananka/ssh-mcp-pro/commit/43a730b543ce8d8d67111dfe0391a39c57aacee4))
40
+ * **windows:** provide tokenless legacy agent task repair ([#235](https://github.com/oaslananka/ssh-mcp-pro/issues/235)) ([5a267e8](https://github.com/oaslananka/ssh-mcp-pro/commit/5a267e8cb60a4f25b3cb0fea2911439b8774d2c5))
41
+
42
+ ## [1.5.0](https://github.com/oaslananka/ssh-mcp-pro/compare/ssh-mcp-pro-v1.4.3...ssh-mcp-pro-v1.5.0) (2026-11-10)
43
+
44
+
45
+ ### Features
46
+
47
+ * **remote:** rotating OAuth refresh tokens for persistent MCP sessions ([8b1aad8](https://github.com/oaslananka/ssh-mcp-pro/commit/8b1aad8be7fcb779a5b409e31d034e941e100ce1))
48
+
8
49
  ## [1.4.3](https://github.com/oaslananka/ssh-mcp-pro/compare/ssh-mcp-pro-v1.4.2...ssh-mcp-pro-v1.4.3) (2026-11-10)
9
50
 
10
51
 
package/MIGRATION.md CHANGED
@@ -7,7 +7,7 @@ Version `1.0.0` is the initial public baseline for this repository. There are no
7
7
  When upgrading within `1.x`, preserve these compatibility expectations:
8
8
 
9
9
  - Node.js must satisfy `>=22.22.2` (Node 24 and 26 are tested in CI).
10
- - pnpm must satisfy `^11.28.10` for current development and build tooling.
10
+ - pnpm must satisfy `^11.28.11` for current development and build tooling.
11
11
  - Existing stdio MCP client configs can continue to launch `ssh-mcp-pro` with no arguments.
12
12
  - HTTP deployments should keep explicit authentication, allowed origins, host allowlists, strict host-key verification, and a remote-safe tool profile.
13
13
 
package/README.md CHANGED
@@ -38,7 +38,7 @@ ssh-mcp-pro is a secure Model Context Protocol (MCP) server for SSH automation.
38
38
  ## Prerequisites
39
39
 
40
40
  - Node.js `>=22.22.2` or `>=24.15.0` or `>=26.3.0`
41
- - pnpm `^11.28.10` (use Corepack for development)
41
+ - pnpm `^11.28.11` (use Corepack for development)
42
42
  - SSH access to the target hosts
43
43
  - Docker, only for local integration tests and container image builds
44
44
 
package/dist/agent-bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { runAgentCli } from "./remote/agent-cli.js";
2
+ import { runAgentCliWithReconnect } from "./remote/agent-cli.js";
3
3
  try {
4
- await runAgentCli(process.argv.slice(2));
4
+ await runAgentCliWithReconnect(process.argv.slice(2));
5
5
  }
6
6
  catch (error) {
7
7
  const message = error instanceof Error ? error.message : String(error);
@@ -1 +1 @@
1
- {"version":3,"file":"agent-bin.js","sourceRoot":"","sources":["../src/agent-bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,IAAI,CAAC;IACH,MAAM,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAAC,OAAO,KAAc,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"agent-bin.js","sourceRoot":"","sources":["../src/agent-bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,IAAI,CAAC;IACH,MAAM,wBAAwB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAAC,OAAO,KAAc,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
package/dist/mcp.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { McpServer } from "@modelcontextprotocol/server";
2
2
  import type { Transport } from "@modelcontextprotocol/server";
3
3
  import type { AppContainer } from "./container.js";
4
- export declare const SERVER_VERSION = "1.4.3";
4
+ export declare const SERVER_VERSION = "1.6.0";
5
5
  export declare const SERVER_NAME = "io.github.oaslananka/ssh-mcp-pro";
6
6
  export declare class SSHMCPServer {
7
7
  private readonly container;
package/dist/mcp.js CHANGED
@@ -5,7 +5,7 @@ import { listResources, readResource } from "./resources.js";
5
5
  import { getMCPPrompt, listMCPPrompts } from "./prompts.js";
6
6
  import { withSpan } from "./telemetry.js";
7
7
  import { createToolRegistry } from "./tools/index.js";
8
- export const SERVER_VERSION = "1.4.3"; // x-release-please-version
8
+ export const SERVER_VERSION = "1.6.0"; // x-release-please-version
9
9
  export const SERVER_NAME = "io.github.oaslananka/ssh-mcp-pro";
10
10
  function getSessionIdFromArgs(args) {
11
11
  if (typeof args !== "object" || args === null || Array.isArray(args)) {
@@ -0,0 +1,4 @@
1
+ import type { RemoteToolName } from "./types.js";
2
+ /** Keep managed process command and stdin payloads out of durable action metadata. */
3
+ export declare function safeStoredActionArgs(tool: RemoteToolName, args: Record<string, unknown>): Record<string, unknown>;
4
+ //# sourceMappingURL=action-record-sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-record-sanitize.d.ts","sourceRoot":"","sources":["../../src/remote/action-record-sanitize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB"}
@@ -0,0 +1,11 @@
1
+ /** Keep managed process command and stdin payloads out of durable action metadata. */
2
+ export function safeStoredActionArgs(tool, args) {
3
+ if (tool === "process_start")
4
+ return { ...args, command: "[redacted]" };
5
+ if (tool === "process_input")
6
+ return { ...args, input: "[redacted]" };
7
+ if (tool === "file_content_search")
8
+ return { ...args, query: "[redacted]" };
9
+ return args;
10
+ }
11
+ //# sourceMappingURL=action-record-sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-record-sanitize.js","sourceRoot":"","sources":["../../src/remote/action-record-sanitize.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAClC,IAAoB,EACpB,IAA6B;IAE7B,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxE,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtE,IAAI,IAAI,KAAK,qBAAqB;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAC5E,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { FileHandle } from "node:fs/promises";
2
+ export interface OutputAccumulator {
3
+ bytes: number;
4
+ chunks: Buffer[];
5
+ truncated: boolean;
6
+ }
7
+ export declare function appendBoundedOutput(accumulator: OutputAccumulator, chunk: Buffer, maxBytes: number): void;
8
+ export declare function finalizeBoundedOutput(accumulator: OutputAccumulator, maxBytes: number): {
9
+ value: Buffer;
10
+ truncated: boolean;
11
+ };
12
+ export declare function readFileBounded(file: FileHandle, maxBytes: number): Promise<{
13
+ value: Buffer;
14
+ truncated: boolean;
15
+ }>;
16
+ /**
17
+ * Read one page using byte offsets without buffering the entire file.
18
+ * Unlike a legacy read, a page must not include a truncation marker in text.
19
+ * Valid UTF-8 is kept at code-point boundaries when a page ends mid-character.
20
+ */
21
+ export declare function readFilePageBounded(file: FileHandle, offsetBytes: number, maxBytes: number): Promise<{
22
+ value: Buffer;
23
+ truncated: boolean;
24
+ nextOffsetBytes?: number;
25
+ }>;
26
+ export declare function readFileTailBounded(file: FileHandle, maxBytes: number, maxLines?: number): Promise<{
27
+ value: Buffer;
28
+ truncated: boolean;
29
+ }>;
30
+ //# sourceMappingURL=agent-bounded-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-bounded-io.d.ts","sourceRoot":"","sources":["../../src/remote/agent-bounded-io.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAkCD,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,iBAAiB,EAC9B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,IAAI,CAcN;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,iBAAiB,EAC9B,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAMvC;AAoBD,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAID;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgC1E;AAyCD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,SAAM,GACb,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAcD"}
@@ -0,0 +1,135 @@
1
+ function truncateBuffer(buffer, maxBytes) {
2
+ if (buffer.byteLength <= maxBytes) {
3
+ return { value: buffer, truncated: false };
4
+ }
5
+ return appendTruncationMarker(buffer, maxBytes);
6
+ }
7
+ function truncationMarker(maxBytes) {
8
+ return Buffer.from(`\n[truncated after ${maxBytes} bytes]\n`);
9
+ }
10
+ function appendTruncationMarker(buffer, maxBytes) {
11
+ if (maxBytes <= 0) {
12
+ return { value: Buffer.alloc(0), truncated: true };
13
+ }
14
+ const marker = truncationMarker(maxBytes);
15
+ if (marker.byteLength >= maxBytes) {
16
+ return { value: marker.subarray(0, maxBytes), truncated: true };
17
+ }
18
+ const payloadBytes = Math.max(0, maxBytes - marker.byteLength);
19
+ return {
20
+ value: Buffer.concat([buffer.subarray(0, payloadBytes), marker], maxBytes),
21
+ truncated: true,
22
+ };
23
+ }
24
+ export function appendBoundedOutput(accumulator, chunk, maxBytes) {
25
+ if (maxBytes <= 0) {
26
+ accumulator.truncated ||= chunk.byteLength > 0;
27
+ return;
28
+ }
29
+ const remaining = maxBytes - accumulator.bytes;
30
+ if (remaining <= 0) {
31
+ accumulator.truncated = true;
32
+ return;
33
+ }
34
+ const slice = chunk.subarray(0, remaining);
35
+ accumulator.chunks.push(slice);
36
+ accumulator.bytes += slice.byteLength;
37
+ accumulator.truncated ||= slice.byteLength !== chunk.byteLength;
38
+ }
39
+ export function finalizeBoundedOutput(accumulator, maxBytes) {
40
+ const value = Buffer.concat(accumulator.chunks, accumulator.bytes);
41
+ if (!accumulator.truncated) {
42
+ return { value, truncated: false };
43
+ }
44
+ return appendTruncationMarker(value, maxBytes);
45
+ }
46
+ async function readHandleRange(file, start, length) {
47
+ const buffer = Buffer.alloc(Math.max(0, length));
48
+ let offset = 0;
49
+ while (offset < buffer.byteLength) {
50
+ const { bytesRead } = await file.read(buffer, offset, buffer.byteLength - offset, start + offset);
51
+ if (bytesRead === 0) {
52
+ break;
53
+ }
54
+ offset += bytesRead;
55
+ }
56
+ return buffer.subarray(0, offset);
57
+ }
58
+ export async function readFileBounded(file, maxBytes) {
59
+ const cappedBytes = Math.max(0, maxBytes);
60
+ const buffer = await readHandleRange(file, 0, cappedBytes + 1);
61
+ return truncateBuffer(buffer, cappedBytes);
62
+ }
63
+ /**
64
+ * Read one page using byte offsets without buffering the entire file.
65
+ * Unlike a legacy read, a page must not include a truncation marker in text.
66
+ * Valid UTF-8 is kept at code-point boundaries when a page ends mid-character.
67
+ */
68
+ export async function readFilePageBounded(file, offsetBytes, maxBytes) {
69
+ const raw = await readHandleRange(file, offsetBytes, maxBytes + 1);
70
+ let page = raw.subarray(0, maxBytes);
71
+ let truncated = raw.byteLength > maxBytes;
72
+ const decoder = new TextDecoder("utf-8", { fatal: true });
73
+ let validPage = false;
74
+ for (let removed = 0; removed <= (truncated ? Math.min(3, page.byteLength) : 0); removed += 1) {
75
+ try {
76
+ decoder.decode(page.subarray(0, page.byteLength - removed));
77
+ page = page.subarray(0, page.byteLength - removed);
78
+ validPage = true;
79
+ break;
80
+ }
81
+ catch {
82
+ // A UTF-8 code point may cross the page boundary.
83
+ }
84
+ }
85
+ if (!validPage || (truncated && page.byteLength === 0)) {
86
+ throw Object.assign(new Error("Page cannot advance at this UTF-8 boundary; increase max_bytes or use a valid offset"), {
87
+ code: "POLICY_DENIED",
88
+ });
89
+ }
90
+ truncated ||= page.byteLength < raw.byteLength;
91
+ return {
92
+ value: page,
93
+ truncated,
94
+ ...(truncated && page.byteLength > 0 ? { nextOffsetBytes: offsetBytes + page.byteLength } : {}),
95
+ };
96
+ }
97
+ const TAIL_SCAN_CHUNK_BYTES = 64 * 1024;
98
+ const MAX_TAIL_SCAN_BYTES = 8 * 1024 * 1024;
99
+ async function findTailStart(file, size, maxLines, maxScanBytes) {
100
+ if (size <= 0 || maxLines <= 0) {
101
+ return { offset: size, scanTruncated: false };
102
+ }
103
+ let position = size;
104
+ const minimumPosition = Math.max(0, size - Math.max(0, maxScanBytes));
105
+ let includedLines = 1;
106
+ while (position > minimumPosition) {
107
+ const chunkSize = Math.min(TAIL_SCAN_CHUNK_BYTES, position - minimumPosition);
108
+ position -= chunkSize;
109
+ const chunk = await readHandleRange(file, position, chunkSize);
110
+ for (let index = chunk.byteLength - 1; index >= 0; index -= 1) {
111
+ const absoluteIndex = position + index;
112
+ if (chunk[index] !== 0x0a || absoluteIndex === size - 1) {
113
+ continue;
114
+ }
115
+ if (includedLines >= maxLines) {
116
+ return { offset: absoluteIndex + 1, scanTruncated: false };
117
+ }
118
+ includedLines += 1;
119
+ }
120
+ }
121
+ return { offset: minimumPosition, scanTruncated: minimumPosition > 0 };
122
+ }
123
+ export async function readFileTailBounded(file, maxBytes, maxLines = 100) {
124
+ const cappedBytes = Math.max(0, maxBytes);
125
+ const stats = await file.stat();
126
+ const scanBytes = Math.max(TAIL_SCAN_CHUNK_BYTES, Math.min(MAX_TAIL_SCAN_BYTES, cappedBytes * 4 + 1));
127
+ const { offset, scanTruncated } = await findTailStart(file, stats.size, maxLines, scanBytes);
128
+ const bytesToRead = Math.min(stats.size - offset, cappedBytes + 1);
129
+ const buffer = await readHandleRange(file, offset, bytesToRead);
130
+ const bounded = truncateBuffer(buffer, cappedBytes);
131
+ return scanTruncated && !bounded.truncated
132
+ ? appendTruncationMarker(bounded.value, cappedBytes)
133
+ : bounded;
134
+ }
135
+ //# sourceMappingURL=agent-bounded-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-bounded-io.js","sourceRoot":"","sources":["../../src/remote/agent-bounded-io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface LocalBrowserEnrollment {
2
+ verificationUrl: string;
3
+ callbackUrl: string;
4
+ port: number;
5
+ finished: Promise<void>;
6
+ close(): void;
7
+ }
8
+ /**
9
+ * A same-device HTTPS dashboard may hand its one-time token directly to a
10
+ * loopback listener. Only the bound browser origin, random challenge and
11
+ * local socket are accepted; the one-time token never appears in the URL.
12
+ */
13
+ export declare function startLocalBrowserEnrollment(serverUrl: string, alias: string, onToken: (token: string) => Promise<void>, options?: {
14
+ timeoutMs?: number;
15
+ }): Promise<LocalBrowserEnrollment>;
16
+ //# sourceMappingURL=agent-browser-enrollment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-browser-enrollment.d.ts","sourceRoot":"","sources":["../../src/remote/agent-browser-enrollment.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AA8DD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAkIjC"}
@@ -0,0 +1,190 @@
1
+ import { randomBytes, timingSafeEqual } from "node:crypto";
2
+ import { createServer } from "node:http";
3
+ const MAX_BODY_BYTES = 4_096;
4
+ const DEFAULT_TIMEOUT_MS = 600_000;
5
+ function safeEqual(expected, actual) {
6
+ const left = Buffer.from(expected);
7
+ const right = Buffer.from(actual);
8
+ return left.length === right.length && timingSafeEqual(left, right);
9
+ }
10
+ function validServerOrigin(serverUrl) {
11
+ const url = new URL(serverUrl);
12
+ if (url.username ||
13
+ url.password ||
14
+ url.search ||
15
+ url.hash ||
16
+ (url.protocol !== "https:" &&
17
+ !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)))) {
18
+ throw new Error("Browser enrollment requires an HTTPS server or local loopback URL");
19
+ }
20
+ return url.origin;
21
+ }
22
+ function send(res, code, message, origin, preflight = false) {
23
+ res.writeHead(code, {
24
+ "Content-Type": "text/plain; charset=utf-8",
25
+ "Cache-Control": "no-store",
26
+ ...(origin
27
+ ? {
28
+ "Access-Control-Allow-Origin": origin,
29
+ Vary: "Origin",
30
+ ...(preflight
31
+ ? {
32
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
33
+ "Access-Control-Allow-Headers": "content-type",
34
+ "Access-Control-Max-Age": "0",
35
+ }
36
+ : {}),
37
+ }
38
+ : {}),
39
+ });
40
+ res.end(message);
41
+ }
42
+ async function readLimitedJson(req) {
43
+ const chunks = [];
44
+ let size = 0;
45
+ for await (const chunk of req) {
46
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
47
+ size += bytes.length;
48
+ if (size > MAX_BODY_BYTES)
49
+ throw new Error("Request body exceeds limit");
50
+ chunks.push(bytes);
51
+ }
52
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
53
+ }
54
+ /**
55
+ * A same-device HTTPS dashboard may hand its one-time token directly to a
56
+ * loopback listener. Only the bound browser origin, random challenge and
57
+ * local socket are accepted; the one-time token never appears in the URL.
58
+ */
59
+ export async function startLocalBrowserEnrollment(serverUrl, alias, onToken, options = {}) {
60
+ const origin = validServerOrigin(serverUrl);
61
+ const state = randomBytes(32).toString("base64url");
62
+ let complete;
63
+ let fail;
64
+ let settled = false;
65
+ const finished = new Promise((resolve, reject) => {
66
+ complete = () => {
67
+ if (settled)
68
+ return;
69
+ settled = true;
70
+ resolve();
71
+ };
72
+ fail = (error) => {
73
+ if (settled)
74
+ return;
75
+ settled = true;
76
+ reject(error);
77
+ };
78
+ });
79
+ // Closing early is allowed without an unhandled rejection, while callers
80
+ // awaiting finished still receive the same timeout/cancellation failure.
81
+ void finished.catch(() => { });
82
+ let enrolled = false;
83
+ const listener = createServer((req, res) => {
84
+ void handleRequest(req, res).catch(() => {
85
+ if (!res.headersSent)
86
+ send(res, 500, "Local approval failed");
87
+ });
88
+ });
89
+ async function handleRequest(req, res) {
90
+ const remote = req.socket.remoteAddress ?? "";
91
+ const localOnly = remote === "127.0.0.1";
92
+ if (!localOnly || req.headers.origin !== origin) {
93
+ send(res, 403, "Browser origin is not allowed");
94
+ return;
95
+ }
96
+ const address = listener.address();
97
+ if (req.headers.host !== `127.0.0.1:${address.port}` ||
98
+ (req.url !== "/enroll" && req.url !== "/ready")) {
99
+ send(res, 403, "Unexpected callback destination", origin);
100
+ return;
101
+ }
102
+ if (req.method === "GET" && req.url === "/ready") {
103
+ send(res, 204, "", origin);
104
+ return;
105
+ }
106
+ if (req.method === "OPTIONS") {
107
+ send(res, 204, "", origin, true);
108
+ return;
109
+ }
110
+ if (req.method !== "POST" || enrolled) {
111
+ send(res, 405, "Enrollment is not available", origin);
112
+ return;
113
+ }
114
+ if (!(req.headers["content-type"] ?? "").startsWith("application/json")) {
115
+ send(res, 415, "JSON required", origin);
116
+ return;
117
+ }
118
+ let body;
119
+ try {
120
+ body = await readLimitedJson(req);
121
+ }
122
+ catch {
123
+ send(res, 400, "Invalid enrollment request", origin);
124
+ return;
125
+ }
126
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
127
+ send(res, 400, "Invalid enrollment request", origin);
128
+ return;
129
+ }
130
+ const data = body;
131
+ if (typeof data.state !== "string" || !safeEqual(state, data.state)) {
132
+ send(res, 403, "Enrollment link does not match", origin);
133
+ return;
134
+ }
135
+ if (typeof data.token !== "string" || !/^[A-Za-z0-9_-]{30,256}$/u.test(data.token)) {
136
+ send(res, 400, "Enrollment token is missing or malformed", origin);
137
+ return;
138
+ }
139
+ enrolled = true;
140
+ try {
141
+ await onToken(data.token);
142
+ send(res, 200, "Enrollment accepted", origin);
143
+ complete();
144
+ listener.close();
145
+ }
146
+ catch {
147
+ enrolled = false;
148
+ send(res, 502, "Device enrollment failed; check the agent terminal", origin);
149
+ }
150
+ }
151
+ await new Promise((resolve, reject) => {
152
+ listener.once("error", reject);
153
+ listener.listen(0, "127.0.0.1", () => {
154
+ listener.off("error", reject);
155
+ resolve();
156
+ });
157
+ });
158
+ const address = listener.address();
159
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
160
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > DEFAULT_TIMEOUT_MS) {
161
+ listener.close();
162
+ throw new Error("Invalid local browser enrollment timeout");
163
+ }
164
+ const timer = setTimeout(() => {
165
+ fail(new Error("Browser enrollment expired; restart the installer"));
166
+ listener.close();
167
+ }, timeoutMs);
168
+ timer.unref();
169
+ void finished
170
+ .finally(() => {
171
+ clearTimeout(timer);
172
+ })
173
+ .catch(() => { });
174
+ const dashboardUrl = new URL("/dashboard", origin);
175
+ dashboardUrl.searchParams.set("local_enroll_port", String(address.port));
176
+ dashboardUrl.searchParams.set("local_enroll_state", state);
177
+ dashboardUrl.searchParams.set("local_enroll_alias", alias);
178
+ return {
179
+ verificationUrl: dashboardUrl.toString(),
180
+ callbackUrl: `http://127.0.0.1:${address.port}/enroll`,
181
+ port: address.port,
182
+ finished,
183
+ close() {
184
+ fail(new Error("Browser enrollment cancelled"));
185
+ clearTimeout(timer);
186
+ listener.close();
187
+ },
188
+ };
189
+ }
190
+ //# sourceMappingURL=agent-browser-enrollment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-browser-enrollment.js","sourceRoot":"","sources":["../../src/remote/agent-browser-enrollment.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,7 @@
1
+ /** Recoverable network failure; invalid enrollment/configuration must not be retried. */
2
+ export declare class RetryableAgentTransportError extends Error {
3
+ }
1
4
  export declare function runAgentCli(argv: string[]): Promise<void>;
5
+ /** Keep installed agents online across transient socket failures without re-enrollment. */
6
+ export declare function runAgentCliWithReconnect(argv: string[], run?: (args: string[]) => Promise<void>, pause?: (delayMs: number) => Promise<void>): Promise<void>;
2
7
  //# sourceMappingURL=agent-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-cli.d.ts","sourceRoot":"","sources":["../../src/remote/agent-cli.ts"],"names":[],"mappings":"AAsfA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC/D"}
1
+ {"version":3,"file":"agent-cli.d.ts","sourceRoot":"","sources":["../../src/remote/agent-cli.ts"],"names":[],"mappings":"AAwDA,yFAAyF;AACzF,qBAAa,4BAA6B,SAAQ,KAAK;CAAG;AAkf1D,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC/D;AACD,2FAA2F;AAC3F,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAe,EACpD,KAAK,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CACW,GAClD,OAAO,CAAC,IAAI,CAAC,CA2Bf"}