mstro-app 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mstro.js +119 -40
- package/dist/server/cli/headless/claude-invoker-process.d.ts +11 -0
- package/dist/server/cli/headless/claude-invoker-process.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-process.js +140 -0
- package/dist/server/cli/headless/claude-invoker-process.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stall.d.ts +40 -0
- package/dist/server/cli/headless/claude-invoker-stall.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stall.js +98 -0
- package/dist/server/cli/headless/claude-invoker-stall.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stream.d.ts +44 -0
- package/dist/server/cli/headless/claude-invoker-stream.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stream.js +276 -0
- package/dist/server/cli/headless/claude-invoker-stream.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-tools.d.ts +21 -0
- package/dist/server/cli/headless/claude-invoker-tools.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-tools.js +137 -0
- package/dist/server/cli/headless/claude-invoker-tools.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker.d.ts +6 -4
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +10 -804
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/haiku-assessments.d.ts +62 -0
- package/dist/server/cli/headless/haiku-assessments.d.ts.map +1 -0
- package/dist/server/cli/headless/haiku-assessments.js +281 -0
- package/dist/server/cli/headless/haiku-assessments.js.map +1 -0
- package/dist/server/cli/headless/headless-logger.d.ts +3 -2
- package/dist/server/cli/headless/headless-logger.d.ts.map +1 -1
- package/dist/server/cli/headless/headless-logger.js +28 -5
- package/dist/server/cli/headless/headless-logger.js.map +1 -1
- package/dist/server/cli/headless/native-timeout-detector.d.ts +44 -0
- package/dist/server/cli/headless/native-timeout-detector.d.ts.map +1 -0
- package/dist/server/cli/headless/native-timeout-detector.js +99 -0
- package/dist/server/cli/headless/native-timeout-detector.js.map +1 -0
- package/dist/server/cli/headless/stall-assessor.d.ts +2 -110
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +65 -457
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/headless/types.d.ts +4 -1
- package/dist/server/cli/headless/types.d.ts.map +1 -1
- package/dist/server/cli/improvisation-attachments.d.ts +21 -0
- package/dist/server/cli/improvisation-attachments.d.ts.map +1 -0
- package/dist/server/cli/improvisation-attachments.js +116 -0
- package/dist/server/cli/improvisation-attachments.js.map +1 -0
- package/dist/server/cli/improvisation-retry.d.ts +52 -0
- package/dist/server/cli/improvisation-retry.d.ts.map +1 -0
- package/dist/server/cli/improvisation-retry.js +434 -0
- package/dist/server/cli/improvisation-retry.js.map +1 -0
- package/dist/server/cli/improvisation-session-manager.d.ts +10 -266
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +117 -1079
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/cli/improvisation-types.d.ts +86 -0
- package/dist/server/cli/improvisation-types.d.ts.map +1 -0
- package/dist/server/cli/improvisation-types.js +10 -0
- package/dist/server/cli/improvisation-types.js.map +1 -0
- package/dist/server/cli/prompt-builders.d.ts +68 -0
- package/dist/server/cli/prompt-builders.d.ts.map +1 -0
- package/dist/server/cli/prompt-builders.js +312 -0
- package/dist/server/cli/prompt-builders.js.map +1 -0
- package/dist/server/index.js +33 -212
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/bouncer-haiku.d.ts +10 -0
- package/dist/server/mcp/bouncer-haiku.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-haiku.js +152 -0
- package/dist/server/mcp/bouncer-haiku.js.map +1 -0
- package/dist/server/mcp/bouncer-integration.d.ts +3 -4
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-integration.js +50 -196
- package/dist/server/mcp/bouncer-integration.js.map +1 -1
- package/dist/server/mcp/security-analysis.d.ts +38 -0
- package/dist/server/mcp/security-analysis.d.ts.map +1 -0
- package/dist/server/mcp/security-analysis.js +183 -0
- package/dist/server/mcp/security-analysis.js.map +1 -0
- package/dist/server/mcp/security-audit.d.ts +1 -1
- package/dist/server/mcp/security-audit.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.d.ts +1 -25
- package/dist/server/mcp/security-patterns.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.js +55 -260
- package/dist/server/mcp/security-patterns.js.map +1 -1
- package/dist/server/server-setup.d.ts +22 -0
- package/dist/server/server-setup.d.ts.map +1 -0
- package/dist/server/server-setup.js +101 -0
- package/dist/server/server-setup.js.map +1 -0
- package/dist/server/services/file-explorer-ops.d.ts +24 -0
- package/dist/server/services/file-explorer-ops.d.ts.map +1 -0
- package/dist/server/services/file-explorer-ops.js +211 -0
- package/dist/server/services/file-explorer-ops.js.map +1 -0
- package/dist/server/services/files.d.ts +2 -85
- package/dist/server/services/files.d.ts.map +1 -1
- package/dist/server/services/files.js +7 -427
- package/dist/server/services/files.js.map +1 -1
- package/dist/server/services/plan/composer.d.ts +1 -1
- package/dist/server/services/plan/composer.d.ts.map +1 -1
- package/dist/server/services/plan/composer.js +118 -32
- package/dist/server/services/plan/composer.js.map +1 -1
- package/dist/server/services/plan/config-installer.d.ts +25 -0
- package/dist/server/services/plan/config-installer.d.ts.map +1 -0
- package/dist/server/services/plan/config-installer.js +182 -0
- package/dist/server/services/plan/config-installer.js.map +1 -0
- package/dist/server/services/plan/dependency-resolver.d.ts +1 -1
- package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -1
- package/dist/server/services/plan/dependency-resolver.js +4 -1
- package/dist/server/services/plan/dependency-resolver.js.map +1 -1
- package/dist/server/services/plan/executor.d.ts +38 -74
- package/dist/server/services/plan/executor.d.ts.map +1 -1
- package/dist/server/services/plan/executor.js +274 -460
- package/dist/server/services/plan/executor.js.map +1 -1
- package/dist/server/services/plan/front-matter.d.ts +18 -0
- package/dist/server/services/plan/front-matter.d.ts.map +1 -0
- package/dist/server/services/plan/front-matter.js +44 -0
- package/dist/server/services/plan/front-matter.js.map +1 -0
- package/dist/server/services/plan/output-manager.d.ts +22 -0
- package/dist/server/services/plan/output-manager.d.ts.map +1 -0
- package/dist/server/services/plan/output-manager.js +97 -0
- package/dist/server/services/plan/output-manager.js.map +1 -0
- package/dist/server/services/plan/parser-core.d.ts +20 -0
- package/dist/server/services/plan/parser-core.d.ts.map +1 -0
- package/dist/server/services/plan/parser-core.js +350 -0
- package/dist/server/services/plan/parser-core.js.map +1 -0
- package/dist/server/services/plan/parser-migration.d.ts +5 -0
- package/dist/server/services/plan/parser-migration.d.ts.map +1 -0
- package/dist/server/services/plan/parser-migration.js +124 -0
- package/dist/server/services/plan/parser-migration.js.map +1 -0
- package/dist/server/services/plan/parser.d.ts +11 -3
- package/dist/server/services/plan/parser.d.ts.map +1 -1
- package/dist/server/services/plan/parser.js +184 -369
- package/dist/server/services/plan/parser.js.map +1 -1
- package/dist/server/services/plan/prompt-builder.d.ts +17 -0
- package/dist/server/services/plan/prompt-builder.d.ts.map +1 -0
- package/dist/server/services/plan/prompt-builder.js +137 -0
- package/dist/server/services/plan/prompt-builder.js.map +1 -0
- package/dist/server/services/plan/review-gate.d.ts +28 -0
- package/dist/server/services/plan/review-gate.d.ts.map +1 -0
- package/dist/server/services/plan/review-gate.js +191 -0
- package/dist/server/services/plan/review-gate.js.map +1 -0
- package/dist/server/services/plan/state-reconciler.d.ts +1 -1
- package/dist/server/services/plan/state-reconciler.d.ts.map +1 -1
- package/dist/server/services/plan/state-reconciler.js +59 -7
- package/dist/server/services/plan/state-reconciler.js.map +1 -1
- package/dist/server/services/plan/types.d.ts +68 -0
- package/dist/server/services/plan/types.d.ts.map +1 -1
- package/dist/server/services/platform-credentials.d.ts +24 -0
- package/dist/server/services/platform-credentials.d.ts.map +1 -0
- package/dist/server/services/platform-credentials.js +68 -0
- package/dist/server/services/platform-credentials.js.map +1 -0
- package/dist/server/services/platform.d.ts +1 -31
- package/dist/server/services/platform.d.ts.map +1 -1
- package/dist/server/services/platform.js +11 -109
- package/dist/server/services/platform.js.map +1 -1
- package/dist/server/services/terminal/pty-manager.d.ts +7 -97
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-manager.js +53 -266
- package/dist/server/services/terminal/pty-manager.js.map +1 -1
- package/dist/server/services/terminal/pty-utils.d.ts +57 -0
- package/dist/server/services/terminal/pty-utils.d.ts.map +1 -0
- package/dist/server/services/terminal/pty-utils.js +141 -0
- package/dist/server/services/terminal/pty-utils.js.map +1 -0
- package/dist/server/services/websocket/file-definition-handlers.d.ts +4 -0
- package/dist/server/services/websocket/file-definition-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-definition-handlers.js +153 -0
- package/dist/server/services/websocket/file-definition-handlers.js.map +1 -0
- package/dist/server/services/websocket/file-explorer-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/file-explorer-handlers.js +52 -391
- package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
- package/dist/server/services/websocket/file-search-handlers.d.ts +5 -0
- package/dist/server/services/websocket/file-search-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-search-handlers.js +238 -0
- package/dist/server/services/websocket/file-search-handlers.js.map +1 -0
- package/dist/server/services/websocket/file-utils.js +3 -3
- package/dist/server/services/websocket/file-utils.js.map +1 -1
- package/dist/server/services/websocket/git-branch-handlers.d.ts +7 -0
- package/dist/server/services/websocket/git-branch-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-branch-handlers.js +110 -0
- package/dist/server/services/websocket/git-branch-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-diff-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-diff-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-diff-handlers.js +123 -0
- package/dist/server/services/websocket/git-diff-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-handlers.d.ts +2 -31
- package/dist/server/services/websocket/git-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-handlers.js +35 -541
- package/dist/server/services/websocket/git-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-log-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-log-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-log-handlers.js +128 -0
- package/dist/server/services/websocket/git-log-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-pr-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-pr-handlers.js +13 -53
- package/dist/server/services/websocket/git-pr-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-tag-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-tag-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-tag-handlers.js +76 -0
- package/dist/server/services/websocket/git-tag-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-utils.d.ts +43 -0
- package/dist/server/services/websocket/git-utils.d.ts.map +1 -0
- package/dist/server/services/websocket/git-utils.js +201 -0
- package/dist/server/services/websocket/git-utils.js.map +1 -0
- package/dist/server/services/websocket/handler.d.ts +2 -0
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +37 -112
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/plan-board-handlers.d.ts +11 -0
- package/dist/server/services/websocket/plan-board-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-board-handlers.js +218 -0
- package/dist/server/services/websocket/plan-board-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-execution-handlers.d.ts +9 -0
- package/dist/server/services/websocket/plan-execution-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-execution-handlers.js +142 -0
- package/dist/server/services/websocket/plan-execution-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-handlers.d.ts +7 -2
- package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-handlers.js +21 -462
- package/dist/server/services/websocket/plan-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-helpers.d.ts +19 -0
- package/dist/server/services/websocket/plan-helpers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-helpers.js +199 -0
- package/dist/server/services/websocket/plan-helpers.js.map +1 -0
- package/dist/server/services/websocket/plan-issue-handlers.d.ts +12 -0
- package/dist/server/services/websocket/plan-issue-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-issue-handlers.js +162 -0
- package/dist/server/services/websocket/plan-issue-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts +7 -0
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js +206 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js.map +1 -0
- package/dist/server/services/websocket/quality-complexity.d.ts +14 -0
- package/dist/server/services/websocket/quality-complexity.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-complexity.js +262 -0
- package/dist/server/services/websocket/quality-complexity.js.map +1 -0
- package/dist/server/services/websocket/quality-fix-agent.d.ts +16 -0
- package/dist/server/services/websocket/quality-fix-agent.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-fix-agent.js +140 -0
- package/dist/server/services/websocket/quality-fix-agent.js.map +1 -0
- package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-handlers.js +34 -346
- package/dist/server/services/websocket/quality-handlers.js.map +1 -1
- package/dist/server/services/websocket/quality-linting.d.ts +9 -0
- package/dist/server/services/websocket/quality-linting.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-linting.js +178 -0
- package/dist/server/services/websocket/quality-linting.js.map +1 -0
- package/dist/server/services/websocket/quality-review-agent.d.ts +19 -0
- package/dist/server/services/websocket/quality-review-agent.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-review-agent.js +206 -0
- package/dist/server/services/websocket/quality-review-agent.js.map +1 -0
- package/dist/server/services/websocket/quality-service.d.ts +3 -51
- package/dist/server/services/websocket/quality-service.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-service.js +9 -651
- package/dist/server/services/websocket/quality-service.js.map +1 -1
- package/dist/server/services/websocket/quality-tools.d.ts +23 -0
- package/dist/server/services/websocket/quality-tools.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-tools.js +208 -0
- package/dist/server/services/websocket/quality-tools.js.map +1 -0
- package/dist/server/services/websocket/quality-types.d.ts +59 -0
- package/dist/server/services/websocket/quality-types.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-types.js +101 -0
- package/dist/server/services/websocket/quality-types.js.map +1 -0
- package/dist/server/services/websocket/session-handlers.d.ts +3 -4
- package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/session-handlers.js +3 -378
- package/dist/server/services/websocket/session-handlers.js.map +1 -1
- package/dist/server/services/websocket/session-history.d.ts +4 -0
- package/dist/server/services/websocket/session-history.d.ts.map +1 -0
- package/dist/server/services/websocket/session-history.js +208 -0
- package/dist/server/services/websocket/session-history.js.map +1 -0
- package/dist/server/services/websocket/session-initialization.d.ts +5 -0
- package/dist/server/services/websocket/session-initialization.d.ts.map +1 -0
- package/dist/server/services/websocket/session-initialization.js +163 -0
- package/dist/server/services/websocket/session-initialization.js.map +1 -0
- package/dist/server/services/websocket/types.d.ts +12 -2
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/package.json +1 -2
- package/server/cli/headless/claude-invoker-process.ts +204 -0
- package/server/cli/headless/claude-invoker-stall.ts +164 -0
- package/server/cli/headless/claude-invoker-stream.ts +353 -0
- package/server/cli/headless/claude-invoker-tools.ts +187 -0
- package/server/cli/headless/claude-invoker.ts +15 -1092
- package/server/cli/headless/haiku-assessments.ts +365 -0
- package/server/cli/headless/headless-logger.ts +26 -5
- package/server/cli/headless/native-timeout-detector.ts +117 -0
- package/server/cli/headless/stall-assessor.ts +65 -618
- package/server/cli/headless/types.ts +4 -1
- package/server/cli/improvisation-attachments.ts +148 -0
- package/server/cli/improvisation-retry.ts +602 -0
- package/server/cli/improvisation-session-manager.ts +140 -1349
- package/server/cli/improvisation-types.ts +98 -0
- package/server/cli/prompt-builders.ts +370 -0
- package/server/index.ts +35 -246
- package/server/mcp/bouncer-haiku.ts +182 -0
- package/server/mcp/bouncer-integration.ts +87 -248
- package/server/mcp/security-analysis.ts +217 -0
- package/server/mcp/security-audit.ts +1 -1
- package/server/mcp/security-patterns.ts +60 -283
- package/server/server-setup.ts +114 -0
- package/server/services/file-explorer-ops.ts +293 -0
- package/server/services/files.ts +20 -532
- package/server/services/plan/composer.ts +140 -35
- package/server/services/plan/config-installer.ts +187 -0
- package/server/services/plan/dependency-resolver.ts +4 -1
- package/server/services/plan/executor.ts +281 -488
- package/server/services/plan/front-matter.ts +48 -0
- package/server/services/plan/output-manager.ts +113 -0
- package/server/services/plan/parser-core.ts +406 -0
- package/server/services/plan/parser-migration.ts +128 -0
- package/server/services/plan/parser.ts +188 -394
- package/server/services/plan/prompt-builder.ts +161 -0
- package/server/services/plan/review-gate.ts +212 -0
- package/server/services/plan/state-reconciler.ts +68 -7
- package/server/services/plan/types.ts +101 -1
- package/server/services/platform-credentials.ts +83 -0
- package/server/services/platform.ts +16 -131
- package/server/services/terminal/pty-manager.ts +66 -313
- package/server/services/terminal/pty-utils.ts +176 -0
- package/server/services/websocket/file-definition-handlers.ts +165 -0
- package/server/services/websocket/file-explorer-handlers.ts +37 -452
- package/server/services/websocket/file-search-handlers.ts +291 -0
- package/server/services/websocket/file-utils.ts +3 -3
- package/server/services/websocket/git-branch-handlers.ts +130 -0
- package/server/services/websocket/git-diff-handlers.ts +140 -0
- package/server/services/websocket/git-handlers.ts +40 -625
- package/server/services/websocket/git-log-handlers.ts +149 -0
- package/server/services/websocket/git-pr-handlers.ts +17 -62
- package/server/services/websocket/git-tag-handlers.ts +91 -0
- package/server/services/websocket/git-utils.ts +230 -0
- package/server/services/websocket/handler.ts +39 -112
- package/server/services/websocket/plan-board-handlers.ts +277 -0
- package/server/services/websocket/plan-execution-handlers.ts +184 -0
- package/server/services/websocket/plan-handlers.ts +23 -544
- package/server/services/websocket/plan-helpers.ts +215 -0
- package/server/services/websocket/plan-issue-handlers.ts +204 -0
- package/server/services/websocket/plan-sprint-handlers.ts +252 -0
- package/server/services/websocket/quality-complexity.ts +294 -0
- package/server/services/websocket/quality-fix-agent.ts +181 -0
- package/server/services/websocket/quality-handlers.ts +36 -404
- package/server/services/websocket/quality-linting.ts +187 -0
- package/server/services/websocket/quality-review-agent.ts +246 -0
- package/server/services/websocket/quality-service.ts +11 -762
- package/server/services/websocket/quality-tools.ts +209 -0
- package/server/services/websocket/quality-types.ts +169 -0
- package/server/services/websocket/session-handlers.ts +5 -437
- package/server/services/websocket/session-history.ts +222 -0
- package/server/services/websocket/session-initialization.ts +209 -0
- package/server/services/websocket/types.ts +46 -2
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Platform Credentials — Token management for device authentication.
|
|
6
|
+
*
|
|
7
|
+
* Reads/writes credentials from ~/.mstro/credentials.json and handles
|
|
8
|
+
* periodic token refresh with the platform server.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
12
|
+
import { homedir } from 'node:os'
|
|
13
|
+
import { join } from 'node:path'
|
|
14
|
+
import { MSTRO_ROOT } from '../utils/paths.js'
|
|
15
|
+
|
|
16
|
+
// Read CLI version from package.json once at import time
|
|
17
|
+
export const CLI_VERSION = (() => {
|
|
18
|
+
try {
|
|
19
|
+
const pkg = JSON.parse(readFileSync(join(MSTRO_ROOT, 'package.json'), 'utf-8'))
|
|
20
|
+
return pkg.version || '0.0.0'
|
|
21
|
+
} catch {
|
|
22
|
+
return '0.0.0'
|
|
23
|
+
}
|
|
24
|
+
})()
|
|
25
|
+
|
|
26
|
+
const MSTRO_DIR = join(homedir(), '.mstro')
|
|
27
|
+
const CREDENTIALS_FILE = join(MSTRO_DIR, 'credentials.json')
|
|
28
|
+
|
|
29
|
+
/** Refresh token every 30 days */
|
|
30
|
+
export const TOKEN_REFRESH_INTERVAL_MS = 30 * 24 * 60 * 60 * 1000
|
|
31
|
+
|
|
32
|
+
export interface StoredCredentials {
|
|
33
|
+
token: string
|
|
34
|
+
userId: string
|
|
35
|
+
email: string
|
|
36
|
+
name?: string
|
|
37
|
+
clientId: string
|
|
38
|
+
lastRefreshedAt?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get stored credentials from ~/.mstro/credentials.json
|
|
43
|
+
*/
|
|
44
|
+
export function getCredentials(): StoredCredentials | null {
|
|
45
|
+
if (!existsSync(CREDENTIALS_FILE)) {
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const content = readFileSync(CREDENTIALS_FILE, 'utf-8')
|
|
50
|
+
const creds = JSON.parse(content)
|
|
51
|
+
if (creds.token && creds.userId && creds.email) {
|
|
52
|
+
return creds
|
|
53
|
+
}
|
|
54
|
+
return null
|
|
55
|
+
} catch {
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Update stored credentials (for token refresh)
|
|
62
|
+
*/
|
|
63
|
+
export function updateCredentials(updates: Partial<StoredCredentials>): void {
|
|
64
|
+
const creds = getCredentials()
|
|
65
|
+
if (!creds) return
|
|
66
|
+
|
|
67
|
+
writeFileSync(CREDENTIALS_FILE, JSON.stringify({ ...creds, ...updates }, null, 2), {
|
|
68
|
+
mode: 0o600
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if token should be refreshed
|
|
74
|
+
*/
|
|
75
|
+
export function shouldRefreshToken(creds: StoredCredentials): boolean {
|
|
76
|
+
if (!creds.lastRefreshedAt) {
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const lastRefreshed = new Date(creds.lastRefreshedAt).getTime()
|
|
81
|
+
const now = Date.now()
|
|
82
|
+
return now - lastRefreshed > TOKEN_REFRESH_INTERVAL_MS
|
|
83
|
+
}
|
|
@@ -7,82 +7,23 @@
|
|
|
7
7
|
* Handles WebSocket connection to the Mstro platform.
|
|
8
8
|
* Requires token-based authentication from `mstro login`.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* 1. Client reads token from ~/.mstro/credentials.json
|
|
12
|
-
* 2. Client connects to platform WebSocket with auth token
|
|
13
|
-
* 3. Platform validates token and auto-pairs to user's account
|
|
14
|
-
* 4. Client becomes an "orchestra" visible in user's web dashboard
|
|
10
|
+
* Credential management lives in platform-credentials.ts.
|
|
15
11
|
*/
|
|
16
12
|
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { basename, join } from 'node:path'
|
|
13
|
+
import { arch, hostname, type } from 'node:os'
|
|
14
|
+
import { basename } from 'node:path'
|
|
20
15
|
import { AnalyticsEvents, trackEvent } from './analytics.js'
|
|
21
16
|
import { getClientId } from './client-id.js'
|
|
17
|
+
import {
|
|
18
|
+
CLI_VERSION,
|
|
19
|
+
getCredentials,
|
|
20
|
+
shouldRefreshToken,
|
|
21
|
+
updateCredentials,
|
|
22
|
+
} from './platform-credentials.js'
|
|
22
23
|
import { captureException } from './sentry.js'
|
|
23
24
|
|
|
24
|
-
const MSTRO_DIR = join(homedir(), '.mstro')
|
|
25
|
-
const CREDENTIALS_FILE = join(MSTRO_DIR, 'credentials.json')
|
|
26
|
-
|
|
27
|
-
// Refresh token every 30 days
|
|
28
|
-
const TOKEN_REFRESH_INTERVAL_MS = 30 * 24 * 60 * 60 * 1000
|
|
29
|
-
|
|
30
|
-
interface StoredCredentials {
|
|
31
|
-
token: string
|
|
32
|
-
userId: string
|
|
33
|
-
email: string
|
|
34
|
-
name?: string
|
|
35
|
-
clientId: string
|
|
36
|
-
lastRefreshedAt?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get stored credentials from ~/.mstro/credentials.json
|
|
41
|
-
*/
|
|
42
|
-
function getCredentials(): StoredCredentials | null {
|
|
43
|
-
if (!existsSync(CREDENTIALS_FILE)) {
|
|
44
|
-
return null
|
|
45
|
-
}
|
|
46
|
-
try {
|
|
47
|
-
const content = readFileSync(CREDENTIALS_FILE, 'utf-8')
|
|
48
|
-
const creds = JSON.parse(content)
|
|
49
|
-
if (creds.token && creds.userId && creds.email) {
|
|
50
|
-
return creds
|
|
51
|
-
}
|
|
52
|
-
return null
|
|
53
|
-
} catch {
|
|
54
|
-
return null
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Update stored credentials (for token refresh)
|
|
60
|
-
*/
|
|
61
|
-
function updateCredentials(updates: Partial<StoredCredentials>): void {
|
|
62
|
-
const creds = getCredentials()
|
|
63
|
-
if (!creds) return
|
|
64
|
-
|
|
65
|
-
writeFileSync(CREDENTIALS_FILE, JSON.stringify({ ...creds, ...updates }, null, 2), {
|
|
66
|
-
mode: 0o600
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Check if token should be refreshed
|
|
72
|
-
*/
|
|
73
|
-
function shouldRefreshToken(creds: StoredCredentials): boolean {
|
|
74
|
-
if (!creds.lastRefreshedAt) {
|
|
75
|
-
return true // Never refreshed
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const lastRefreshed = new Date(creds.lastRefreshedAt).getTime()
|
|
79
|
-
const now = Date.now()
|
|
80
|
-
return now - lastRefreshed > TOKEN_REFRESH_INTERVAL_MS
|
|
81
|
-
}
|
|
82
|
-
|
|
83
25
|
/**
|
|
84
26
|
* Get machine identification string
|
|
85
|
-
* Format: "hostname @ node-vX.X.X platform (arch)"
|
|
86
27
|
* Example: "Jessica @ node-v22.21.1 linux (arm64)"
|
|
87
28
|
*/
|
|
88
29
|
export function getMachineIdentifier(): string {
|
|
@@ -114,9 +55,6 @@ interface ConnectionCallbacks {
|
|
|
114
55
|
onRelayedMessage?: (message: unknown) => void
|
|
115
56
|
}
|
|
116
57
|
|
|
117
|
-
/**
|
|
118
|
-
* Platform WebSocket connection with token-based authentication
|
|
119
|
-
*/
|
|
120
58
|
/** Number of missed pongs before treating connection as dead */
|
|
121
59
|
const MAX_MISSED_PONGS = 2
|
|
122
60
|
|
|
@@ -134,6 +72,7 @@ export class PlatformConnection {
|
|
|
134
72
|
private tokenRefreshInterval: ReturnType<typeof setInterval> | null = null
|
|
135
73
|
private heartbeatInterval: ReturnType<typeof setInterval> | null = null
|
|
136
74
|
private missedPongs = 0
|
|
75
|
+
private readonly startedAt: string
|
|
137
76
|
|
|
138
77
|
constructor(
|
|
139
78
|
workingDirectory: string,
|
|
@@ -143,16 +82,12 @@ export class PlatformConnection {
|
|
|
143
82
|
this.workingDirectory = workingDirectory
|
|
144
83
|
this.platformUrl = platformUrl || DEFAULT_PLATFORM_URL
|
|
145
84
|
this.callbacks = callbacks
|
|
85
|
+
this.startedAt = new Date().toISOString()
|
|
146
86
|
}
|
|
147
87
|
|
|
148
|
-
/**
|
|
149
|
-
* Refresh the device token if needed
|
|
150
|
-
*/
|
|
151
88
|
private async maybeRefreshToken(): Promise<void> {
|
|
152
89
|
const creds = getCredentials()
|
|
153
|
-
if (!creds || !shouldRefreshToken(creds))
|
|
154
|
-
return
|
|
155
|
-
}
|
|
90
|
+
if (!creds || !shouldRefreshToken(creds)) return
|
|
156
91
|
|
|
157
92
|
try {
|
|
158
93
|
const response = await fetch(`${this.platformUrl}/api/auth/device/refresh`, {
|
|
@@ -177,25 +112,14 @@ export class PlatformConnection {
|
|
|
177
112
|
}
|
|
178
113
|
}
|
|
179
114
|
|
|
180
|
-
/**
|
|
181
|
-
* Start periodic token refresh check
|
|
182
|
-
*/
|
|
183
115
|
private startTokenRefreshCheck(): void {
|
|
184
|
-
// Check every 24 hours
|
|
185
116
|
this.tokenRefreshInterval = setInterval(() => {
|
|
186
117
|
this.maybeRefreshToken()
|
|
187
118
|
}, 24 * 60 * 60 * 1000)
|
|
188
119
|
}
|
|
189
120
|
|
|
190
|
-
/**
|
|
191
|
-
* Start heartbeat to keep connection alive and refresh server-side TTL.
|
|
192
|
-
* Tracks missed pongs — if the server doesn't respond to MAX_MISSED_PONGS
|
|
193
|
-
* consecutive pings, the connection is considered dead and force-closed
|
|
194
|
-
* to trigger reconnection.
|
|
195
|
-
*/
|
|
196
121
|
private startHeartbeat(): void {
|
|
197
122
|
this.missedPongs = 0
|
|
198
|
-
// Send ping every 2 minutes (server TTL is 5 minutes)
|
|
199
123
|
this.heartbeatInterval = setInterval(() => this.heartbeatTick(), 2 * 60 * 1000)
|
|
200
124
|
}
|
|
201
125
|
|
|
@@ -217,9 +141,6 @@ export class PlatformConnection {
|
|
|
217
141
|
}
|
|
218
142
|
}
|
|
219
143
|
|
|
220
|
-
/**
|
|
221
|
-
* Stop heartbeat
|
|
222
|
-
*/
|
|
223
144
|
private stopHeartbeat(): void {
|
|
224
145
|
if (this.heartbeatInterval) {
|
|
225
146
|
clearInterval(this.heartbeatInterval)
|
|
@@ -227,9 +148,6 @@ export class PlatformConnection {
|
|
|
227
148
|
}
|
|
228
149
|
}
|
|
229
150
|
|
|
230
|
-
/**
|
|
231
|
-
* Stop periodic token refresh check
|
|
232
|
-
*/
|
|
233
151
|
private stopTokenRefreshCheck(): void {
|
|
234
152
|
if (this.tokenRefreshInterval) {
|
|
235
153
|
clearInterval(this.tokenRefreshInterval)
|
|
@@ -237,9 +155,6 @@ export class PlatformConnection {
|
|
|
237
155
|
}
|
|
238
156
|
}
|
|
239
157
|
|
|
240
|
-
/**
|
|
241
|
-
* Connect to platform WebSocket
|
|
242
|
-
*/
|
|
243
158
|
connect(): void {
|
|
244
159
|
this.isIntentionallyClosed = false
|
|
245
160
|
const name = basename(this.workingDirectory)
|
|
@@ -250,7 +165,6 @@ export class PlatformConnection {
|
|
|
250
165
|
const osType = type().toLowerCase()
|
|
251
166
|
const cpuArch = arch()
|
|
252
167
|
|
|
253
|
-
// Get auth token from credentials
|
|
254
168
|
const credentials = getCredentials()
|
|
255
169
|
const authToken = credentials?.token
|
|
256
170
|
|
|
@@ -260,8 +174,6 @@ export class PlatformConnection {
|
|
|
260
174
|
return
|
|
261
175
|
}
|
|
262
176
|
|
|
263
|
-
// Build URL params WITHOUT the auth token — token is sent post-connection
|
|
264
|
-
// to avoid leaking it in proxy logs, browser history, and server access logs
|
|
265
177
|
const params = new URLSearchParams({
|
|
266
178
|
name,
|
|
267
179
|
workingDirectory: this.workingDirectory,
|
|
@@ -271,7 +183,9 @@ export class PlatformConnection {
|
|
|
271
183
|
nodeVersion,
|
|
272
184
|
osType,
|
|
273
185
|
cpuArch,
|
|
274
|
-
|
|
186
|
+
cliVersion: CLI_VERSION,
|
|
187
|
+
capabilities: JSON.stringify({}),
|
|
188
|
+
startedAt: this.startedAt,
|
|
275
189
|
})
|
|
276
190
|
|
|
277
191
|
const wsUrl = `${this.platformUrl.replace(/^http/, 'ws')}/ws/client?${params}`
|
|
@@ -286,10 +200,9 @@ export class PlatformConnection {
|
|
|
286
200
|
return
|
|
287
201
|
}
|
|
288
202
|
|
|
289
|
-
// Connection timeout - if not connected within 10 seconds, show helpful error
|
|
290
203
|
const connectionTimeout = setTimeout(() => {
|
|
291
204
|
const state = this.ws?.readyState
|
|
292
|
-
if (this.ws && (state === 0 || state === undefined)) {
|
|
205
|
+
if (this.ws && (state === 0 || state === undefined)) {
|
|
293
206
|
console.error('\n❌ Connection timeout. The platform may have rejected your credentials.')
|
|
294
207
|
console.error(' Run `mstro login --force` to re-authenticate.\n')
|
|
295
208
|
this.ws.close()
|
|
@@ -299,14 +212,8 @@ export class PlatformConnection {
|
|
|
299
212
|
|
|
300
213
|
this.ws.onopen = () => {
|
|
301
214
|
clearTimeout(connectionTimeout)
|
|
302
|
-
// Platform WebSocket open — auth will follow
|
|
303
|
-
|
|
304
|
-
// Send auth token as first message instead of URL param
|
|
305
215
|
this.ws!.send(JSON.stringify({ type: 'auth', token: authToken }))
|
|
306
|
-
|
|
307
|
-
// Check if token needs refresh on connect
|
|
308
216
|
this.maybeRefreshToken()
|
|
309
|
-
// Start periodic refresh checks
|
|
310
217
|
this.startTokenRefreshCheck()
|
|
311
218
|
this.reconnectAttempts = 0
|
|
312
219
|
trackEvent(AnalyticsEvents.PLATFORM_CONNECTED)
|
|
@@ -321,7 +228,6 @@ export class PlatformConnection {
|
|
|
321
228
|
}
|
|
322
229
|
}
|
|
323
230
|
|
|
324
|
-
// Track if we ever successfully connected (received 'paired' message)
|
|
325
231
|
let everConnected = false
|
|
326
232
|
const originalOnConnected = this.callbacks.onConnected
|
|
327
233
|
this.callbacks.onConnected = (connectionId) => {
|
|
@@ -330,12 +236,10 @@ export class PlatformConnection {
|
|
|
330
236
|
}
|
|
331
237
|
|
|
332
238
|
this.ws.onclose = (event) => {
|
|
333
|
-
// Stop heartbeat on any close
|
|
334
239
|
this.stopHeartbeat()
|
|
335
240
|
this.isConnected = false
|
|
336
241
|
|
|
337
242
|
if (!this.isIntentionallyClosed) {
|
|
338
|
-
// Check if we were rejected due to auth (code 4001 or 1006 before ever connecting)
|
|
339
243
|
const isAuthFailure = event.code === 4001 ||
|
|
340
244
|
event.reason?.includes('Unauthorized') ||
|
|
341
245
|
(event.code === 1006 && !everConnected)
|
|
@@ -364,29 +268,21 @@ export class PlatformConnection {
|
|
|
364
268
|
case 'paired':
|
|
365
269
|
this.isConnected = true
|
|
366
270
|
this.connectionId = message.connectionId as string
|
|
367
|
-
// Connection status printed by onConnected callback
|
|
368
|
-
// Start heartbeat to keep server-side TTL refreshed
|
|
369
271
|
this.startHeartbeat()
|
|
370
272
|
this.callbacks.onConnected?.(message.connectionId as string)
|
|
371
273
|
break
|
|
372
|
-
|
|
373
274
|
case 'web_connected':
|
|
374
275
|
this.callbacks.onWebConnected?.()
|
|
375
276
|
trackEvent(AnalyticsEvents.WEB_CLIENT_CONNECTED)
|
|
376
277
|
break
|
|
377
|
-
|
|
378
278
|
case 'web_disconnected':
|
|
379
279
|
this.callbacks.onWebDisconnected?.()
|
|
380
280
|
trackEvent(AnalyticsEvents.WEB_CLIENT_DISCONNECTED)
|
|
381
281
|
break
|
|
382
|
-
|
|
383
282
|
case 'pong':
|
|
384
283
|
this.missedPongs = 0
|
|
385
284
|
break
|
|
386
|
-
|
|
387
285
|
default:
|
|
388
|
-
// Relay message from web to wsHandler
|
|
389
|
-
// These are messages like 'execute', 'initTab', 'autocomplete', etc.
|
|
390
286
|
this.callbacks.onRelayedMessage?.(message)
|
|
391
287
|
break
|
|
392
288
|
}
|
|
@@ -409,29 +305,18 @@ export class PlatformConnection {
|
|
|
409
305
|
}, delay)
|
|
410
306
|
}
|
|
411
307
|
|
|
412
|
-
/**
|
|
413
|
-
* Send message to platform (will be relayed to web if connected)
|
|
414
|
-
*/
|
|
415
308
|
send(message: unknown): void {
|
|
416
309
|
if (this.ws && this.ws.readyState === WebSocketImpl.OPEN) {
|
|
417
310
|
this.ws.send(JSON.stringify(message))
|
|
418
311
|
}
|
|
419
312
|
}
|
|
420
313
|
|
|
421
|
-
/**
|
|
422
|
-
* Check if connected to platform
|
|
423
|
-
*/
|
|
424
314
|
isConnectedToPlatform(): boolean {
|
|
425
315
|
return this.isConnected && this.ws?.readyState === WebSocketImpl.OPEN
|
|
426
316
|
}
|
|
427
317
|
|
|
428
|
-
/**
|
|
429
|
-
* Disconnect from platform
|
|
430
|
-
*/
|
|
431
318
|
disconnect(): void {
|
|
432
319
|
this.isIntentionallyClosed = true
|
|
433
|
-
|
|
434
|
-
// Stop heartbeat and token refresh checks
|
|
435
320
|
this.stopHeartbeat()
|
|
436
321
|
this.stopTokenRefreshCheck()
|
|
437
322
|
|