spck 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/.oxlintrc.json +49 -0
  2. package/LICENSE +21 -0
  3. package/README.md +631 -0
  4. package/bin/cli.js +20 -0
  5. package/bin/validate-cwd.js +41 -0
  6. package/dist/config/__tests__/config.test.d.ts +2 -0
  7. package/dist/config/__tests__/config.test.js +262 -0
  8. package/dist/config/__tests__/credentials.test.d.ts +2 -0
  9. package/dist/config/__tests__/credentials.test.js +360 -0
  10. package/dist/config/config.d.ts +33 -0
  11. package/dist/config/config.js +185 -0
  12. package/dist/config/credentials.d.ts +75 -0
  13. package/dist/config/credentials.js +259 -0
  14. package/dist/config/server-selection.d.ts +40 -0
  15. package/dist/config/server-selection.js +130 -0
  16. package/dist/connection/__tests__/firebase-auth.test.d.ts +2 -0
  17. package/dist/connection/__tests__/firebase-auth.test.js +96 -0
  18. package/dist/connection/__tests__/hmac.test.d.ts +2 -0
  19. package/dist/connection/__tests__/hmac.test.js +372 -0
  20. package/dist/connection/auth.d.ts +13 -0
  21. package/dist/connection/auth.js +91 -0
  22. package/dist/connection/firebase-auth.d.ts +40 -0
  23. package/dist/connection/firebase-auth.js +429 -0
  24. package/dist/connection/hmac.d.ts +24 -0
  25. package/dist/connection/hmac.js +109 -0
  26. package/dist/i18n/index.d.ts +25 -0
  27. package/dist/i18n/index.js +101 -0
  28. package/dist/i18n/locales/en.json +313 -0
  29. package/dist/i18n/locales/es.json +302 -0
  30. package/dist/i18n/locales/fr.json +302 -0
  31. package/dist/i18n/locales/id.json +302 -0
  32. package/dist/i18n/locales/ja.json +302 -0
  33. package/dist/i18n/locales/ko.json +302 -0
  34. package/dist/i18n/locales/locales/en.json +309 -0
  35. package/dist/i18n/locales/locales/es.json +302 -0
  36. package/dist/i18n/locales/locales/fr.json +302 -0
  37. package/dist/i18n/locales/locales/id.json +302 -0
  38. package/dist/i18n/locales/locales/ja.json +302 -0
  39. package/dist/i18n/locales/locales/ko.json +302 -0
  40. package/dist/i18n/locales/locales/pt.json +302 -0
  41. package/dist/i18n/locales/locales/zh-Hans.json +302 -0
  42. package/dist/i18n/locales/pt.json +302 -0
  43. package/dist/i18n/locales/zh-Hans.json +302 -0
  44. package/dist/index.d.ts +25 -0
  45. package/dist/index.js +493 -0
  46. package/dist/proxy/ProxyClient.d.ts +125 -0
  47. package/dist/proxy/ProxyClient.js +781 -0
  48. package/dist/proxy/ProxySocketWrapper.d.ts +43 -0
  49. package/dist/proxy/ProxySocketWrapper.js +98 -0
  50. package/dist/proxy/__tests__/ProxyClient.test.d.ts +2 -0
  51. package/dist/proxy/__tests__/ProxyClient.test.js +445 -0
  52. package/dist/proxy/__tests__/ProxySocketWrapper.test.d.ts +2 -0
  53. package/dist/proxy/__tests__/ProxySocketWrapper.test.js +190 -0
  54. package/dist/proxy/__tests__/handshake-validation.test.d.ts +2 -0
  55. package/dist/proxy/__tests__/handshake-validation.test.js +282 -0
  56. package/dist/proxy/__tests__/token-refresh-race.test.d.ts +14 -0
  57. package/dist/proxy/__tests__/token-refresh-race.test.js +173 -0
  58. package/dist/proxy/chunking.d.ts +53 -0
  59. package/dist/proxy/chunking.js +127 -0
  60. package/dist/proxy/handshake-validation.d.ts +21 -0
  61. package/dist/proxy/handshake-validation.js +49 -0
  62. package/dist/rpc/__tests__/router.test.d.ts +2 -0
  63. package/dist/rpc/__tests__/router.test.js +262 -0
  64. package/dist/rpc/router.d.ts +37 -0
  65. package/dist/rpc/router.js +132 -0
  66. package/dist/services/BrowserProxyService.d.ts +13 -0
  67. package/dist/services/BrowserProxyService.js +139 -0
  68. package/dist/services/FilesystemService.d.ts +99 -0
  69. package/dist/services/FilesystemService.js +742 -0
  70. package/dist/services/GitService.d.ts +243 -0
  71. package/dist/services/GitService.js +1439 -0
  72. package/dist/services/SearchService.d.ts +93 -0
  73. package/dist/services/SearchService.js +670 -0
  74. package/dist/services/TerminalService.d.ts +62 -0
  75. package/dist/services/TerminalService.js +337 -0
  76. package/dist/services/__tests__/BrowserProxyService.test.d.ts +2 -0
  77. package/dist/services/__tests__/BrowserProxyService.test.js +145 -0
  78. package/dist/services/__tests__/FilesystemService.test.d.ts +2 -0
  79. package/dist/services/__tests__/FilesystemService.test.js +609 -0
  80. package/dist/services/__tests__/GitService.test.d.ts +2 -0
  81. package/dist/services/__tests__/GitService.test.js +953 -0
  82. package/dist/services/__tests__/SearchService.test.d.ts +2 -0
  83. package/dist/services/__tests__/SearchService.test.js +384 -0
  84. package/dist/services/__tests__/TerminalService.test.d.ts +2 -0
  85. package/dist/services/__tests__/TerminalService.test.js +513 -0
  86. package/dist/setup/wizard.d.ts +10 -0
  87. package/dist/setup/wizard.js +172 -0
  88. package/dist/types.d.ts +196 -0
  89. package/dist/types.js +44 -0
  90. package/dist/utils/__tests__/gitignore.test.d.ts +2 -0
  91. package/dist/utils/__tests__/gitignore.test.js +127 -0
  92. package/dist/utils/gitignore.d.ts +24 -0
  93. package/dist/utils/gitignore.js +77 -0
  94. package/dist/utils/logger.d.ts +96 -0
  95. package/dist/utils/logger.js +456 -0
  96. package/dist/utils/project-dir.d.ts +51 -0
  97. package/dist/utils/project-dir.js +191 -0
  98. package/dist/utils/ripgrep.d.ts +34 -0
  99. package/dist/utils/ripgrep.js +148 -0
  100. package/dist/utils/tool-detection.d.ts +17 -0
  101. package/dist/utils/tool-detection.js +126 -0
  102. package/dist/watcher/FileWatcher.d.ts +10 -0
  103. package/dist/watcher/FileWatcher.js +42 -0
  104. package/package.json +70 -0
  105. package/src/config/__tests__/config.test.ts +318 -0
  106. package/src/config/__tests__/credentials.test.ts +494 -0
  107. package/src/config/config.ts +206 -0
  108. package/src/config/credentials.ts +302 -0
  109. package/src/config/server-selection.ts +150 -0
  110. package/src/connection/__tests__/firebase-auth.test.ts +121 -0
  111. package/src/connection/__tests__/hmac.test.ts +509 -0
  112. package/src/connection/auth.ts +140 -0
  113. package/src/connection/firebase-auth.ts +504 -0
  114. package/src/connection/hmac.ts +139 -0
  115. package/src/i18n/index.ts +119 -0
  116. package/src/i18n/locales/en.json +313 -0
  117. package/src/i18n/locales/es.json +302 -0
  118. package/src/i18n/locales/fr.json +302 -0
  119. package/src/i18n/locales/id.json +302 -0
  120. package/src/i18n/locales/ja.json +302 -0
  121. package/src/i18n/locales/ko.json +302 -0
  122. package/src/i18n/locales/pt.json +302 -0
  123. package/src/i18n/locales/zh-Hans.json +302 -0
  124. package/src/index.ts +542 -0
  125. package/src/proxy/ProxyClient.ts +968 -0
  126. package/src/proxy/ProxySocketWrapper.ts +113 -0
  127. package/src/proxy/__tests__/ProxyClient.test.ts +575 -0
  128. package/src/proxy/__tests__/ProxySocketWrapper.test.ts +251 -0
  129. package/src/proxy/__tests__/handshake-validation.test.ts +367 -0
  130. package/src/proxy/chunking.ts +162 -0
  131. package/src/proxy/handshake-validation.ts +64 -0
  132. package/src/rpc/__tests__/router.test.ts +400 -0
  133. package/src/rpc/router.ts +183 -0
  134. package/src/services/BrowserProxyService.ts +179 -0
  135. package/src/services/FilesystemService.ts +841 -0
  136. package/src/services/GitService.ts +1639 -0
  137. package/src/services/SearchService.ts +809 -0
  138. package/src/services/TerminalService.ts +413 -0
  139. package/src/services/__tests__/BrowserProxyService.test.ts +155 -0
  140. package/src/services/__tests__/FilesystemService.test.ts +1002 -0
  141. package/src/services/__tests__/GitService.test.ts +1552 -0
  142. package/src/services/__tests__/SearchService.test.ts +484 -0
  143. package/src/services/__tests__/TerminalService.test.ts +702 -0
  144. package/src/setup/wizard.ts +242 -0
  145. package/src/types/fossil-delta.d.ts +4 -0
  146. package/src/types.ts +287 -0
  147. package/src/utils/__tests__/gitignore.test.ts +174 -0
  148. package/src/utils/gitignore.ts +91 -0
  149. package/src/utils/logger.ts +578 -0
  150. package/src/utils/project-dir.ts +218 -0
  151. package/src/utils/ripgrep.ts +180 -0
  152. package/src/utils/tool-detection.ts +141 -0
  153. package/src/watcher/FileWatcher.ts +53 -0
  154. package/tsconfig.json +24 -0
  155. package/vitest.config.ts +19 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Lightweight i18n system for the CLI
