aiox-core 5.0.7 → 5.0.8

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 (191) hide show
  1. package/.aiox-core/cli/commands/pro/buyer.js +379 -0
  2. package/.aiox-core/cli/commands/pro/index.js +191 -52
  3. package/.aiox-core/cli/commands/validate/index.js +2 -0
  4. package/.aiox-core/core/code-intel/helpers/dev-helper.js +1 -1
  5. package/.aiox-core/core/code-intel/helpers/devops-helper.js +0 -1
  6. package/.aiox-core/core/code-intel/helpers/planning-helper.js +1 -1
  7. package/.aiox-core/core/code-intel/helpers/qa-helper.js +2 -2
  8. package/.aiox-core/core/config/schemas/framework-config.schema.json +1 -0
  9. package/.aiox-core/core/config/template-overrides.js +1 -1
  10. package/.aiox-core/core/doctor/checks/ide-sync.js +81 -25
  11. package/.aiox-core/core/doctor/checks/rules-files.js +0 -1
  12. package/.aiox-core/core/doctor/checks/skills-count.js +83 -15
  13. package/.aiox-core/core/graph-dashboard/cli.js +1 -2
  14. package/.aiox-core/core/graph-dashboard/data-sources/code-intel-source.js +1 -1
  15. package/.aiox-core/core/ids/layer-classifier.js +1 -1
  16. package/.aiox-core/core/pro/pro-updater.js +578 -0
  17. package/.aiox-core/core/synapse/context/context-tracker.js +107 -9
  18. package/.aiox-core/core/synapse/layers/layer-processor.js +1 -1
  19. package/.aiox-core/core-config.yaml +15 -1
  20. package/.aiox-core/data/capability-detection.js +15 -15
  21. package/.aiox-core/data/entity-registry.yaml +18 -2
  22. package/.aiox-core/data/registry-update-log.jsonl +5 -0
  23. package/.aiox-core/data/tok3-token-comparison.js +0 -4
  24. package/.aiox-core/data/tool-search-validation.js +1 -1
  25. package/.aiox-core/development/agents/aiox-master.md +44 -6
  26. package/.aiox-core/development/agents/data-engineer.md +4 -4
  27. package/.aiox-core/development/agents/devops.md +52 -2
  28. package/.aiox-core/development/agents/po.md +1 -1
  29. package/.aiox-core/development/agents/qa.md +5 -11
  30. package/.aiox-core/development/agents/sm.md +3 -3
  31. package/.aiox-core/development/agents/ux-design-expert.md +1 -1
  32. package/.aiox-core/development/scripts/unified-activation-pipeline.js +29 -3
  33. package/.aiox-core/development/tasks/dev-develop-story.md +46 -7
  34. package/.aiox-core/development/tasks/devops-pro-access-grant.md +93 -0
  35. package/.aiox-core/development/tasks/devops-pro-activate.md +42 -0
  36. package/.aiox-core/development/tasks/devops-pro-check-access.md +34 -0
  37. package/.aiox-core/development/tasks/devops-pro-request-reset.md +34 -0
  38. package/.aiox-core/development/tasks/devops-pro-resend-verification.md +32 -0
  39. package/.aiox-core/development/tasks/devops-pro-reset-password.md +36 -0
  40. package/.aiox-core/development/tasks/devops-pro-validate-login.md +36 -0
  41. package/.aiox-core/development/tasks/devops-pro-verify-status.md +33 -0
  42. package/.aiox-core/development/tasks/qa-gate.md +54 -4
  43. package/.aiox-core/development/tasks/validate-next-story.md +39 -2
  44. package/.aiox-core/framework-config.yaml +1 -0
  45. package/.aiox-core/infrastructure/scripts/codex-skills-sync/README.md +69 -0
  46. package/.aiox-core/infrastructure/scripts/codex-skills-sync/bootstrap.js +727 -0
  47. package/.aiox-core/infrastructure/scripts/codex-skills-sync/index.js +10 -0
  48. package/.aiox-core/infrastructure/scripts/codex-skills-sync/validate.js +65 -4
  49. package/.aiox-core/infrastructure/scripts/generate-settings-json.js +29 -4
  50. package/.aiox-core/infrastructure/scripts/ide-sync/agent-parser.js +4 -0
  51. package/.aiox-core/infrastructure/scripts/ide-sync/index.js +67 -7
  52. package/.aiox-core/infrastructure/scripts/ide-sync/transformers/claude-code.js +145 -3
  53. package/.aiox-core/infrastructure/scripts/repair-agent-references.js +263 -0
  54. package/.aiox-core/infrastructure/scripts/validate-claude-integration.js +60 -8
  55. package/.aiox-core/infrastructure/scripts/validate-paths.js +13 -0
  56. package/.aiox-core/install-manifest.yaml +134 -82
  57. package/.aiox-core/utils/filters/index.js +2 -1
  58. package/.claude/commands/AIOX/agents/aiox-master.md +21 -0
  59. package/.claude/commands/AIOX/agents/analyst.md +21 -0
  60. package/.claude/commands/AIOX/agents/architect.md +21 -0
  61. package/.claude/commands/AIOX/agents/data-engineer.md +21 -0
  62. package/.claude/commands/AIOX/agents/dev.md +21 -0
  63. package/.claude/commands/AIOX/agents/devops.md +21 -0
  64. package/.claude/commands/AIOX/agents/pm.md +21 -0
  65. package/.claude/commands/AIOX/agents/po.md +21 -0
  66. package/.claude/commands/AIOX/agents/qa.md +21 -0
  67. package/.claude/commands/AIOX/agents/sm.md +21 -0
  68. package/.claude/commands/AIOX/agents/squad-creator.md +21 -0
  69. package/.claude/commands/AIOX/agents/ux-design-expert.md +21 -0
  70. package/.claude/commands/AIOX/scripts/agent-config-loader.js +624 -0
  71. package/.claude/commands/AIOX/scripts/generate-greeting.js +160 -0
  72. package/.claude/commands/AIOX/scripts/greeting-builder.js +866 -0
  73. package/.claude/commands/AIOX/scripts/session-context-loader.js +286 -0
  74. package/.claude/commands/AIOX/stories/story-6.1.4.md +1404 -0
  75. package/.claude/commands/cohort-squad/agents/cohort-manager.md +156 -0
  76. package/.claude/commands/design-system/agents/brad-frost.md +1097 -0
  77. package/.claude/commands/design-system/agents/dan-mall.md +857 -0
  78. package/.claude/commands/design-system/agents/dave-malouf.md +2272 -0
  79. package/.claude/commands/design-system/agents/design-chief.md +102 -0
  80. package/.claude/commands/design-system/agents/nano-banana-generator.md +162 -0
  81. package/.claude/commands/greet.md +101 -0
  82. package/.claude/commands/synapse/manager.md +75 -0
  83. package/.claude/commands/synapse/tasks/add-rule.md +94 -0
  84. package/.claude/commands/synapse/tasks/create-command.md +109 -0
  85. package/.claude/commands/synapse/tasks/create-domain.md +127 -0
  86. package/.claude/commands/synapse/tasks/diagnose-synapse.md +245 -0
  87. package/.claude/commands/synapse/tasks/edit-rule.md +109 -0
  88. package/.claude/commands/synapse/tasks/suggest-domain.md +116 -0
  89. package/.claude/commands/synapse/tasks/toggle-domain.md +83 -0
  90. package/.claude/commands/synapse/templates/domain-template +8 -0
  91. package/.claude/commands/synapse/templates/manifest-entry-template +4 -0
  92. package/.claude/commands/synapse/utils/manifest-parser-reference.md +134 -0
  93. package/.claude/hooks/precompact-session-digest.cjs +2 -2
  94. package/.claude/skills/AIOX/agents/aiox-master/SKILL.md +511 -0
  95. package/.claude/skills/AIOX/agents/analyst/SKILL.md +281 -0
  96. package/.claude/skills/AIOX/agents/architect/SKILL.md +482 -0
  97. package/.claude/skills/AIOX/agents/data-engineer/SKILL.md +503 -0
  98. package/.claude/skills/AIOX/agents/dev/SKILL.md +568 -0
  99. package/.claude/skills/AIOX/agents/devops/SKILL.md +597 -0
  100. package/.claude/skills/AIOX/agents/pm/SKILL.md +385 -0
  101. package/.claude/skills/AIOX/agents/po/SKILL.md +343 -0
  102. package/.claude/skills/AIOX/agents/qa/SKILL.md +451 -0
  103. package/.claude/skills/AIOX/agents/sm/SKILL.md +295 -0
  104. package/.claude/skills/AIOX/agents/squad-creator/SKILL.md +352 -0
  105. package/.claude/skills/AIOX/agents/ux-design-expert/SKILL.md +503 -0
  106. package/.claude/skills/architect-first/SKILL.md +275 -0
  107. package/.claude/skills/architect-first/assets/architecture-template.md +505 -0
  108. package/.claude/skills/architect-first/assets/config-template.yaml +351 -0
  109. package/.claude/skills/architect-first/references/architecture-checklist.md +216 -0
  110. package/.claude/skills/architect-first/references/pre-implementation-checklist.md +119 -0
  111. package/.claude/skills/architect-first/references/stop-rules-guide.md +291 -0
  112. package/.claude/skills/architect-first/references/testing-strategy-guide.md +477 -0
  113. package/.claude/skills/architect-first/scripts/architecture_validator.py +490 -0
  114. package/.claude/skills/architect-first/scripts/check_coupling.py +306 -0
  115. package/.claude/skills/architect-first/scripts/validate_risk_mitigation.py +382 -0
  116. package/.claude/skills/checklist-runner/SKILL.md +113 -0
  117. package/.claude/skills/clone-mind.md +329 -0
  118. package/.claude/skills/coderabbit-review/SKILL.md +106 -0
  119. package/.claude/skills/course-generation-workflow.md +76 -0
  120. package/.claude/skills/enhance-workflow.md +466 -0
  121. package/.claude/skills/mcp-builder/LICENSE.txt +202 -0
  122. package/.claude/skills/mcp-builder/SKILL.md +328 -0
  123. package/.claude/skills/mcp-builder/reference/evaluation.md +602 -0
  124. package/.claude/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
  125. package/.claude/skills/mcp-builder/reference/node_mcp_server.md +916 -0
  126. package/.claude/skills/mcp-builder/reference/python_mcp_server.md +752 -0
  127. package/.claude/skills/mcp-builder/scripts/connections.py +151 -0
  128. package/.claude/skills/mcp-builder/scripts/evaluation.py +373 -0
  129. package/.claude/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  130. package/.claude/skills/mcp-builder/scripts/requirements.txt +2 -0
  131. package/.claude/skills/ralph.md +181 -0
  132. package/.claude/skills/skill-creator/LICENSE.txt +202 -0
  133. package/.claude/skills/skill-creator/SKILL.md +209 -0
  134. package/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
  135. package/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
  136. package/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
  137. package/.claude/skills/squad.md +301 -0
  138. package/.claude/skills/synapse/SKILL.md +132 -0
  139. package/.claude/skills/synapse/assets/README.md +50 -0
  140. package/.claude/skills/synapse/references/brackets.md +100 -0
  141. package/.claude/skills/synapse/references/commands.md +118 -0
  142. package/.claude/skills/synapse/references/domains.md +126 -0
  143. package/.claude/skills/synapse/references/layers.md +186 -0
  144. package/.claude/skills/synapse/references/manifest.md +142 -0
  145. package/.claude/skills/tech-search/SKILL.md +431 -0
  146. package/.claude/skills/tech-search/prompts/page-extract.md +133 -0
  147. package/README.en.md +2 -2
  148. package/README.md +8 -2
  149. package/bin/aiox.js +55 -4
  150. package/bin/utils/framework-guard.js +4 -2
  151. package/bin/utils/pro-detector.js +119 -28
  152. package/bin/utils/validate-publish.js +6 -6
  153. package/docs/aiox-agent-flows/devops-system.md +18 -0
  154. package/docs/aiox-workflows/README.md +1 -0
  155. package/docs/aiox-workflows/pro-access-grant-workflow.md +218 -0
  156. package/docs/guides/pro/access-grant-ops-playbook.md +370 -0
  157. package/docs/guides/pro/install-gate-setup.md +12 -6
  158. package/docs/guides/pro/squad-creator-handoff-pro-access-ops.md +134 -0
  159. package/docs/guides/supabase-ops-handoff.md +768 -0
  160. package/package.json +12 -1
  161. package/packages/aiox-pro-cli/bin/aiox-pro.js +33 -12
  162. package/packages/installer/src/config/configure-environment.js +118 -50
  163. package/packages/installer/src/installer/aiox-core-installer.js +124 -27
  164. package/packages/installer/src/installer/brownfield-upgrader.js +66 -9
  165. package/packages/installer/src/installer/dependency-installer.js +4 -0
  166. package/packages/installer/src/pro/pro-scaffolder.js +5 -5
  167. package/packages/installer/src/updater/index.js +151 -10
  168. package/packages/installer/src/wizard/ide-config-generator.js +73 -7
  169. package/packages/installer/src/wizard/index.js +119 -31
  170. package/packages/installer/src/wizard/pro-setup.js +118 -47
  171. package/packages/installer/src/wizard/validation/validators/dependency-validator.js +32 -25
  172. package/packages/installer/src/wizard/validation/validators/file-structure-validator.js +26 -0
  173. package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +84 -1
  174. package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +1 -1
  175. package/packages/installer/tests/unit/doctor/doctor-checks.test.js +85 -19
  176. package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +4 -4
  177. package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +5 -5
  178. package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +4 -4
  179. package/packages/installer/tests/unit/merger/yaml-merger.test.js +11 -11
  180. package/pro/README.md +12 -1
  181. package/pro/license/index.js +3 -11
  182. package/pro/license/license-api.js +25 -0
  183. package/pro/license/license-cache.js +135 -31
  184. package/pro/license/license-crypto.js +59 -3
  185. package/pro/package.json +5 -4
  186. package/pro/squads/README.md +16 -16
  187. package/pro/squads/index.js +1 -1
  188. package/scripts/e2e/installed-skills-smoke.js +264 -0
  189. package/scripts/package-synapse.js +3 -3
  190. package/scripts/validate-package-completeness.js +8 -11
  191. package/.aiox-core/lib/build.json +0 -1
