aios-core 4.2.13 → 4.2.15

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 (95) hide show
  1. package/.aios-core/core/code-intel/helpers/dev-helper.js +206 -0
  2. package/.aios-core/core/registry/registry-schema.json +166 -166
  3. package/.aios-core/core/synapse/diagnostics/collectors/hook-collector.js +3 -3
  4. package/.aios-core/data/entity-registry.yaml +27 -0
  5. package/.aios-core/development/scripts/approval-workflow.js +642 -642
  6. package/.aios-core/development/scripts/backup-manager.js +606 -606
  7. package/.aios-core/development/scripts/branch-manager.js +389 -389
  8. package/.aios-core/development/scripts/code-quality-improver.js +1311 -1311
  9. package/.aios-core/development/scripts/commit-message-generator.js +849 -849
  10. package/.aios-core/development/scripts/conflict-resolver.js +674 -674
  11. package/.aios-core/development/scripts/dependency-analyzer.js +637 -637
  12. package/.aios-core/development/scripts/diff-generator.js +351 -351
  13. package/.aios-core/development/scripts/elicitation-engine.js +384 -384
  14. package/.aios-core/development/scripts/elicitation-session-manager.js +299 -299
  15. package/.aios-core/development/scripts/git-wrapper.js +461 -461
  16. package/.aios-core/development/scripts/manifest-preview.js +244 -244
  17. package/.aios-core/development/scripts/metrics-tracker.js +775 -775
  18. package/.aios-core/development/scripts/modification-validator.js +554 -554
  19. package/.aios-core/development/scripts/pattern-learner.js +1224 -1224
  20. package/.aios-core/development/scripts/performance-analyzer.js +757 -757
  21. package/.aios-core/development/scripts/refactoring-suggester.js +1138 -1138
  22. package/.aios-core/development/scripts/rollback-handler.js +530 -530
  23. package/.aios-core/development/scripts/security-checker.js +358 -358
  24. package/.aios-core/development/scripts/template-engine.js +239 -239
  25. package/.aios-core/development/scripts/template-validator.js +278 -278
  26. package/.aios-core/development/scripts/test-generator.js +843 -843
  27. package/.aios-core/development/scripts/transaction-manager.js +589 -589
  28. package/.aios-core/development/scripts/usage-tracker.js +673 -673
  29. package/.aios-core/development/scripts/validate-filenames.js +226 -226
  30. package/.aios-core/development/scripts/version-tracker.js +526 -526
  31. package/.aios-core/development/scripts/yaml-validator.js +396 -396
  32. package/.aios-core/development/tasks/build-autonomous.md +10 -4
  33. package/.aios-core/development/tasks/create-service.md +23 -0
  34. package/.aios-core/development/tasks/dev-develop-story.md +12 -6
  35. package/.aios-core/development/tasks/dev-suggest-refactoring.md +7 -1
  36. package/.aios-core/development/tasks/publish-npm.md +3 -3
  37. package/.aios-core/hooks/unified/README.md +1 -1
  38. package/.aios-core/install-manifest.yaml +65 -61
  39. package/.aios-core/manifests/schema/manifest-schema.json +190 -190
  40. package/.aios-core/product/templates/component-react-tmpl.tsx +98 -98
  41. package/.aios-core/product/templates/engine/schemas/adr.schema.json +102 -102
  42. package/.aios-core/product/templates/engine/schemas/dbdr.schema.json +205 -205
  43. package/.aios-core/product/templates/engine/schemas/epic.schema.json +175 -175
  44. package/.aios-core/product/templates/engine/schemas/pmdr.schema.json +175 -175
  45. package/.aios-core/product/templates/engine/schemas/prd-v2.schema.json +300 -300
  46. package/.aios-core/product/templates/engine/schemas/prd.schema.json +152 -152
  47. package/.aios-core/product/templates/engine/schemas/story.schema.json +222 -222
  48. package/.aios-core/product/templates/engine/schemas/task.schema.json +154 -154
  49. package/.aios-core/product/templates/eslintrc-security.json +32 -32
  50. package/.aios-core/product/templates/github-actions-cd.yml +212 -212
  51. package/.aios-core/product/templates/github-actions-ci.yml +172 -172
  52. package/.aios-core/product/templates/shock-report-tmpl.html +502 -502
  53. package/.aios-core/product/templates/token-exports-css-tmpl.css +240 -240
  54. package/.aios-core/quality/schemas/quality-metrics.schema.json +233 -233
  55. package/.aios-core/scripts/migrate-framework-docs.sh +300 -300
  56. package/README.en.md +747 -0
  57. package/README.md +4 -2
  58. package/bin/aios.js +7 -4
  59. package/package.json +1 -1
  60. package/packages/aios-pro-cli/src/recover.js +1 -1
  61. package/packages/installer/src/wizard/ide-config-generator.js +6 -6
  62. package/packages/installer/src/wizard/pro-setup.js +3 -3
  63. package/pro/license/degradation.js +220 -220
  64. package/pro/license/errors.js +450 -450
  65. package/pro/license/feature-gate.js +354 -354
  66. package/pro/license/index.js +181 -181
  67. package/pro/license/license-cache.js +523 -523
  68. package/pro/license/license-crypto.js +303 -303
  69. package/scripts/package-synapse.js +5 -5
  70. package/scripts/validate-package-completeness.js +3 -3
  71. package/.aios-core/.session/current-session.json +0 -14
  72. package/.aios-core/data/registry-update-log.jsonl +0 -191
  73. package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +0 -335
  74. package/.aios-core/docs/component-creation-guide.md +0 -458
  75. package/.aios-core/docs/session-update-pattern.md +0 -307
  76. package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +0 -1963
  77. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +0 -1190
  78. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +0 -439
  79. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +0 -5398
  80. package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +0 -523
  81. package/.aios-core/docs/template-syntax.md +0 -267
  82. package/.aios-core/docs/troubleshooting-guide.md +0 -625
  83. package/.aios-core/infrastructure/tests/utilities-audit-results.json +0 -501
  84. package/.aios-core/manifests/agents.csv +0 -29
  85. package/.aios-core/manifests/tasks.csv +0 -198
  86. package/.aios-core/manifests/workers.csv +0 -204
  87. package/.claude/rules/agent-authority.md +0 -105
  88. package/.claude/rules/coderabbit-integration.md +0 -93
  89. package/.claude/rules/ids-principles.md +0 -112
  90. package/.claude/rules/story-lifecycle.md +0 -139
  91. package/.claude/rules/workflow-execution.md +0 -150
  92. package/scripts/glue/README.md +0 -355
  93. package/scripts/glue/compose-agent-prompt.cjs +0 -362
  94. /package/.claude/hooks/{precompact-session-digest.js → precompact-session-digest.cjs} +0 -0
  95. /package/.claude/hooks/{synapse-engine.js → synapse-engine.cjs} +0 -0