3
+ * No external dependencies — uses JSON locale files with dot-path keys and {{variable}} interpolation
4
+ */
5
+
6
+ import { readFileSync } from 'fs';
7
+ import { dirname, join } from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ import osLocale from 'os-locale';
10
+
11
+ type Translations = Record<string, any>;
12
+
13
+ // Support both CJS (ts-jest) and ESM (runtime) contexts
14
+ // eslint-disable-next-line no-eval
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const localesDir = join(__dirname, 'locales');
17
+
18
+ function loadLocale(file: string): Translations {
19
+ try {
20
+ return JSON.parse(readFileSync(join(localesDir, file), 'utf-8'));
21
+ } catch {
22
+ return {};
23
+ }
24
+ }
25
+
26
+ const en = loadLocale('en.json');
27
+
28
+ const locales: Record<string, Translations> = {
29
+ en,
30
+ es: loadLocale('es.json'),
31
+ fr: loadLocale('fr.json'),
32
+ id: loadLocale('id.json'),
33
+ ja: loadLocale('ja.json'),
34
+ ko: loadLocale('ko.json'),
35
+ pt: loadLocale('pt.json'),
36
+ 'zh-Hans': loadLocale('zh-Hans.json'),
37
+ };
38
+
39
+ const SUPPORTED_LOCALES = Object.keys(locales);
40
+
41
+ let currentLocale = 'en';
42
+
43
+ /**
44
+ * Map system locale string (e.g. "ja_JP.UTF-8") to a supported locale code
45
+ */
46
+ function mapLocale(raw: string): string {
47
+ // Normalize: lowercase, replace - with _
48
+ const normalized = raw.toLowerCase().replace(/-/g, '_');
49
+
50
+ // zh_cn / zh_sg → zh-Hans
51
+ if (normalized.startsWith('zh_cn') || normalized.startsWith('zh_sg') || normalized === 'zh_hans' || normalized.startsWith('zh_hans')) {
52
+ return 'zh-Hans';
53
+ }
54
+
55
+ // Extract language code (before _ or .)
56
+ const lang = normalized.split(/[_.]/)[0];
57
+
58
+ if (SUPPORTED_LOCALES.includes(lang)) {
59
+ return lang;
60
+ }
61
+
62
+ return 'en';
63
+ }
64
+
65
+ /**
66
+ * Detect locale using os-locale (reads LC_ALL, LANG, LANGUAGE, and OS-specific APIs)
67
+ */
68
+ export function detectLocale(): string {
69
+ const raw = osLocale();
70
+ currentLocale = mapLocale(raw);
71
+ return currentLocale;
72
+ }
73
+
74
+ /**
75
+ * Set locale explicitly (e.g. from --locale CLI flag)
76
+ */
77
+ export function setLocale(locale: string): void {
78
+ currentLocale = mapLocale(locale);
79
+ }
80
+
81
+ /**
82
+ * Get the current locale
83
+ */
84
+ export function getLocale(): string {
85
+ return currentLocale;
86
+ }
87
+
88
+ /**
89
+ * Resolve a dot-path key from a translations object
90
+ * e.g. resolve('tools.gitDetected', translations) → translations.tools.gitDetected
91
+ */
92
+ function resolve(key: string, obj: Translations): string | undefined {
93
+ const parts = key.split('.');
94
+ let current: any = obj;
95
+ for (const part of parts) {
96
+ if (current == null || typeof current !== 'object') return undefined;
97
+ current = current[part];
98
+ }
99
+ return typeof current === 'string' ? current : undefined;
100
+ }
101
+
102
+ /**
103
+ * Translate a key with optional parameter interpolation
104
+ *
105
+ * @param key - Dot-path key (e.g. 'tools.gitDetected')
106
+ * @param params - Optional parameters for {{variable}} interpolation
107
+ * @returns Translated string, falling back to English, then the key itself
108
+ */
109
+ export function t(key: string, params?: Record<string, string | number>): string {
110
+ let text = resolve(key, locales[currentLocale]) ?? resolve(key, en) ?? key;
111
+
112
+ if (params) {
113
+ for (const [name, value] of Object.entries(params)) {
114
+ text = text.replace(new RegExp(`\\{\\{${name}\\}\\}`, 'g'), String(value));
115
+ }
116
+ }
117
+
118
+ return text;
119
+ }
@@ -0,0 +1,313 @@
1
+ {
2
+ "app": {
3
+ "title": "Spck CLI",
4
+ "goodbye": "Goodbye!"
5
+ },
6
+ "config": {
7
+ "loaded": "Configuration loaded",
8
+ "notFound": "No configuration found. Running setup wizard...",
9
+ "corrupted": "Configuration file is corrupted",
10
+ "corruptedRunSetup": "Running setup wizard to recreate...",
11
+ "fileNotFound": "Configuration file not found: {{path}}",
12
+ "fileNotFoundHint": "Running setup wizard to create initial configuration...",
13
+ "fileCorrupted": "Configuration file is corrupted: {{path}}",
14
+ "fileCorruptedHint": "Will run setup wizard to recreate...",
15
+ "saved": "Configuration saved successfully!"
16
+ },
17
+ "auth": {
18
+ "title": "Firebase Authentication",
19
+ "startingCallback": "Starting local callback server on port {{port}}...",
20
+ "openingBrowser": "Opening browser for authentication...",
21
+ "couldNotOpenBrowser": "Could not open browser automatically: {{message}}",
22
+ "manualAuthHint": "If browser doesn't open, authenticate manually:",
23
+ "visitUrl": "Or visit: {{url}}",
24
+ "waiting": "Waiting for authentication (timeout: 10 minutes)...",
25
+ "success": "Authentication successful!",
26
+ "userId": "User ID: {{userId}}",
27
+ "credentialsLoaded": "Firebase credentials loaded",
28
+ "generatingToken": "Generating fresh Firebase ID token...",
29
+ "noRefreshToken": "No refresh token available. Re-authentication required.",
30
+ "refreshTokenExpired": "Refresh token expired or invalid. Re-authentication required.",
31
+ "tokenRefreshError": "Token refresh error: {{message}}",
32
+ "tokenRefreshFailed": "Token refresh failed. Re-authentication required."
33
+ },
34
+ "tools": {
35
+ "title": "Tool Detection",
36
+ "gitForceDisabled": "Git force-disabled (development mode)",
37
+ "gitDetected": "Git detected: {{version}}",
38
+ "gitDetectedShort": "Git detected",
39
+ "gitNotDetected": "Git not detected",
40
+ "gitDisabledHint": "Git features will be disabled in this session.",
41
+ "gitInstallHint": "Install Git to enable version control features:",
42
+ "ripgrepForceDisabled": "Ripgrep force-disabled (development mode)",
43
+ "ripgrepDetected": "Ripgrep detected: {{version}}",
44
+ "ripgrepDetectedShort": "Ripgrep detected",
45
+ "ripgrepNotDetected": "Ripgrep not detected",
46
+ "ripgrepDisabledHint": "Fast search features will be disabled in this session.",
47
+ "ripgrepInstallHint": "Install ripgrep for high-performance code search:",
48
+ "gitInstallUrl": "https://git-scm.com/downloads",
49
+ "ripgrepInstallUrl": "https://github.com/BurntSushi/ripgrep#installation"
50
+ },
51
+ "features": {
52
+ "title": "Available Features",
53
+ "filesystem": "Filesystem operations",
54
+ "gitEnabled": "Git version control",
55
+ "gitDisabled": "Git version control (git not installed)",
56
+ "searchFast": "Fast search (ripgrep)",
57
+ "searchBasic": "Basic search (ripgrep not installed)",
58
+ "terminalEnabled": "Terminal service",
59
+ "terminalDisabled": "Terminal service (disabled in config)",
60
+ "browserProxyEnabled": "Browser proxy service",
61
+ "browserProxyDisabled": "Browser proxy service (disabled in config)",
62
+ "securityTitle": "Security Mode",
63
+ "userAuthEnabled": "User Authentication: ENABLED",
64
+ "userAuthEnabledHint1": "Requires Firebase authentication for all connections",
65
+ "userAuthEnabledHint2": "Adds user identity verification layer",
66
+ "userAuthEnabledHint3": "Compatible with Spck Editor (not Lite)",
67
+ "userAuthDisabled": "User Authentication: DISABLED",
68
+ "userAuthDisabledHint1": "Connections protected by secret signing key only",
69
+ "userAuthDisabledHint2": "Lower latency, no Firebase auth required",
70
+ "userAuthDisabledHint3": "Compatible with Spck Editor Lite"
71
+ },
72
+ "server": {
73
+ "selectingBest": "Selecting best relay server...",
74
+ "checkingLatency": "Checking server latency...",
75
+ "selected": "Selected server: {{label}} ({{url}}) - {{ping}}ms",
76
+ "allUnreachable": "All servers unreachable, using default: {{url}}",
77
+ "usingOverride": "Using server override: {{url}}",
78
+ "usingSaved": "Using saved server: {{url}}",
79
+ "failedSelect": "Failed to select relay server: {{message}}",
80
+ "usingDefault": "Using default: {{url}}",
81
+ "unreachable": "unreachable"
82
+ },
83
+ "connection": {
84
+ "title": "Connecting to Relay Server",
85
+ "relayServer": "Relay server: {{server}}",
86
+ "scanQR": "Scan this QR code with Spck Editor mobile app:",
87
+ "clientId": "Client ID: {{id}}",
88
+ "secret": "Secret: {{secret}}",
89
+ "name": "Name: {{name}}",
90
+ "relayServerLabel": "Relay server: {{server}}",
91
+ "relayServerMismatch": "IMPORTANT: The client must select the same relay server",
92
+ "relayServerMismatchHint": "({{server}}) in Spck Editor to connect.",
93
+ "existingFound": "Existing connection found",
94
+ "connectedAt": "Connected at: {{date}}",
95
+ "noExisting": "No existing connection found. Connecting to proxy...",
96
+ "tokenExpired": "Server token expired. Reconnecting...",
97
+ "settingsCorrupted": "Connection settings corrupted, will reconnect to proxy...",
98
+ "reusingSecret": "Reusing existing secret for clientId",
99
+ "generatedSecret": "Generated new secret for clientId",
100
+ "newDevice": "New device connecting: {{deviceId}}",
101
+ "newDeviceWarning": "This is the first time this device has connected.",
102
+ "newDeviceCompromised": "If you did not initiate this connection, your credentials may be compromised.",
103
+ "userVerifying": "Requesting user verification...",
104
+ "userVerified": "User verified for {{deviceId}}: {{userId}}",
105
+ "userVerifyFailed": "User verification failed for {{deviceId}}: {{message}}",
106
+ "userVerifyOptional": "Continuing anyway (verification is optional)",
107
+ "protocolNegotiated": "Protocol v{{version}} negotiated with {{deviceId}}",
108
+ "protocolUnsupported": "Unsupported protocol version {{version}} from {{deviceId}}. This CLI only supports protocol v1. An upgrade is required: update your client/library (and this CLI, if applicable) to the latest version so protocol versions match. If you installed the CLI globally, run: npm i -g spck@latest",
109
+ "chunkingMessage": "Chunking large {{event}} message: {{chunks}} chunks (~{{size}}MB) for {{deviceId}}",
110
+ "disconnectedFromProxy": "Disconnected from proxy: {{reason}}",
111
+ "serverTerminated": "Server terminated connection. Exiting...",
112
+ "attemptingReconnect": "Attempting to reconnect...",
113
+ "reconnectAttempt": "Reconnection attempt {{attempt}}/5...",
114
+ "reconnected": "Reconnected after {{attempts}} attempts",
115
+ "reconnectFailed": "Failed to reconnect after 5 attempts.",
116
+ "exiting": "Exiting...",
117
+ "shuttingDown": "Shutting down gracefully...",
118
+ "killTimeout": "Kill acknowledgment timeout, forcing disconnect",
119
+ "gracefulDisconnect": "Gracefully disconnected from proxy",
120
+ "connectError": "Connection error: {{message}}",
121
+ "connectErrorNamespace": "Namespace: /listen",
122
+ "connectErrorType": "Error type: {{type}}",
123
+ "connectFailed": "Failed to connect to relay server",
124
+ "connectFailedUrl": "URL: {{url}}/listen",
125
+ "connectFailedError": "Error: {{message}}",
126
+ "connectFailedCauses": "Possible causes:",
127
+ "connectFailedCause1": "- Server is not reachable (check your internet connection)",
128
+ "connectFailedCause2": "- Network/firewall blocking connection",
129
+ "unknownMessageType": "Unknown message type from {{deviceId}}",
130
+ "errorHandlingMessage": "Error handling message from {{deviceId}}",
131
+ "unknownHandshakeType": "Unknown handshake message type: {{type}}",
132
+ "rejectingUnauthenticated": "Rejecting {{event}} from unauthenticated connection: {{deviceId}}",
133
+ "rejectingUserVerification": "Rejecting protocol_selected - user verification required but not completed: {{deviceId}}",
134
+ "invalidRpcMessage": "Invalid RPC message from {{deviceId}}",
135
+ "unhandledError": "Unhandled error in handleError:",
136
+ "freeTierNotice": "Free account: {{used}} / {{limit}} min used today ({{remaining}} min remaining)",
137
+ "freeTierUpgrade": "Upgrade for unlimited CLI access."
138
+ },
139
+ "multipleConnection": {
140
+ "detected": "MULTIPLE CONNECTION ATTEMPT DETECTED!",
141
+ "existingCount": "Existing connections: {{count}}",
142
+ "newConnectionId": "New connection ID: {{id}}",
143
+ "rejectedHint": "For security reasons, new connections are rejected by default.",
144
+ "restartHint": "If you want to allow multiple connections, restart the CLI.",
145
+ "compromiseWarning": "If you did not initiate this connection, your client ID",
146
+ "compromiseHint": "may have been compromised. Consider regenerating it."
147
+ },
148
+ "proxyError": {
149
+ "error": "Proxy error: {{message}}",
150
+ "tokenExpiredTimeout": "Your access token has expired or timed out.",
151
+ "tokenExpiredHint": "Please try again or re-authenticate with: spck auth login",
152
+ "tokenRevoked": "Your login token has been revoked.",
153
+ "tokenRevokedHint": "Please re-authenticate: spck auth logout && spck auth login",
154
+ "privacyConsent": "Privacy policy consent required.",
155
+ "privacyConsentHint1": "Please accept the privacy policy in the Spck Editor app",
156
+ "privacyConsentHint2": "under Account Settings to use this feature.",
157
+ "accountDeleting": "Your account is being deleted.",
158
+ "accountDeletingHint": "Please wait 72 hours before trying again.",
159
+ "accountBanned": "This account has been banned.",
160
+ "accountBannedHint1": "Your account has been banned for violation of the",
161
+ "accountBannedHint2": "Terms of Service agreement.",
162
+ "subscriptionCheckFailed": "Unable to verify subscription status.",
163
+ "subscriptionCheckFailedHint": "This may be a temporary issue. Please try again later.",
164
+ "subscriptionRequired": "This feature requires a paid subscription.",
165
+ "subscriptionRequiredHint": "Open the Spck Editor app to upgrade to Supporter or Gold.",
166
+ "maxConnections": "Maximum of {{max}} CLI connections reached.",
167
+ "maxConnectionsHint": "Close other CLI instances and try again.",
168
+ "duplicateClientId": "A CLI with this client ID is already connected.",
169
+ "duplicateHint1": "This can happen if:",
170
+ "duplicateHint2": "- Another CLI instance is still running with the same connection",
171
+ "duplicateHint3": "- A previous connection did not properly disconnect",
172
+ "duplicateHint4": "Please:",
173
+ "duplicateHint5": "1. Close any other running CLI instances",
174
+ "duplicateHint6": "2. Wait a few seconds for the previous connection to timeout",
175
+ "duplicateHint7": "3. Try connecting again",
176
+ "firebaseExpiredRefreshFailed": "Firebase token expired and refresh failed.",
177
+ "firebaseExpiredRefreshFailedHint": "Please re-authenticate: spck auth login",
178
+ "firebaseExpired": "Firebase token expired.",
179
+ "firebaseExpiredHint": "Please re-authenticate: spck auth login",
180
+ "firebaseInvalid": "Firebase token is invalid (not expired).",
181
+ "firebaseInvalidHint1": "The token may be corrupted or from a different account.",
182
+ "firebaseInvalidHint2": "Please re-authenticate: spck auth login",
183
+ "firebaseTokenExpiring": "Firebase token expired. Attempting to refresh...",
184
+ "tokenRefreshFailed": "Token refresh failed: {{message}}",
185
+ "dailyLimitExceeded": "Daily free tier limit of 30 minutes has been reached.",
186
+ "dailyLimitReset": "Limit resets in {{time}}.",
187
+ "dailyLimitExceededHint": "Open the Spck Editor app to upgrade to Supporter or Gold for unlimited CLI access.",
188
+ "defaultError": "A problem occurred when verifying your subscription."
189
+ },
190
+ "errors": {
191
+ "permissionError": "Permission Error: Cannot write to required directory",
192
+ "permissionPath": "Path: {{path}}",
193
+ "permissionOperation": "Operation: {{operation}}",
194
+ "permissionFix": "Please fix permissions:",
195
+ "permissionFixCmd1": "chmod 700 ~/.spck-editor",
196
+ "permissionFixCmd2": "chmod 600 ~/.spck-editor/.credentials.json",
197
+ "permissionFixHint": "Or ensure your user has write access to the home directory.",
198
+ "diskFull": "Disk Full: No space left on device",
199
+ "diskFullHint": "Please free up disk space and try again.",
200
+ "cannotConnect": "Cannot connect to proxy server",
201
+ "cannotConnectError": "Error: {{message}}",
202
+ "cannotConnectCauses": "Possible causes:",
203
+ "cannotConnectCause1": "- Proxy server is down",
204
+ "cannotConnectCause2": "- Network connection issue",
205
+ "cannotConnectCause3": "- Incorrect proxy URL in config",
206
+ "cannotConnectHint": "Please check the proxy URL and try again.",
207
+ "failedToStart": "Failed to start proxy client: {{message}}",
208
+ "rootNotFound": "Root directory not found: {{path}}",
209
+ "rootNotFoundHint": "Please ensure the directory exists and is accessible, or run setup wizard:",
210
+ "rootNotFoundCmd": "spck --setup",
211
+ "uncaughtException": "Uncaught exception: {{message}}",
212
+ "unhandledRejection": "Unhandled rejection: {{message}}",
213
+ "shutdownError": "Error during shutdown: {{message}}",
214
+ "cliError": "Error: {{message}}",
215
+ "cliErrorHint": "Run with --help to see available commands and options."
216
+ },
217
+ "logout": {
218
+ "title": "Logout",
219
+ "clearedCredentials": "Cleared user credentials",
220
+ "removed": "Removed: {{path}}",
221
+ "clearedSettings": "Cleared connection settings",
222
+ "noCredentials": "No credentials or connection settings found",
223
+ "notLoggedIn": "You are not currently logged in.",
224
+ "success": "Successfully logged out!",
225
+ "runAgain": "Run the CLI again to re-authenticate."
226
+ },
227
+ "account": {
228
+ "title": "Account Information",
229
+ "credentialsCorrupted": "Credentials file is corrupted.",
230
+ "credentialsCorruptedHint1": "Please logout and re-authenticate:",
231
+ "credentialsCorruptedHint2": "spck --logout",
232
+ "notLoggedIn": "Not currently logged in.",
233
+ "notLoggedInHint1": "Run the CLI to authenticate:",
234
+ "notLoggedInHint2": "spck",
235
+ "fetching": "Fetching account information...",
236
+ "decodeFailed": "Failed to decode authentication token",
237
+ "loggedIn": "Logged In",
238
+ "userId": "User ID: {{userId}}",
239
+ "email": "Email: {{email}}",
240
+ "verified": "Verified: {{status}}",
241
+ "yes": "Yes",
242
+ "no": "No",
243
+ "tokenExpires": "Token expires: {{date}}",
244
+ "timeRemaining": "Time remaining: {{hours}}h {{minutes}}m",
245
+ "subscription": "Subscription",
246
+ "status": "Status: {{status}}",
247
+ "plan": "Plan: {{plan}}",
248
+ "premium": "Premium: {{status}}",
249
+ "fetchFailed": "Failed to retrieve account information",
250
+ "fetchFailedError": "Error: {{message}}",
251
+ "permissionDenied": "Permission denied accessing credentials file",
252
+ "permissionHint1": "Please check file permissions:",
253
+ "permissionHint2": "chmod 600 ~/.spck-editor/.credentials.json",
254
+ "networkError": "Network connection error",
255
+ "networkHint": "Please check your internet connection"
256
+ },
257
+ "credentials": {
258
+ "corrupted": "Credentials file is corrupted: {{path}}",
259
+ "corruptedHint": "Will trigger re-authentication...",
260
+ "settingsCorrupted": "Connection settings file is corrupted: {{path}}",
261
+ "settingsCorruptedHint": "Will reconnect to proxy..."
262
+ },
263
+ "projectDir": {
264
+ "configured": "Project directory configured",
265
+ "directory": "Directory: {{path}}",
266
+ "configLink": "Config: {{symlink}} -> {{dataPath}}"
267
+ },
268
+ "setup": {
269
+ "title": "Spck Networking CLI - Initial Setup",
270
+ "description1": "This wizard will help you configure the Spck Networking CLI.",
271
+ "description2": "The CLI connects to a proxy server to enable remote access",
272
+ "description3": "to your local filesystem, git, and terminal.",
273
+ "projectConfig": "Project Configuration",
274
+ "rootDirPrompt": "Root directory to serve [{{default}}]: ",
275
+ "terminalConfig": "Terminal Configuration",
276
+ "terminalDescription": "Terminal service allows remote shell access to your machine.",
277
+ "terminalPrompt": "Enable terminal service? [Y/n]: ",
278
+ "advancedTerminalPrompt": "Configure advanced terminal settings? [y/N]: ",
279
+ "maxBufferPrompt": "Maximum buffer lines (terminal history) [{{default}}]: ",
280
+ "maxBufferHint": "(Larger buffer stores more history but may slow synchronization)",
281
+ "maxTerminalsPrompt": "Maximum terminal processes [{{default}}]: ",
282
+ "browserProxyConfig": "Browser Proxy Configuration",
283
+ "browserProxyDescription": "Browser proxy allows Spck Editor to open a live preview of your local dev server inside the browser.",
284
+ "browserProxyPrompt": "Enable browser proxy service? [Y/n]: ",
285
+ "securityConfig": "Security Configuration",
286
+ "securityDescription1": "Additional user authentication adds an extra security layer",
287
+ "securityDescription2": "by requiring the client to verify their Firebase identity.",
288
+ "securityDescription3": "This increases initial connection time by ~3-15 seconds.",
289
+ "securityDocsHint": "Learn more: {{url}}",
290
+ "securityPrompt": "Enable additional user authentication? [y/N]: ",
291
+ "gitConfig": "Git Configuration",
292
+ "gitignoreDetected": "A .gitignore file was detected in your project directory.",
293
+ "gitignoreRecommend1": "It is recommended to add .spck-editor/ to .gitignore to prevent",
294
+ "gitignoreRecommend2": "accidentally committing the directory to version control.",
295
+ "gitignorePrompt": "Add .spck-editor/ to .gitignore? [Y/n]: ",
296
+ "gitignoreAdded": "Added .spck-editor/ to .gitignore",
297
+ "gitignoreFailed": "Failed to update .gitignore: {{message}}",
298
+ "gitignoreManualHint": "You can manually add .spck-editor/ to your .gitignore file.",
299
+ "setupFailed": "Setup failed: {{message}}",
300
+ "configSummary": "Configuration summary:",
301
+ "summaryName": "Server name: {{name}}",
302
+ "summaryNameNotSet": "Not set",
303
+ "summaryRoot": "Root directory: {{root}}",
304
+ "summaryTerminal": "Terminal service: {{status}}",
305
+ "summaryEnabled": "Enabled",
306
+ "summaryDisabled": "Disabled",
307
+ "summaryMaxBuffer": "- Max buffer lines: {{value}}",
308
+ "summaryMaxProcesses": "- Max processes: {{value}}",
309
+ "summaryUserAuth": "User authentication: {{status}}",
310
+ "summaryBrowserProxy": "Browser proxy: {{status}}",
311
+ "received": "Received {{signal}}"
312
+ }
313
+ }