@@ -21,6 +21,7 @@ const fs = require('fs');
21
21
  const path = require('path');
22
22
  const {
23
23
  generateMachineId,
24
+ generateMachineIdLegacy,
24
25
  generateSalt,
25
26
  deriveCacheKey,
26
27
  encrypt,
@@ -44,6 +45,9 @@ const CONFIG = {
44
45
 
45
46
  // Cache version for migration support
46
47
  CACHE_VERSION: 1,
48
+
49
+ // Legacy cache fallback window for hostname/CPU/MAC machine IDs.
50
+ LEGACY_MACHINE_ID_FALLBACK_DAYS: 90,
47
51
  };
48
52
 
49
53
  /**
@@ -168,6 +172,112 @@ function writeLicenseCache(data, baseDir) {
168
172
  }
169
173
  }
170
174
 
175
+ /**
176
+ * Build the canonical HMAC payload for encrypted cache content.
177
+ *
178
+ * @param {object} cacheFile - Parsed encrypted cache file
179
+ * @returns {string} JSON payload used for HMAC verification
180
+ */
181
+ function buildHmacData(cacheFile) {
182
+ return JSON.stringify({
183
+ ciphertext: cacheFile.encrypted,
184
+ iv: cacheFile.iv,
185
+ tag: cacheFile.tag,
186
+ });
187
+ }
188
+
189
+ /**
190
+ * Validate encrypted cache file structure.
191
+ *
192
+ * @param {object} cacheFile - Parsed encrypted cache file
193
+ * @returns {boolean} true when required fields exist
194
+ */
195
+ function hasValidCacheStructure(cacheFile) {
196
+ return Boolean(
197
+ cacheFile
198
+ && cacheFile.encrypted
199
+ && cacheFile.iv
200
+ && cacheFile.tag
201
+ && cacheFile.hmac
202
+ && cacheFile.salt,
203
+ );
204
+ }
205
+
206
+ /**
207
+ * Try to decrypt a cache file with a specific machine ID.
208
+ *
209
+ * @param {object} cacheFile - Parsed encrypted cache file
210
+ * @param {string} machineId - Machine ID candidate for key derivation
211
+ * @returns {object|null} Decrypted cache data or null
212
+ */
213
+ function decryptCacheWithMachineId(cacheFile, machineId) {
214
+ try {
215
+ const salt = Buffer.from(cacheFile.salt, 'hex');
216
+ const key = deriveCacheKey(machineId, salt);
217
+ const hmacData = buildHmacData(cacheFile);
218
+
219
+ if (!verifyHMAC(hmacData, key, cacheFile.hmac)) {
220
+ return null;
221
+ }
222
+
223
+ const decrypted = decrypt(
224
+ {
225
+ ciphertext: cacheFile.encrypted,
226
+ iv: cacheFile.iv,
227
+ tag: cacheFile.tag,
228
+ },
229
+ key,
230
+ );
231
+
232
+ if (decrypted.machineId !== machineId) {
233
+ return null;
234
+ }
235
+
236
+ return decrypted;
237
+ } catch {
238
+ return null;
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Check whether a legacy machine-ID cache is still inside its migration window.
244
+ *
245
+ * @param {object} cache - Decrypted legacy cache data
246
+ * @returns {boolean} true if fallback may still be used
247
+ */
248
+ function isLegacyFallbackAllowed(cache) {
249
+ if (!cache || !cache.activatedAt) {
250
+ return false;
251
+ }
252
+
253
+ const activatedAt = new Date(cache.activatedAt);
254
+ const activatedAtMs = activatedAt.getTime();
255
+
256
+ if (!Number.isFinite(activatedAtMs)) {
257
+ return false;
258
+ }
259
+
260
+ const fallbackMs = CONFIG.LEGACY_MACHINE_ID_FALLBACK_DAYS * 24 * 60 * 60 * 1000;
261
+ return Date.now() - activatedAtMs <= fallbackMs;
262
+ }
263
+
264
+ /**
265
+ * Re-encrypt a legacy cache with the new native machine-ID key.
266
+ *
267
+ * @param {object} cache - Decrypted legacy cache data
268
+ * @param {string} [baseDir] - Optional base directory override
269
+ * @returns {{ success: boolean, error?: string }} Migration result
270
+ */
271
+ function migrateCacheKey(cache, baseDir) {
272
+ const result = writeLicenseCache(cache, baseDir);
273
+
274
+ if (result.success) {
275
+ console.info('[aiox-pro] Cache migrated to new machine_id format');
276
+ }
277
+
278
+ return result;
279
+ }
280
+
171
281
  /**
172
282
  * Read and verify license cache from disk.
173
283
  *
@@ -195,42 +305,34 @@ function readLicenseCache(baseDir) {
195
305
  const cacheFile = JSON.parse(fileContent);
196
306
 
197
307
  // Validate structure
198
- if (!cacheFile.encrypted || !cacheFile.iv || !cacheFile.tag || !cacheFile.hmac || !cacheFile.salt) {
308
+ if (!hasValidCacheStructure(cacheFile)) {
199
309
  return null;
200
310
  }
201
311
 
202
- // Derive key from current machine
203
- const machineId = generateMachineId();
204
- const salt = Buffer.from(cacheFile.salt, 'hex');
205
- const key = deriveCacheKey(machineId, salt);
206
-
207
- // Verify HMAC integrity
208
- const hmacData = JSON.stringify({
209
- ciphertext: cacheFile.encrypted,
210
- iv: cacheFile.iv,
211
- tag: cacheFile.tag,
212
- });
213
-
214
- if (!verifyHMAC(hmacData, key, cacheFile.hmac)) {
215
- // HMAC mismatch: cache is tampered or from different machine
216
- return null;
312
+ // First try the legacy key so existing caches can migrate in place.
313
+ const legacyMachineId = generateMachineIdLegacy();
314
+ const legacyCache = decryptCacheWithMachineId(cacheFile, legacyMachineId);
315
+
316
+ if (legacyCache) {
317
+ if (!isLegacyFallbackAllowed(legacyCache)) {
318
+ return null;
319
+ }
320
+
321
+ const migrationResult = migrateCacheKey(legacyCache, baseDir);
322
+ if (migrationResult.success) {
323
+ return {
324
+ ...legacyCache,
325
+ machineId: generateMachineId(),
326
+ version: CONFIG.CACHE_VERSION,
327
+ };
328
+ }
329
+
330
+ return legacyCache;
217
331
  }
218
332
 
219
- // Decrypt
220
- const encryptedData = {
221
- ciphertext: cacheFile.encrypted,
222
- iv: cacheFile.iv,
223
- tag: cacheFile.tag,
224
- };
225
-
226
- const decrypted = decrypt(encryptedData, key);
227
-
228
- // Verify machine ID matches (defense in depth)
229
- if (decrypted.machineId !== machineId) {
230
- return null;
231
- }
232
-
233
- return decrypted;
333
+ // Then try the new native machine-ID key for migrated and fresh caches.
334
+ const machineId = generateMachineId();
335
+ return decryptCacheWithMachineId(cacheFile, machineId);
234
336
  } catch {
235
337
  // Any error (parse, decrypt, etc.) means cache is invalid
236
338
  return null;
@@ -519,5 +621,7 @@ module.exports = {
519
621
  getAioxDir,
520
622
 
521
623
  // Exported for testing
624
+ migrateCacheKey,
625
+ isLegacyFallbackAllowed,
522
626
  _CONFIG: CONFIG,
523
627
  };
@@ -16,6 +16,7 @@
16
16
 
17
17
  const crypto = require('crypto');
18
18
  const os = require('os');
19
+ const { machineIdSync } = require('node-machine-id');
19
20
 
20
21
  /**
21
22
  * Configuration constants for cryptographic operations.
@@ -40,14 +41,32 @@ const CONFIG = {
40
41
  };
41
42
 
42
43
  /**
43
- * Generate a deterministic machine identifier.
44
+ * Namespace the raw OS UUID before hashing so this format cannot collide with
45
+ * legacy hostname/CPU/MAC fingerprints that happen to produce the same text.
46
+ */
47
+ const MACHINE_ID_HASH_PREFIX = 'aiox-pro-native-machine-id:v1:';
48
+
49
+ let cachedMachineId = null;
50
+
51
+ /**
52
+ * Hash machine identity material without exposing the raw OS UUID.
53
+ *
54
+ * @param {string} value - Raw machine identity material
55
+ * @returns {string} SHA-256 hex digest
56
+ */
57
+ function hashMachineId(value) {
58
+ return crypto.createHash('sha256').update(value).digest('hex');
59
+ }
60
+
61
+ /**
62
+ * Generate the legacy deterministic machine identifier.
44
63
  *
45
64
  * Combines hostname + CPU model + first MAC address to create
46
65
  * a unique but reproducible identifier for this machine.
47
66
  *
48
67
  * @returns {string} SHA-256 hash of machine fingerprint components
49
68
  */
50
- function generateMachineId() {
69
+ function generateMachineIdLegacy() {
51
70
  const components = [];
52
71
 
53
72
  // Hostname
@@ -77,7 +96,42 @@ function generateMachineId() {
77
96
 
78
97
  // Create deterministic hash
79
98
  const fingerprint = components.join('|');
80
- return crypto.createHash('sha256').update(fingerprint).digest('hex');
99
+ return hashMachineId(fingerprint);
100
+ }
101
+
102
+ /**
103
+ * Generate a stable deterministic machine identifier.
104
+ *
105
+ * Uses the OS native machine UUID instead of network-interface metadata so the
106
+ * result survives Wi-Fi MAC rotation, VPN changes, and interface ordering.
107
+ *
108
+ * @returns {string} SHA-256 hash of native machine UUID
109
+ */
110
+ function generateMachineId() {
111
+ if (cachedMachineId) {
112
+ return cachedMachineId;
113
+ }
114
+
115
+ try {
116
+ const nativeMachineId = machineIdSync(true);
117
+
118
+ if (!nativeMachineId || typeof nativeMachineId !== 'string') {
119
+ throw new Error('Native machine id unavailable');
120
+ }
121
+
122
+ cachedMachineId = hashMachineId(`${MACHINE_ID_HASH_PREFIX}${nativeMachineId}`);
123
+ return cachedMachineId;
124
+ } catch {
125
+ cachedMachineId = generateMachineIdLegacy();
126
+ return cachedMachineId;
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Reset cached machine ID. Intended for tests that mock the machine-id provider.
132
+ */
133
+ function _resetMachineIdCacheForTests() {
134
+ cachedMachineId = null;
81
135
  }
82
136
 
83
137
  /**
@@ -299,5 +353,7 @@ module.exports = {
299
353
  validateKeyFormat,
300
354
 
301
355
  // Exported for testing
356
+ generateMachineIdLegacy,
357
+ _resetMachineIdCacheForTests,
302
358
  _CONFIG: CONFIG,
303
359
  };
package/pro/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
- "name": "@aiox-fullstack/pro",
3
- "version": "0.3.0",
2
+ "name": "@aiox-squads/pro",
3
+ "version": "0.4.0",
4
4
  "description": "AIOX Pro: Premium features for AIOX Framework",
5
5
  "private": false,
6
6
  "dependencies": {
7
- "yaml": "^2.8.2"
7
+ "node-machine-id": "^1.1.12",
8
+ "yaml": "^2.8.4"
8
9
  },
9
10
  "scripts": {
10
11
  "validate:publish-surface": "node scripts/validate-publish-surface.js"
11
12
  },
12
13
  "peerDependencies": {
13
- "aiox-core": ">=5.0.0"
14
+ "aiox-core": ">=5.0.8"
14
15
  },
15
16
  "engines": {
16
17
  "node": ">=18"
@@ -4,25 +4,25 @@ Pre-built agent squads installed during `npx aiox-core install` after Pro licens
4
4
 
5
5
  ## Available Squads
6
6
 
7
- | Squad | Agents | Description |
8
- |-------|--------|-------------|
9
- | **aiox-sop** | 6 | SOP factory, audit, extraction, and machine-readable operational playbooks |
10
- | **brand** | 16 | Naming, identity, positioning, narrative, and brand activation systems |
11
- | **claude-code-mastery** | 8 | Claude Code setup, hooks, MCP, swarm orchestration, and integration guardrails |
12
- | **data** | 7 | Data intelligence, analytics, segmentation, and measurement workflows |
13
- | **db-sage** | 1 | PostgreSQL and Supabase architecture, migrations, RLS, and query optimization |
14
- | **squad-creator-pro** | 6 | Meta-squad for creating AI agent squads based on real elite minds |
15
- | **design** | 8 | Design System squad — tokens, components, accessibility, DesignOps |
16
- | **etl-ops** | 3 | Extraction and transformation pipelines for local and remote content sources |
17
- | **hormozi** | 16 | Offers, leads, ads, pricing, retention, and growth systems inspired by Hormozi |
18
- | **spy** | 3 | Competitive intelligence, viral content analysis, and benchmark workflows |
19
- | **squad-creator** | 1 | Core squad creation, evolution, validation, and ecosystem orchestration |
20
- | **storytelling** | 13 | Narrative systems, pitches, storytelling frameworks, and brand communication |
7
+ | Squad | Agents | Description |
8
+ | ----------------------- | ------ | ------------------------------------------------------------------------------ |
9
+ | **aiox-sop** | 6 | SOP factory, audit, extraction, and machine-readable operational playbooks |
10
+ | **brand** | 16 | Naming, identity, positioning, narrative, and brand activation systems |
11
+ | **claude-code-mastery** | 8 | Claude Code setup, hooks, MCP, swarm orchestration, and integration guardrails |
12
+ | **data** | 7 | Data intelligence, analytics, segmentation, and measurement workflows |
13
+ | **db-sage** | 1 | PostgreSQL and Supabase architecture, migrations, RLS, and query optimization |
14
+ | **squad-creator-pro** | 6 | Meta-squad for creating AI agent squads based on real elite minds |
15
+ | **design** | 8 | Design System squad — tokens, components, accessibility, DesignOps |
16
+ | **etl-ops** | 3 | Extraction and transformation pipelines for local and remote content sources |
17
+ | **hormozi** | 16 | Offers, leads, ads, pricing, retention, and growth systems inspired by Hormozi |
18
+ | **spy** | 3 | Competitive intelligence, viral content analysis, and benchmark workflows |
19
+ | **squad-creator** | 1 | Core squad creation, evolution, validation, and ecosystem orchestration |
20
+ | **storytelling** | 13 | Narrative systems, pitches, storytelling frameworks, and brand communication |
21
21
 
22
22
  ## How It Works
23
23
 
24
24
  1. User runs `npx aiox-core install` and activates Pro license
25
- 2. `@aiox-fullstack/pro` npm package is installed
25
+ 2. `@aiox-squads/pro` npm package is installed
26
26
  3. Scaffolder copies all squads from this directory into the user's project `squads/`
27
27
  4. Agent commands are auto-installed into active IDEs (Claude Code, Codex, Gemini, Cursor)
28
28
  5. CI validates package and README coverage before the sync PR to `aiox-core`
@@ -39,4 +39,4 @@ Pre-built agent squads installed during `npx aiox-core install` after Pro licens
39
39
 
40
40
  - `npm run validate:publish-surface` fails if a top-level squad is missing from `package.json` or this README
41
41
  - `.github/workflows/sync-aiox-core.yml` opens or updates the `aiox-core` PR that advances the `pro` submodule
42
- - Durante a transição do npm, o `aiox-core` ainda aceita o fallback legado `@aios-fullstack/pro` em ambientes já instalados
42
+ - Durante a transição do npm, o `aiox-core` permanece como pacote core canônico; novos fluxos Pro devem usar `aiox-core` + `@aiox-squads/pro`
@@ -5,7 +5,7 @@
5
5
  * This pattern should be followed by all pro modules.
6
6
  *
7
7
  * Usage:
8
- * const { PremiumSquads } = require('@aiox-fullstack/pro/squads');
8
+ * const { PremiumSquads } = require('@aiox-squads/pro/squads');
9
9
  *
10
10
  * // The module will throw ProFeatureError if not licensed
11
11
  * const squads = new PremiumSquads();
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ /**
6
+ * Installed Project Skills E2E Smoke
7
+ *
8
+ * Packs the local aiox-core package, installs it into a temporary brownfield
9
+ * project, runs the installed CLI, and validates that skills are materialized
10
+ * and activatable from the installed project rather than from the source repo.
11
+ */
12
+
13
+ const { spawnSync } = require('child_process');
14
+ const fs = require('fs');
15
+ const os = require('os');
16
+ const path = require('path');
17
+
18
+ const repoRoot = path.resolve(__dirname, '..', '..');
19
+ const { getSkillId } = require(path.join(
20
+ repoRoot,
21
+ '.aiox-core',
22
+ 'infrastructure',
23
+ 'scripts',
24
+ 'codex-skills-sync',
25
+ 'index',
26
+ ));
27
+ const verbose = process.env.AIOX_E2E_VERBOSE === '1';
28
+ const keepTemp = process.env.AIOX_E2E_KEEP_TEMP === '1';
29
+ const agentSet = (process.env.AIOX_E2E_AGENT_SET || 'dev,qa,aiox-master')
30
+ .split(',')
31
+ .map((agent) => agent.trim())
32
+ .filter(Boolean);
33
+
34
+ const packDir = fs.mkdtempSync(path.join(os.tmpdir(), 'aiox-pack-'));
35
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'aiox-installed-skills-'));
36
+ const projectRoot = path.join(tempRoot, 'project');
37
+ const requiredCorePackages = ['fast-glob', 'fs-extra', 'js-yaml', 'semver', 'ajv', 'tar', 'chalk'];
38
+
39
+ function log(message) {
40
+ console.log(`[installed-skills-e2e] ${message}`);
41
+ }
42
+
43
+ function fail(message, details = '') {
44
+ const suffix = details ? `\n${details}` : '';
45
+ throw new Error(`${message}${suffix}`);
46
+ }
47
+
48
+ function run(command, args, options = {}) {
49
+ const cwd = options.cwd || repoRoot;
50
+ const env = { ...process.env, ...(options.env || {}) };
51
+ const label = `${command} ${args.join(' ')}`;
52
+
53
+ if (verbose) {
54
+ log(`$ ${label} (cwd=${cwd})`);
55
+ }
56
+
57
+ const result = spawnSync(command, args, {
58
+ cwd,
59
+ env,
60
+ encoding: 'utf8',
61
+ timeout: options.timeout || 120000,
62
+ maxBuffer: 1024 * 1024 * 20,
63
+ });
64
+
65
+ if (result.error) {
66
+ fail(`Command failed to start: ${label}`, result.error.message);
67
+ }
68
+
69
+ if (verbose && result.stdout) process.stdout.write(result.stdout);
70
+ if (verbose && result.stderr) process.stderr.write(result.stderr);
71
+
72
+ if (result.status !== 0) {
73
+ fail(
74
+ `Command failed (${result.status}): ${label}`,
75
+ [
76
+ result.stdout && `STDOUT:\n${result.stdout}`,
77
+ result.stderr && `STDERR:\n${result.stderr}`,
78
+ ].filter(Boolean).join('\n\n'),
79
+ );
80
+ }
81
+
82
+ return result.stdout || '';
83
+ }
84
+
85
+ function assertPathExists(relativePath, type = 'any') {
86
+ const absolutePath = path.join(projectRoot, relativePath);
87
+ if (!fs.existsSync(absolutePath)) {
88
+ fail(`Missing expected installed path: ${relativePath}`);
89
+ }
90
+
91
+ const stat = fs.statSync(absolutePath);
92
+ if (type === 'file' && !stat.isFile()) {
93
+ fail(`Expected file but found non-file: ${relativePath}`);
94
+ }
95
+ if (type === 'dir' && !stat.isDirectory()) {
96
+ fail(`Expected directory but found non-directory: ${relativePath}`);
97
+ }
98
+
99
+ return absolutePath;
100
+ }
101
+
102
+ function assertAbsolutePathExists(absolutePath, type = 'any') {
103
+ if (!fs.existsSync(absolutePath)) {
104
+ fail(`Missing expected path: ${absolutePath}`);
105
+ }
106
+
107
+ const stat = fs.statSync(absolutePath);
108
+ if (type === 'file' && !stat.isFile()) {
109
+ fail(`Expected file but found non-file: ${absolutePath}`);
110
+ }
111
+ if (type === 'dir' && !stat.isDirectory()) {
112
+ fail(`Expected directory but found non-directory: ${absolutePath}`);
113
+ }
114
+
115
+ return absolutePath;
116
+ }
117
+
118
+ function assertNoSourceRepoLeak(relativePath) {
119
+ const absolutePath = assertPathExists(relativePath, 'file');
120
+ const content = fs.readFileSync(absolutePath, 'utf8');
121
+
122
+ if (content.includes(repoRoot)) {
123
+ fail(`Installed artifact leaks source repo path: ${relativePath}`);
124
+ }
125
+
126
+ return content;
127
+ }
128
+
129
+ function assertContains(content, expected, relativePath) {
130
+ if (!content.includes(expected)) {
131
+ fail(`Expected ${relativePath} to contain: ${expected}`);
132
+ }
133
+ }
134
+
135
+ function parseDoctorJson(output) {
136
+ try {
137
+ return JSON.parse(output);
138
+ } catch {
139
+ fail('Doctor --json did not return parseable JSON', output);
140
+ }
141
+ }
142
+
143
+ function cleanup() {
144
+ if (keepTemp) {
145
+ log(`Keeping temp root: ${tempRoot}`);
146
+ log(`Keeping pack dir: ${packDir}`);
147
+ return;
148
+ }
149
+
150
+ fs.rmSync(tempRoot, { recursive: true, force: true });
151
+ fs.rmSync(packDir, { recursive: true, force: true });
152
+ }
153
+
154
+ async function main() {
155
+ log(`Repo root: ${repoRoot}`);
156
+ log(`Temp project: ${projectRoot}`);
157
+
158
+ fs.mkdirSync(projectRoot, { recursive: true });
159
+
160
+ log('Packing local aiox-core package');
161
+ run('npm', ['pack', '--pack-destination', packDir], { cwd: repoRoot, timeout: 180000 });
162
+ const tarballs = fs.readdirSync(packDir).filter((entry) => entry.endsWith('.tgz'));
163
+ if (tarballs.length !== 1) {
164
+ fail(`Expected exactly one packed tarball, found ${tarballs.length}`, tarballs.join('\n'));
165
+ }
166
+ const tarballPath = path.join(packDir, tarballs[0]);
167
+
168
+ log('Creating brownfield test project');
169
+ run('npm', ['init', '-y'], { cwd: projectRoot });
170
+
171
+ log('Installing packed aiox-core tarball');
172
+ run('npm', ['install', tarballPath], { cwd: projectRoot, timeout: 180000 });
173
+
174
+ const cliPath = path.join(projectRoot, 'node_modules', 'aiox-core', 'bin', 'aiox.js');
175
+ const packagedCoreDir = path.join(projectRoot, 'node_modules', 'aiox-core', '.aiox-core');
176
+ assertPathExists(path.join('node_modules', 'aiox-core', 'bin', 'aiox.js'), 'file');
177
+
178
+ log('Validating packaged .aiox-core dependencies');
179
+ assertAbsolutePathExists(path.join(packagedCoreDir, 'package.json'), 'file');
180
+ run('npm', ['install', '--production', '--ignore-scripts'], {
181
+ cwd: packagedCoreDir,
182
+ timeout: 180000,
183
+ });
184
+ for (const packageName of requiredCorePackages) {
185
+ assertAbsolutePathExists(path.join(packagedCoreDir, 'node_modules', packageName), 'dir');
186
+ }
187
+
188
+ log('Running installed aiox install in CI mode');
189
+ run('node', [cliPath, 'install', '--ci', '--yes', '--ide', 'claude-code'], {
190
+ cwd: projectRoot,
191
+ timeout: 240000,
192
+ env: {
193
+ CI: '1',
194
+ AIOX_INSTALL_FORCE: '1',
195
+ AIOX_INSTALL_QUIET: '1',
196
+ },
197
+ });
198
+
199
+ log('Validating installed skill and agent artifacts');
200
+ assertPathExists('.aiox-core', 'dir');
201
+ assertPathExists('.aiox-core/development/agents', 'dir');
202
+ assertPathExists('.claude/skills/AIOX/agents', 'dir');
203
+ assertPathExists('.codex/agents', 'dir');
204
+ assertPathExists('.codex/skills', 'dir');
205
+
206
+ for (const agent of agentSet) {
207
+ const claudeSkill = `.claude/skills/AIOX/agents/${agent}/SKILL.md`;
208
+ const codexAgent = `.codex/agents/${agent}.md`;
209
+ const codexSkillId = getSkillId(agent);
210
+ const codexSkill = `.codex/skills/${codexSkillId}/SKILL.md`;
211
+ const sourceAgent = `.aiox-core/development/agents/${agent}.md`;
212
+
213
+ assertPathExists(sourceAgent, 'file');
214
+
215
+ const claudeSkillContent = assertNoSourceRepoLeak(claudeSkill);
216
+ assertContains(claudeSkillContent, 'activation_type: pipeline', claudeSkill);
217
+ assertContains(claudeSkillContent, `Source: .aiox-core/development/agents/${agent}.md`, claudeSkill);
218
+
219
+ const codexAgentContent = assertNoSourceRepoLeak(codexAgent);
220
+ assertContains(codexAgentContent, `id: ${agent}`, codexAgent);
221
+
222
+ const codexSkillContent = assertNoSourceRepoLeak(codexSkill);
223
+ assertContains(codexSkillContent, `name: ${codexSkillId}`, codexSkill);
224
+ assertContains(codexSkillContent, `.aiox-core/development/agents/${agent}.md`, codexSkill);
225
+ }
226
+
227
+ log(`Activating installed agents: ${agentSet.join(', ')}`);
228
+ const greetingScript = path.join(projectRoot, '.aiox-core', 'development', 'scripts', 'generate-greeting.js');
229
+ assertPathExists('.aiox-core/development/scripts/generate-greeting.js', 'file');
230
+
231
+ for (const agent of agentSet) {
232
+ const greeting = run('node', [greetingScript, agent], { cwd: projectRoot, timeout: 30000 });
233
+ if (!/Agent .*ready|Agent .*loaded|ready/i.test(greeting)) {
234
+ fail(`Activation smoke did not produce a ready signal for ${agent}`, greeting);
235
+ }
236
+ if (!/Available Commands|\*help/.test(greeting)) {
237
+ fail(`Activation smoke did not expose commands/help for ${agent}`, greeting);
238
+ }
239
+ }
240
+
241
+ log('Running installed doctor --json');
242
+ const doctorOutput = run('node', [cliPath, 'doctor', '--json'], {
243
+ cwd: projectRoot,
244
+ timeout: 120000,
245
+ });
246
+ const doctor = parseDoctorJson(doctorOutput);
247
+ if (!doctor.summary || doctor.summary.fail > 0) {
248
+ fail('Installed doctor reported FAIL results', JSON.stringify(doctor, null, 2));
249
+ }
250
+
251
+ log(`PASS: installed project skills E2E completed for ${agentSet.length} agents`);
252
+ }
253
+
254
+ main()
255
+ .catch((error) => {
256
+ console.error(`\n[installed-skills-e2e] FAIL: ${error.message}`);
257
+ if (!keepTemp) {
258
+ console.error('[installed-skills-e2e] Re-run with AIOX_E2E_KEEP_TEMP=1 to preserve temp files.');
259
+ } else {
260
+ console.error(`[installed-skills-e2e] Temp root preserved: ${tempRoot}`);
261
+ }
262
+ process.exitCode = 1;
263
+ })
264
+ .finally(cleanup);
@@ -217,19 +217,19 @@ cp hook/synapse-engine.cjs <your-project>/.claude/hooks/
217
217
 
218
218
  Add to \`.claude/settings.local.json\`:
219
219
 
220
- \`\`\`json
220
+ ~~~json
221
221
  {
222
222
  "hooks": {
223
223
  "UserPromptSubmit": [
224
224
  {
225
225
  "type": "command",
226
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/synapse-engine.cjs\"",
226
+ "command": "node \\"$CLAUDE_PROJECT_DIR/.claude/hooks/synapse-engine.cjs\\"",
227
227
  "timeout": 10
228
228
  }
229
229
  ]
230
230
  }
231
231
  }
232
- \`\`\`
232
+ ~~~
233
233
 
234
234
  ### 4. Copy Runtime Domains
235
235