@@ -1,450 +1,450 @@
1
- /**
2
- * License Errors Module
3
- *
4
- * Custom error classes for license and feature gating.
5
- *
6
- * @module pro/license/errors
7
- * @see ADR-PRO-003 - Feature Gating & Licensing
8
- * @see Story PRO-6 - License Key & Feature Gating System
9
- */
10
-
11
- 'use strict';
12
-
13
- /**
14
- * Error thrown when a pro feature is accessed without a valid license.
15
- *
16
- * Provides a user-friendly message with activation instructions.
17
- * Never exposes sensitive information (license keys, internal state).
18
- *
19
- * Usage:
20
- * throw new ProFeatureError('pro.squads.premium', 'Premium Squads');
21
- *
22
- * Message format (per ADR-PRO-003):
23
- * {Feature Name} requires an active AIOS Pro license.
24
- * Your data and configurations are preserved.
25
- * Activate: aios pro activate --key <KEY>
26
- * Purchase: https://synkra.ai/pro
27
- */
28
- class ProFeatureError extends Error {
29
- /**
30
- * Create a ProFeatureError.
31
- *
32
- * @param {string} featureId - The feature ID that was requested (e.g., "pro.squads.premium")
33
- * @param {string} [friendlyName] - Human-friendly name for the feature
34
- * @param {object} [options] - Additional options
35
- * @param {string} [options.purchaseUrl] - Custom purchase URL
36
- * @param {string} [options.activateCommand] - Custom activation command
37
- */
38
- constructor(featureId, friendlyName, options = {}) {
39
- const name = friendlyName || featureId;
40
- const purchaseUrl = options.purchaseUrl || 'https://synkra.ai/pro';
41
- const activateCommand = options.activateCommand || 'aios pro activate --key <KEY>';
42
-
43
- const message = [
44
- `${name} requires an active AIOS Pro license.`,
45
- 'Your data and configurations are preserved.',
46
- `Activate: ${activateCommand}`,
47
- `Purchase: ${purchaseUrl}`,
48
- ].join('\n');
49
-
50
- super(message);
51
-
52
- this.name = 'ProFeatureError';
53
- this.featureId = featureId;
54
- this.friendlyName = name;
55
- this.purchaseUrl = purchaseUrl;
56
- this.activateCommand = activateCommand;
57
-
58
- // Capture stack trace (V8 engines)
59
- if (Error.captureStackTrace) {
60
- Error.captureStackTrace(this, ProFeatureError);
61
- }
62
- }
63
-
64
- /**
65
- * Get formatted message for CLI display.
66
- *
67
- * @returns {string} Formatted error message
68
- */
69
- toCliMessage() {
70
- return [
71
- '',
72
- ` ${this.friendlyName} requires an active AIOS Pro license.`,
73
- '',
74
- ' Your data and configurations are preserved.',
75
- '',
76
- ` Activate: ${this.activateCommand}`,
77
- ` Purchase: ${this.purchaseUrl}`,
78
- '',
79
- ].join('\n');
80
- }
81
-
82
- /**
83
- * Get JSON representation for API responses.
84
- *
85
- * @returns {object} JSON-serializable error object
86
- */
87
- toJSON() {
88
- return {
89
- error: 'ProFeatureError',
90
- featureId: this.featureId,
91
- friendlyName: this.friendlyName,
92
- message: `${this.friendlyName} requires an active AIOS Pro license.`,
93
- activateCommand: this.activateCommand,
94
- purchaseUrl: this.purchaseUrl,
95
- };
96
- }
97
- }
98
-
99
- /**
100
- * Error thrown when license activation fails.
101
- */
102
- class LicenseActivationError extends Error {
103
- /**
104
- * Create a LicenseActivationError.
105
- *
106
- * @param {string} message - Error message
107
- * @param {string} [code] - Error code (e.g., 'INVALID_KEY', 'NETWORK_ERROR')
108
- * @param {object} [details] - Additional error details
109
- */
110
- constructor(message, code, details = {}) {
111
- super(message);
112
-
113
- this.name = 'LicenseActivationError';
114
- this.code = code || 'ACTIVATION_FAILED';
115
- this.details = details;
116
-
117
- if (Error.captureStackTrace) {
118
- Error.captureStackTrace(this, LicenseActivationError);
119
- }
120
- }
121
-
122
- /**
123
- * Create error for invalid key format.
124
- *
125
- * @returns {LicenseActivationError}
126
- */
127
- static invalidKeyFormat() {
128
- return new LicenseActivationError(
129
- 'Invalid license key format. Expected: PRO-XXXX-XXXX-XXXX-XXXX',
130
- 'INVALID_KEY_FORMAT',
131
- );
132
- }
133
-
134
- /**
135
- * Create error for network failure.
136
- *
137
- * @param {Error} [cause] - Original error
138
- * @returns {LicenseActivationError}
139
- */
140
- static networkError(cause) {
141
- return new LicenseActivationError(
142
- 'Unable to reach license server. Please check your internet connection.',
143
- 'NETWORK_ERROR',
144
- { cause: cause ? cause.message : undefined },
145
- );
146
- }
147
-
148
- /**
149
- * Create error for invalid key (server rejected).
150
- *
151
- * @returns {LicenseActivationError}
152
- */
153
- static invalidKey() {
154
- return new LicenseActivationError(
155
- 'The license key is invalid or has been revoked.',
156
- 'INVALID_KEY',
157
- );
158
- }
159
-
160
- /**
161
- * Create error for expired key.
162
- *
163
- * @returns {LicenseActivationError}
164
- */
165
- static expiredKey() {
166
- return new LicenseActivationError(
167
- 'The license key has expired. Please renew at https://synkra.ai/pro',
168
- 'EXPIRED_KEY',
169
- );
170
- }
171
-
172
- /**
173
- * Create error for seat limit exceeded.
174
- *
175
- * @param {number} used - Seats currently used
176
- * @param {number} max - Maximum seats allowed
177
- * @returns {LicenseActivationError}
178
- */
179
- static seatLimitExceeded(used, max) {
180
- return new LicenseActivationError(
181
- `Seat limit exceeded. ${used}/${max} seats in use. Deactivate another device or upgrade your license.`,
182
- 'SEAT_LIMIT_EXCEEDED',
183
- { used, max },
184
- );
185
- }
186
-
187
- /**
188
- * Create error for rate limiting.
189
- *
190
- * @param {number} [retryAfter] - Seconds until retry is allowed
191
- * @returns {LicenseActivationError}
192
- */
193
- static rateLimited(retryAfter) {
194
- const message = retryAfter
195
- ? `Too many requests. Please try again in ${retryAfter} seconds.`
196
- : 'Too many requests. Please try again later.';
197
-
198
- return new LicenseActivationError(message, 'RATE_LIMITED', { retryAfter });
199
- }
200
-
201
- /**
202
- * Create error for server error.
203
- *
204
- * @returns {LicenseActivationError}
205
- */
206
- static serverError() {
207
- return new LicenseActivationError(
208
- 'License server error. Please try again later.',
209
- 'SERVER_ERROR',
210
- );
211
- }
212
-
213
- /**
214
- * Get JSON representation for API responses.
215
- *
216
- * @returns {object} JSON-serializable error object
217
- */
218
- toJSON() {
219
- return {
220
- error: 'LicenseActivationError',
221
- code: this.code,
222
- message: this.message,
223
- details: this.details,
224
- };
225
- }
226
- }
227
-
228
- /**
229
- * Error thrown when license validation fails.
230
- */
231
- class LicenseValidationError extends Error {
232
- /**
233
- * Create a LicenseValidationError.
234
- *
235
- * @param {string} message - Error message
236
- * @param {string} [code] - Error code
237
- */
238
- constructor(message, code) {
239
- super(message);
240
-
241
- this.name = 'LicenseValidationError';
242
- this.code = code || 'VALIDATION_FAILED';
243
-
244
- if (Error.captureStackTrace) {
245
- Error.captureStackTrace(this, LicenseValidationError);
246
- }
247
- }
248
-
249
- /**
250
- * Create error for corrupted cache.
251
- *
252
- * @returns {LicenseValidationError}
253
- */
254
- static corruptedCache() {
255
- return new LicenseValidationError(
256
- 'License cache is corrupted. Please reactivate with: aios pro activate --key <KEY>',
257
- 'CORRUPTED_CACHE',
258
- );
259
- }
260
-
261
- /**
262
- * Create error for machine mismatch.
263
- *
264
- * @returns {LicenseValidationError}
265
- */
266
- static machineMismatch() {
267
- return new LicenseValidationError(
268
- 'License was activated on a different machine. Please reactivate.',
269
- 'MACHINE_MISMATCH',
270
- );
271
- }
272
- }
273
-
274
- /**
275
- * Error thrown when authentication fails.
276
- *
277
- * Covers signup, login, email verification, and session errors.
278
- *
279
- * @see Story PRO-11 - Email Authentication & Buyer-Based Pro Activation
280
- */
281
- class AuthError extends Error {
282
- /**
283
- * Create an AuthError.
284
- *
285
- * @param {string} message - Error message
286
- * @param {string} [code] - Error code (e.g., 'EMAIL_NOT_VERIFIED', 'INVALID_CREDENTIALS')
287
- * @param {object} [details] - Additional error details
288
- */
289
- constructor(message, code, details = {}) {
290
- super(message);
291
-
292
- this.name = 'AuthError';
293
- this.code = code || 'AUTH_FAILED';
294
- this.details = details;
295
-
296
- if (Error.captureStackTrace) {
297
- Error.captureStackTrace(this, AuthError);
298
- }
299
- }
300
-
301
- /**
302
- * Create error for invalid credentials (wrong email/password).
303
- *
304
- * @returns {AuthError}
305
- */
306
- static invalidCredentials() {
307
- return new AuthError(
308
- 'Invalid email or password.',
309
- 'INVALID_CREDENTIALS',
310
- );
311
- }
312
-
313
- /**
314
- * Create error for email not verified.
315
- *
316
- * @returns {AuthError}
317
- */
318
- static emailNotVerified() {
319
- return new AuthError(
320
- 'Please verify your email first. Check your inbox.',
321
- 'EMAIL_NOT_VERIFIED',
322
- );
323
- }
324
-
325
- /**
326
- * Create error for email already registered.
327
- *
328
- * @returns {AuthError}
329
- */
330
- static emailAlreadyRegistered() {
331
- return new AuthError(
332
- 'An account with this email already exists. Try logging in instead.',
333
- 'EMAIL_ALREADY_REGISTERED',
334
- );
335
- }
336
-
337
- /**
338
- * Create error for rate limiting on auth endpoints.
339
- *
340
- * @param {number} [retryAfter] - Seconds until retry is allowed
341
- * @returns {AuthError}
342
- */
343
- static rateLimited(retryAfter) {
344
- const message = retryAfter
345
- ? `Too many attempts. Try again in ${Math.ceil(retryAfter / 60)} minutes.`
346
- : 'Too many attempts. Please try again later.';
347
-
348
- return new AuthError(message, 'AUTH_RATE_LIMITED', { retryAfter });
349
- }
350
-
351
- /**
352
- * Create error for verification timeout.
353
- *
354
- * @returns {AuthError}
355
- */
356
- static verificationTimeout() {
357
- return new AuthError(
358
- 'Email verification timed out. Please try again.',
359
- 'VERIFICATION_TIMEOUT',
360
- );
361
- }
362
-
363
- /**
364
- * Get JSON representation for API responses.
365
- *
366
- * @returns {object} JSON-serializable error object
367
- */
368
- toJSON() {
369
- return {
370
- error: 'AuthError',
371
- code: this.code,
372
- message: this.message,
373
- details: this.details,
374
- };
375
- }
376
- }
377
-
378
- /**
379
- * Error thrown when buyer validation fails.
380
- *
381
- * Used when validate_buyer API indicates the user is not a paying customer.
382
- *
383
- * @see Story PRO-11 - Email Authentication & Buyer-Based Pro Activation
384
- */
385
- class BuyerValidationError extends Error {
386
- /**
387
- * Create a BuyerValidationError.
388
- *
389
- * @param {string} message - Error message
390
- * @param {string} [code] - Error code
391
- * @param {object} [details] - Additional error details
392
- */
393
- constructor(message, code, details = {}) {
394
- super(message);
395
-
396
- this.name = 'BuyerValidationError';
397
- this.code = code || 'BUYER_VALIDATION_FAILED';
398
- this.details = details;
399
-
400
- if (Error.captureStackTrace) {
401
- Error.captureStackTrace(this, BuyerValidationError);
402
- }
403
- }
404
-
405
- /**
406
- * Create error for non-buyer (validate_buyer returned false).
407
- *
408
- * @returns {BuyerValidationError}
409
- */
410
- static notABuyer() {
411
- return new BuyerValidationError(
412
- 'No active Pro subscription found for this email.',
413
- 'NOT_A_BUYER',
414
- );
415
- }
416
-
417
- /**
418
- * Create error for buyer validation service failure.
419
- *
420
- * @returns {BuyerValidationError}
421
- */
422
- static serviceUnavailable() {
423
- return new BuyerValidationError(
424
- 'Subscription verification service is temporarily unavailable. Please try again later.',
425
- 'BUYER_SERVICE_UNAVAILABLE',
426
- );
427
- }
428
-
429
- /**
430
- * Get JSON representation for API responses.
431
- *
432
- * @returns {object} JSON-serializable error object
433
- */
434
- toJSON() {
435
- return {
436
- error: 'BuyerValidationError',
437
- code: this.code,
438
- message: this.message,
439
- details: this.details,
440
- };
441
- }
442
- }
443
-
444
- module.exports = {
445
- ProFeatureError,
446
- LicenseActivationError,
447
- LicenseValidationError,
448
- AuthError,
449
- BuyerValidationError,
450
- };
1
+ /**
2
+ * License Errors Module
3
+ *
4
+ * Custom error classes for license and feature gating.
5
+ *
6
+ * @module pro/license/errors
7
+ * @see ADR-PRO-003 - Feature Gating & Licensing
8
+ * @see Story PRO-6 - License Key & Feature Gating System
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ /**
14
+ * Error thrown when a pro feature is accessed without a valid license.
15
+ *
16
+ * Provides a user-friendly message with activation instructions.
17
+ * Never exposes sensitive information (license keys, internal state).
18
+ *
19
+ * Usage:
20
+ * throw new ProFeatureError('pro.squads.premium', 'Premium Squads');
21
+ *
22
+ * Message format (per ADR-PRO-003):
23
+ * {Feature Name} requires an active AIOS Pro license.
24
+ * Your data and configurations are preserved.
25
+ * Activate: aios pro activate --key <KEY>
26
+ * Purchase: https://synkra.ai/pro
27
+ */
28
+ class ProFeatureError extends Error {
29
+ /**
30
+ * Create a ProFeatureError.
31
+ *
32
+ * @param {string} featureId - The feature ID that was requested (e.g., "pro.squads.premium")
33
+ * @param {string} [friendlyName] - Human-friendly name for the feature
34
+ * @param {object} [options] - Additional options
35
+ * @param {string} [options.purchaseUrl] - Custom purchase URL
36
+ * @param {string} [options.activateCommand] - Custom activation command
37
+ */
38
+ constructor(featureId, friendlyName, options = {}) {
39
+ const name = friendlyName || featureId;
40
+ const purchaseUrl = options.purchaseUrl || 'https://synkra.ai/pro';
41
+ const activateCommand = options.activateCommand || 'aios pro activate --key <KEY>';
42
+
43
+ const message = [
44
+ `${name} requires an active AIOS Pro license.`,
45
+ 'Your data and configurations are preserved.',
46
+ `Activate: ${activateCommand}`,
47
+ `Purchase: ${purchaseUrl}`,
48
+ ].join('\n');
49
+
50
+ super(message);
51
+
52
+ this.name = 'ProFeatureError';
53
+ this.featureId = featureId;
54
+ this.friendlyName = name;
55
+ this.purchaseUrl = purchaseUrl;
56
+ this.activateCommand = activateCommand;
57
+
58
+ // Capture stack trace (V8 engines)
59
+ if (Error.captureStackTrace) {
60
+ Error.captureStackTrace(this, ProFeatureError);
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Get formatted message for CLI display.
66
+ *
67
+ * @returns {string} Formatted error message
68
+ */
69
+ toCliMessage() {
70
+ return [
71
+ '',
72
+ ` ${this.friendlyName} requires an active AIOS Pro license.`,
73
+ '',
74
+ ' Your data and configurations are preserved.',
75
+ '',
76
+ ` Activate: ${this.activateCommand}`,
77
+ ` Purchase: ${this.purchaseUrl}`,
78
+ '',
79
+ ].join('\n');
80
+ }
81
+
82
+ /**
83
+ * Get JSON representation for API responses.
84
+ *
85
+ * @returns {object} JSON-serializable error object
86
+ */
87
+ toJSON() {
88
+ return {
89
+ error: 'ProFeatureError',
90
+ featureId: this.featureId,
91
+ friendlyName: this.friendlyName,
92
+ message: `${this.friendlyName} requires an active AIOS Pro license.`,
93
+ activateCommand: this.activateCommand,
94
+ purchaseUrl: this.purchaseUrl,
95
+ };
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Error thrown when license activation fails.
101
+ */
102
+ class LicenseActivationError extends Error {
103
+ /**
104
+ * Create a LicenseActivationError.
105
+ *
106
+ * @param {string} message - Error message
107
+ * @param {string} [code] - Error code (e.g., 'INVALID_KEY', 'NETWORK_ERROR')
108
+ * @param {object} [details] - Additional error details
109
+ */
110
+ constructor(message, code, details = {}) {
111
+ super(message);
112
+
113
+ this.name = 'LicenseActivationError';
114
+ this.code = code || 'ACTIVATION_FAILED';
115
+ this.details = details;
116
+
117
+ if (Error.captureStackTrace) {
118
+ Error.captureStackTrace(this, LicenseActivationError);
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Create error for invalid key format.
124
+ *
125
+ * @returns {LicenseActivationError}
126
+ */
127
+ static invalidKeyFormat() {
128
+ return new LicenseActivationError(
129
+ 'Invalid license key format. Expected: PRO-XXXX-XXXX-XXXX-XXXX',
130
+ 'INVALID_KEY_FORMAT',
131
+ );
132
+ }
133
+
134
+ /**
135
+ * Create error for network failure.
136
+ *
137
+ * @param {Error} [cause] - Original error
138
+ * @returns {LicenseActivationError}
139
+ */
140
+ static networkError(cause) {
141
+ return new LicenseActivationError(
142
+ 'Unable to reach license server. Please check your internet connection.',
143
+ 'NETWORK_ERROR',
144
+ { cause: cause ? cause.message : undefined },
145
+ );
146
+ }
147
+
148
+ /**
149
+ * Create error for invalid key (server rejected).
150
+ *
151
+ * @returns {LicenseActivationError}
152
+ */
153
+ static invalidKey() {
154
+ return new LicenseActivationError(
155
+ 'The license key is invalid or has been revoked.',
156
+ 'INVALID_KEY',
157
+ );
158
+ }
159
+
160
+ /**
161
+ * Create error for expired key.
162
+ *
163
+ * @returns {LicenseActivationError}
164
+ */
165
+ static expiredKey() {
166
+ return new LicenseActivationError(
167
+ 'The license key has expired. Please renew at https://synkra.ai/pro',
168
+ 'EXPIRED_KEY',
169
+ );
170
+ }
171
+
172
+ /**
173
+ * Create error for seat limit exceeded.
174
+ *
175
+ * @param {number} used - Seats currently used
176
+ * @param {number} max - Maximum seats allowed
177
+ * @returns {LicenseActivationError}
178
+ */
179
+ static seatLimitExceeded(used, max) {
180
+ return new LicenseActivationError(
181
+ `Seat limit exceeded. ${used}/${max} seats in use. Deactivate another device or upgrade your license.`,
182
+ 'SEAT_LIMIT_EXCEEDED',
183
+ { used, max },
184
+ );
185
+ }
186
+
187
+ /**
188
+ * Create error for rate limiting.
189
+ *
190
+ * @param {number} [retryAfter] - Seconds until retry is allowed
191
+ * @returns {LicenseActivationError}
192
+ */
193
+ static rateLimited(retryAfter) {
194
+ const message = retryAfter
195
+ ? `Too many requests. Please try again in ${retryAfter} seconds.`
196
+ : 'Too many requests. Please try again later.';
197
+
198
+ return new LicenseActivationError(message, 'RATE_LIMITED', { retryAfter });
199
+ }
200
+
201
+ /**
202
+ * Create error for server error.
203
+ *
204
+ * @returns {LicenseActivationError}
205
+ */
206
+ static serverError() {
207
+ return new LicenseActivationError(
208
+ 'License server error. Please try again later.',
209
+ 'SERVER_ERROR',
210
+ );
211
+ }
212
+
213
+ /**
214
+ * Get JSON representation for API responses.
215
+ *
216
+ * @returns {object} JSON-serializable error object
217
+ */
218
+ toJSON() {
219
+ return {
220
+ error: 'LicenseActivationError',
221
+ code: this.code,
222
+ message: this.message,
223
+ details: this.details,
224
+ };
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Error thrown when license validation fails.
230
+ */
231
+ class LicenseValidationError extends Error {
232
+ /**
233
+ * Create a LicenseValidationError.
234
+ *
235
+ * @param {string} message - Error message
236
+ * @param {string} [code] - Error code
237
+ */
238
+ constructor(message, code) {
239
+ super(message);
240
+
241
+ this.name = 'LicenseValidationError';
242
+ this.code = code || 'VALIDATION_FAILED';
243
+
244
+ if (Error.captureStackTrace) {
245
+ Error.captureStackTrace(this, LicenseValidationError);
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Create error for corrupted cache.
251
+ *
252
+ * @returns {LicenseValidationError}
253
+ */
254
+ static corruptedCache() {
255
+ return new LicenseValidationError(
256
+ 'License cache is corrupted. Please reactivate with: aios pro activate --key <KEY>',
257
+ 'CORRUPTED_CACHE',
258
+ );
259
+ }
260
+
261
+ /**
262
+ * Create error for machine mismatch.
263
+ *
264
+ * @returns {LicenseValidationError}
265
+ */
266
+ static machineMismatch() {
267
+ return new LicenseValidationError(
268
+ 'License was activated on a different machine. Please reactivate.',
269
+ 'MACHINE_MISMATCH',
270
+ );
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Error thrown when authentication fails.
276
+ *
277
+ * Covers signup, login, email verification, and session errors.
278
+ *
279
+ * @see Story PRO-11 - Email Authentication & Buyer-Based Pro Activation
280
+ */
281
+ class AuthError extends Error {
282
+ /**
283
+ * Create an AuthError.
284
+ *
285
+ * @param {string} message - Error message
286
+ * @param {string} [code] - Error code (e.g., 'EMAIL_NOT_VERIFIED', 'INVALID_CREDENTIALS')
287
+ * @param {object} [details] - Additional error details
288
+ */
289
+ constructor(message, code, details = {}) {
290
+ super(message);
291
+
292
+ this.name = 'AuthError';
293
+ this.code = code || 'AUTH_FAILED';
294
+ this.details = details;
295
+
296
+ if (Error.captureStackTrace) {
297
+ Error.captureStackTrace(this, AuthError);
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Create error for invalid credentials (wrong email/password).
303
+ *
304
+ * @returns {AuthError}
305
+ */
306
+ static invalidCredentials() {
307
+ return new AuthError(
308
+ 'Invalid email or password.',
309
+ 'INVALID_CREDENTIALS',
310
+ );
311
+ }
312
+
313
+ /**
314
+ * Create error for email not verified.
315
+ *
316
+ * @returns {AuthError}
317
+ */
318
+ static emailNotVerified() {
319
+ return new AuthError(
320
+ 'Please verify your email first. Check your inbox.',
321
+ 'EMAIL_NOT_VERIFIED',
322
+ );
323
+ }
324
+
325
+ /**
326
+ * Create error for email already registered.
327
+ *
328
+ * @returns {AuthError}
329
+ */
330
+ static emailAlreadyRegistered() {
331
+ return new AuthError(
332
+ 'An account with this email already exists. Try logging in instead.',
333
+ 'EMAIL_ALREADY_REGISTERED',
334
+ );
335
+ }
336
+
337
+ /**
338
+ * Create error for rate limiting on auth endpoints.
339
+ *
340
+ * @param {number} [retryAfter] - Seconds until retry is allowed
341
+ * @returns {AuthError}
342
+ */
343
+ static rateLimited(retryAfter) {
344
+ const message = retryAfter
345
+ ? `Too many attempts. Try again in ${Math.ceil(retryAfter / 60)} minutes.`
346
+ : 'Too many attempts. Please try again later.';
347
+
348
+ return new AuthError(message, 'AUTH_RATE_LIMITED', { retryAfter });
349
+ }
350
+
351
+ /**
352
+ * Create error for verification timeout.
353
+ *
354
+ * @returns {AuthError}
355
+ */
356
+ static verificationTimeout() {
357
+ return new AuthError(
358
+ 'Email verification timed out. Please try again.',
359
+ 'VERIFICATION_TIMEOUT',
360
+ );
361
+ }
362
+
363
+ /**
364
+ * Get JSON representation for API responses.
365
+ *
366
+ * @returns {object} JSON-serializable error object
367
+ */
368
+ toJSON() {
369
+ return {
370
+ error: 'AuthError',
371
+ code: this.code,
372
+ message: this.message,
373
+ details: this.details,
374
+ };
375
+ }
376
+ }
377
+
378
+ /**
379
+ * Error thrown when buyer validation fails.
380
+ *
381
+ * Used when validate_buyer API indicates the user is not a paying customer.
382
+ *
383
+ * @see Story PRO-11 - Email Authentication & Buyer-Based Pro Activation
384
+ */
385
+ class BuyerValidationError extends Error {
386
+ /**
387
+ * Create a BuyerValidationError.
388
+ *
389
+ * @param {string} message - Error message
390
+ * @param {string} [code] - Error code
391
+ * @param {object} [details] - Additional error details
392
+ */
393
+ constructor(message, code, details = {}) {
394
+ super(message);
395
+
396
+ this.name = 'BuyerValidationError';
397
+ this.code = code || 'BUYER_VALIDATION_FAILED';
398
+ this.details = details;
399
+
400
+ if (Error.captureStackTrace) {
401
+ Error.captureStackTrace(this, BuyerValidationError);
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Create error for non-buyer (validate_buyer returned false).
407
+ *
408
+ * @returns {BuyerValidationError}
409
+ */
410
+ static notABuyer() {
411
+ return new BuyerValidationError(
412
+ 'No active Pro subscription found for this email.',
413
+ 'NOT_A_BUYER',
414
+ );
415
+ }
416
+
417
+ /**
418
+ * Create error for buyer validation service failure.
419
+ *
420
+ * @returns {BuyerValidationError}
421
+ */
422
+ static serviceUnavailable() {
423
+ return new BuyerValidationError(
424
+ 'Subscription verification service is temporarily unavailable. Please try again later.',
425
+ 'BUYER_SERVICE_UNAVAILABLE',
426
+ );
427
+ }
428
+
429
+ /**
430
+ * Get JSON representation for API responses.
431
+ *
432
+ * @returns {object} JSON-serializable error object
433
+ */
434
+ toJSON() {
435
+ return {
436
+ error: 'BuyerValidationError',
437
+ code: this.code,
438
+ message: this.message,
439
+ details: this.details,
440
+ };
441
+ }
442
+ }
443
+
444
+ module.exports = {
445
+ ProFeatureError,
446
+ LicenseActivationError,
447
+ LicenseValidationError,
448
+ AuthError,
449
+ BuyerValidationError,
450
+ };