@factiii/stack 0.1.201 → 0.7.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 (61) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +95 -403
  3. package/bin/stack +334 -334
  4. package/dist/cli/dev-sync.js +16 -16
  5. package/dist/plugins/addons/auth/index.d.ts.map +1 -1
  6. package/dist/plugins/addons/auth/index.js +31 -12
  7. package/dist/plugins/addons/auth/index.js.map +1 -1
  8. package/dist/plugins/addons/auth/scanfix/secrets.d.ts +3 -0
  9. package/dist/plugins/addons/auth/scanfix/secrets.d.ts.map +1 -1
  10. package/dist/plugins/addons/auth/scanfix/secrets.js +54 -19
  11. package/dist/plugins/addons/auth/scanfix/secrets.js.map +1 -1
  12. package/dist/plugins/addons/auth/scanfix/validate.d.ts +3 -0
  13. package/dist/plugins/addons/auth/scanfix/validate.d.ts.map +1 -1
  14. package/dist/plugins/addons/auth/scanfix/validate.js +37 -18
  15. package/dist/plugins/addons/auth/scanfix/validate.js.map +1 -1
  16. package/dist/plugins/addons/vercel/index.js +9 -9
  17. package/dist/plugins/addons/vercel/scanfix/config.js +10 -10
  18. package/dist/plugins/addons/vercel/scanfix/token.js +15 -15
  19. package/dist/plugins/approved.json +13 -13
  20. package/dist/plugins/pipelines/aws/index.js +12 -12
  21. package/dist/plugins/pipelines/aws/policies/bootstrap-policy.json +135 -135
  22. package/dist/plugins/pipelines/aws/prod.js +1 -1
  23. package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
  24. package/dist/plugins/pipelines/factiii/index.js +2 -14
  25. package/dist/plugins/pipelines/factiii/index.js.map +1 -1
  26. package/dist/plugins/pipelines/factiii/prod.js +21 -21
  27. package/dist/plugins/pipelines/factiii/scanfix/port-convention.d.ts.map +1 -1
  28. package/dist/plugins/pipelines/factiii/scanfix/port-convention.js +2 -4
  29. package/dist/plugins/pipelines/factiii/scanfix/port-convention.js.map +1 -1
  30. package/dist/plugins/pipelines/factiii/staging.js +23 -23
  31. package/dist/plugins/pipelines/factiii/workflows/stack-ci.yml +75 -75
  32. package/dist/plugins/pipelines/factiii/workflows/stack-cicd-prod.yml +73 -73
  33. package/dist/plugins/servers/amazon-linux/index.js +16 -16
  34. package/dist/plugins/servers/mac/index.js +12 -12
  35. package/dist/plugins/servers/mac/staging.js +2 -2
  36. package/dist/plugins/servers/ubuntu/index.js +23 -23
  37. package/dist/plugins/servers/windows/index.js +15 -15
  38. package/dist/scanfix/commands/mac.d.ts.map +1 -1
  39. package/dist/scanfix/commands/mac.js +5 -4
  40. package/dist/scanfix/commands/mac.js.map +1 -1
  41. package/dist/scanfix/fixes/certbot.d.ts.map +1 -1
  42. package/dist/scanfix/fixes/certbot.js +4 -18
  43. package/dist/scanfix/fixes/certbot.js.map +1 -1
  44. package/dist/scanfix/fixes/docker.d.ts.map +1 -1
  45. package/dist/scanfix/fixes/docker.js +5 -14
  46. package/dist/scanfix/fixes/docker.js.map +1 -1
  47. package/dist/scanfix/ssl-cert-helper.d.ts.map +1 -1
  48. package/dist/scanfix/ssl-cert-helper.js +18 -4
  49. package/dist/scanfix/ssl-cert-helper.js.map +1 -1
  50. package/dist/scripts/generate-all.js +73 -73
  51. package/dist/utils/deployment-report.js +2 -2
  52. package/dist/utils/secret-prompts.js +34 -34
  53. package/dist/utils/ssh-helper.d.ts.map +1 -1
  54. package/dist/utils/ssh-helper.js +150 -142
  55. package/dist/utils/ssh-helper.js.map +1 -1
  56. package/dist/utils/template-generator.js +74 -74
  57. package/package.json +93 -114
  58. package/dist/plugins/pipelines/factiii/scanfix/docker.d.ts +0 -20
  59. package/dist/plugins/pipelines/factiii/scanfix/docker.d.ts.map +0 -1
  60. package/dist/plugins/pipelines/factiii/scanfix/docker.js +0 -131
  61. package/dist/plugins/pipelines/factiii/scanfix/docker.js.map +0 -1
@@ -361,19 +361,19 @@ async function syncToServer(tarPath, environment, config, sshKeyPath) {
361
361
  await exec(`scp -i "${sshKeyPath}" -o StrictHostKeyChecking=no "${tarPath}" "${user}@${host}:/tmp/infrastructure.tar.gz"`, { maxBuffer: 50 * 1024 * 1024 });
362
362
  // SSH to server and extract
363
363
  console.log(' Extracting on server...');
364
- await exec(`ssh -i "${sshKeyPath}" -o StrictHostKeyChecking=no "${user}@${host}" \
365
- "mkdir -p ~/.factiii/infrastructure && \
366
- cd ~/.factiii/infrastructure && \
367
- tar -xzf /tmp/infrastructure.tar.gz && \
368
- rm /tmp/infrastructure.tar.gz && \
369
- echo 'Installing infrastructure dependencies...' && \
370
- export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
371
- if [ -f 'pnpm-lock.yaml' ]; then \
372
- command -v pnpm >/dev/null 2>&1 || npm install -g pnpm && \
373
- pnpm install; \
374
- else \
375
- npm install; \
376
- fi && \
364
+ await exec(`ssh -i "${sshKeyPath}" -o StrictHostKeyChecking=no "${user}@${host}" \
365
+ "mkdir -p ~/.factiii/infrastructure && \
366
+ cd ~/.factiii/infrastructure && \
367
+ tar -xzf /tmp/infrastructure.tar.gz && \
368
+ rm /tmp/infrastructure.tar.gz && \
369
+ echo 'Installing infrastructure dependencies...' && \
370
+ export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
371
+ if [ -f 'pnpm-lock.yaml' ]; then \
372
+ command -v pnpm >/dev/null 2>&1 || npm install -g pnpm && \
373
+ pnpm install; \
374
+ else \
375
+ npm install; \
376
+ fi && \
377
377
  echo '[OK] Infrastructure synced successfully'"`);
378
378
  console.log(` [OK] Synced to ${environment}\n`);
379
379
  }
@@ -400,9 +400,9 @@ async function deployAfterSync(environment, config, sshKeyPath) {
400
400
  const repoName = config.name || 'app';
401
401
  console.log(`Deploying to ${environment}...`);
402
402
  try {
403
- await exec(`ssh -i "${sshKeyPath}" -o StrictHostKeyChecking=no "${user}@${host}" \
404
- "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
405
- cd ~/.factiii/${repoName} && \
403
+ await exec(`ssh -i "${sshKeyPath}" -o StrictHostKeyChecking=no "${user}@${host}" \
404
+ "export PATH=\"/opt/homebrew/bin:/usr/local/bin:\$PATH\" && \
405
+ cd ~/.factiii/${repoName} && \
406
406
  GITHUB_ACTIONS=true node ~/.factiii/infrastructure/bin/factiii deploy --${environment}"`);
407
407
  console.log(` [OK] Deployed to ${environment}\n`);
408
408
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/addons/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAwB,MAAM,yBAAyB,CAAC;AAoClG,cAAM,SAAS;IAKb,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC5B,MAAM,CAAC,QAAQ,CAAC,IAAI,0BAA0B;IAC9C,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAW;IAC5C,MAAM,CAAC,QAAQ,CAAC,OAAO,WAAW;IAElC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,EAAE,CAAgC;IAE7E,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAY;IAGnD,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAAkB;IAG3D,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASnD;IAGF,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGtD;IAEF;;;OAGG;WACU,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAalF,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASrC;IAMF,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,CAAe;IAM3C;;OAEG;WACU,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAkC5E,OAAO,CAAC,OAAO,CAAgB;gBAEnB,MAAM,EAAE,aAAa;CAGlC;AAED,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/addons/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAwB,MAAM,yBAAyB,CAAC;AAqDlG,cAAM,SAAS;IAKb,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC5B,MAAM,CAAC,QAAQ,CAAC,IAAI,0BAA0B;IAC9C,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAW;IAC5C,MAAM,CAAC,QAAQ,CAAC,OAAO,WAAW;IAElC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,EAAE,CAAgC;IAE7E,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAY;IAGnD,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAEtB;IAGnB,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASnD;IAGF,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGtD;IAEF;;;OAGG;WACU,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAalF,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASrC;IAMF,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,CAAe;IAM3C;;OAEG;WACU,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAqC5E,OAAO,CAAC,OAAO,CAAgB;gBAEnB,MAAM,EAAE,aAAa;CAGlC;AAED,eAAe,SAAS,CAAC"}
@@ -65,6 +65,22 @@ const path = __importStar(require("path"));
65
65
  const setup_js_1 = require("./scanfix/setup.js");
66
66
  const secrets_js_1 = require("./scanfix/secrets.js");
67
67
  const validate_js_1 = require("./scanfix/validate.js");
68
+ /**
69
+ * Load the stack-plugin contract from @factiii/auth.
70
+ * Returns null if auth is not installed or doesn't export it.
71
+ */
72
+ function loadAuthContract() {
73
+ try {
74
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
75
+ return require('@factiii/auth/stack-plugin');
76
+ }
77
+ catch {
78
+ // @factiii/auth not installed or doesn't export stack-plugin
79
+ return null;
80
+ }
81
+ }
82
+ // Load the contract once at module init
83
+ const authContract = loadAuthContract();
68
84
  /**
69
85
  * Try to load scanfixes from @factiii/auth's stackPlugin export.
70
86
  * Returns the exported fixes if available, null otherwise.
@@ -106,10 +122,12 @@ class AuthAddon {
106
122
  */
107
123
  static compatibleServers = ['mac', 'ubuntu', 'windows'];
108
124
  static defaultServer = 'ubuntu';
109
- // Env vars this plugin requires (auto-generates .env.example checks)
110
- static requiredEnvVars = ['JWT_SECRET'];
111
- // Schema for stack.yml (user-editable, optional)
112
- static configSchema = {
125
+ // Env vars this plugin requires sourced from @factiii/auth's contract
126
+ static requiredEnvVars = authContract
127
+ ? [...authContract.requiredEnvVars]
128
+ : ['JWT_SECRET'];
129
+ // Schema for stack.yml (user-editable, optional) — sourced from @factiii/auth's contract
130
+ static configSchema = authContract?.configSchema ?? {
113
131
  auth: {
114
132
  features: {
115
133
  oauth: false,
@@ -142,13 +160,13 @@ class AuthAddon {
142
160
  }
143
161
  }
144
162
  static helpText = {
145
- JWT_SECRET: `
146
- JWT signing secret for @factiii/auth.
147
-
148
- This is auto-generated (256-bit random) when you run:
149
- npx stack fix --secrets
150
-
151
- The secret is stored in Ansible Vault and used to sign
163
+ JWT_SECRET: `
164
+ JWT signing secret for @factiii/auth.
165
+
166
+ This is auto-generated (256-bit random) when you run:
167
+ npx stack fix --secrets
168
+
169
+ The secret is stored in Ansible Vault and used to sign
152
170
  authentication tokens (JWT) for your application.`,
153
171
  };
154
172
  // ============================================================
@@ -175,11 +193,12 @@ class AuthAddon {
175
193
  detected.auth_installed = false;
176
194
  }
177
195
  // Check if auth models exist in Prisma schema
196
+ const modelsToCheck = authContract?.prismaModels ?? ['User', 'Session'];
178
197
  try {
179
198
  const schemaPath = path.join(rootDir, 'prisma', 'schema.prisma');
180
199
  if (fs.existsSync(schemaPath)) {
181
200
  const content = fs.readFileSync(schemaPath, 'utf8');
182
- detected.auth_initialized = content.includes('model User') && content.includes('model Session');
201
+ detected.auth_initialized = modelsToCheck.every((model) => content.includes('model ' + model));
183
202
  }
184
203
  else {
185
204
  detected.auth_initialized = false;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/addons/auth/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/addons/auth/index.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,9 @@
4
4
  * Manages authentication secrets in Ansible Vault:
5
5
  * - JWT_SECRET: auto-generated 256-bit random key
6
6
  * - OAuth keys: prompted from user (Google, Apple)
7
+ *
8
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
9
+ * to avoid hardcoded strings drifting out of sync.
7
10
  */
8
11
  import type { Fix } from '../../../../types/index.js';
9
12
  export declare const secretsFixes: Fix[];
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAyCrE,eAAO,MAAM,YAAY,EAAE,GAAG,EA+H7B,CAAC"}
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AA2ErE,eAAO,MAAM,YAAY,EAAE,GAAG,EA+H7B,CAAC"}
@@ -5,6 +5,9 @@
5
5
  * Manages authentication secrets in Ansible Vault:
6
6
  * - JWT_SECRET: auto-generated 256-bit random key
7
7
  * - OAuth keys: prompted from user (Google, Apple)
8
+ *
9
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
10
+ * to avoid hardcoded strings drifting out of sync.
8
11
  */
9
12
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
13
  if (k2 === undefined) k2 = k;
@@ -43,6 +46,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
43
46
  exports.secretsFixes = void 0;
44
47
  const crypto = __importStar(require("crypto"));
45
48
  const config_helpers_js_1 = require("../../../../utils/config-helpers.js");
49
+ /**
50
+ * Load secret name constants from @factiii/auth's stack-plugin contract.
51
+ * Falls back to hardcoded values if auth is not installed.
52
+ */
53
+ function loadAuthSecretNames() {
54
+ try {
55
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
56
+ const contract = require('@factiii/auth/stack-plugin');
57
+ return {
58
+ requiredEnvVars: [...contract.AUTH_REQUIRED_ENV_VARS],
59
+ oauthEnvVars: {
60
+ google: [...contract.AUTH_OAUTH_ENV_VARS.google],
61
+ apple: [...contract.AUTH_OAUTH_ENV_VARS.apple],
62
+ },
63
+ };
64
+ }
65
+ catch {
66
+ // Fallback if @factiii/auth not installed
67
+ return {
68
+ requiredEnvVars: ['JWT_SECRET'],
69
+ oauthEnvVars: {
70
+ google: ['GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET'],
71
+ apple: ['APPLE_CLIENT_ID'],
72
+ },
73
+ };
74
+ }
75
+ }
76
+ const authSecrets = loadAuthSecretNames();
46
77
  /**
47
78
  * Get auth config from FactiiiConfig (handles undefined/null)
48
79
  */
@@ -79,16 +110,20 @@ async function getVault(config, rootDir) {
79
110
  rootDir,
80
111
  });
81
112
  }
113
+ const JWT_SECRET = authSecrets.requiredEnvVars[0] ?? 'JWT_SECRET';
114
+ const GOOGLE_CLIENT_ID = authSecrets.oauthEnvVars.google[0] ?? 'GOOGLE_CLIENT_ID';
115
+ const GOOGLE_CLIENT_SECRET = authSecrets.oauthEnvVars.google[1] ?? 'GOOGLE_CLIENT_SECRET';
116
+ const APPLE_CLIENT_ID = authSecrets.oauthEnvVars.apple[0] ?? 'APPLE_CLIENT_ID';
82
117
  exports.secretsFixes = [
83
118
  {
84
119
  id: 'auth-jwt-secret-missing',
85
120
  stage: 'secrets',
86
121
  severity: 'critical',
87
- description: 'JWT_SECRET not found in Ansible Vault (required for auth)',
122
+ description: JWT_SECRET + ' not found in Ansible Vault (required for auth)',
88
123
  scan: async (config, rootDir) => {
89
124
  try {
90
125
  const vault = await getVault(config, rootDir);
91
- const secret = await vault.getSecret('JWT_SECRET');
126
+ const secret = await vault.getSecret(JWT_SECRET);
92
127
  return !secret;
93
128
  }
94
129
  catch {
@@ -100,13 +135,13 @@ exports.secretsFixes = [
100
135
  const vault = await getVault(config, rootDir);
101
136
  // Auto-generate a cryptographically secure 256-bit secret
102
137
  const jwtSecret = crypto.randomBytes(32).toString('hex');
103
- const result = await vault.setSecret('JWT_SECRET', jwtSecret);
138
+ const result = await vault.setSecret(JWT_SECRET, jwtSecret);
104
139
  if (result.success) {
105
- console.log(' [OK] Generated and stored JWT_SECRET in Ansible Vault');
140
+ console.log(' [OK] Generated and stored ' + JWT_SECRET + ' in Ansible Vault');
106
141
  console.log(' (256-bit random key, no manual input needed)');
107
142
  return true;
108
143
  }
109
- console.log(' Failed to store JWT_SECRET in vault');
144
+ console.log(' Failed to store ' + JWT_SECRET + ' in vault');
110
145
  return false;
111
146
  }
112
147
  catch (e) {
@@ -114,19 +149,19 @@ exports.secretsFixes = [
114
149
  return false;
115
150
  }
116
151
  },
117
- manualFix: 'Generate and store JWT secret: npx stack deploy --secrets set JWT_SECRET',
152
+ manualFix: 'Generate and store JWT secret: npx stack deploy --secrets set ' + JWT_SECRET,
118
153
  },
119
154
  {
120
155
  id: 'auth-oauth-google-missing',
121
156
  stage: 'secrets',
122
157
  severity: 'warning',
123
- description: 'Google OAuth credentials not in vault (GOOGLE_CLIENT_ID)',
158
+ description: 'Google OAuth credentials not in vault (' + GOOGLE_CLIENT_ID + ')',
124
159
  scan: async (config, rootDir) => {
125
160
  if (!isOAuthEnabled(config, 'google'))
126
161
  return false;
127
162
  try {
128
163
  const vault = await getVault(config, rootDir);
129
- const clientId = await vault.getSecret('GOOGLE_CLIENT_ID');
164
+ const clientId = await vault.getSecret(GOOGLE_CLIENT_ID);
130
165
  return !clientId;
131
166
  }
132
167
  catch {
@@ -141,12 +176,12 @@ exports.secretsFixes = [
141
176
  console.log(' Google OAuth Setup');
142
177
  console.log(' Get credentials from: https://console.cloud.google.com/apis/credentials');
143
178
  console.log('');
144
- const clientId = await promptForSecret('GOOGLE_CLIENT_ID', config);
145
- const r1 = await vault.setSecret('GOOGLE_CLIENT_ID', clientId);
179
+ const clientId = await promptForSecret(GOOGLE_CLIENT_ID, config);
180
+ const r1 = await vault.setSecret(GOOGLE_CLIENT_ID, clientId);
146
181
  if (!r1.success)
147
182
  return false;
148
- const clientSecret = await promptForSecret('GOOGLE_CLIENT_SECRET', config);
149
- const r2 = await vault.setSecret('GOOGLE_CLIENT_SECRET', clientSecret);
183
+ const clientSecret = await promptForSecret(GOOGLE_CLIENT_SECRET, config);
184
+ const r2 = await vault.setSecret(GOOGLE_CLIENT_SECRET, clientSecret);
150
185
  if (!r2.success)
151
186
  return false;
152
187
  console.log(' [OK] Stored Google OAuth credentials in vault');
@@ -157,21 +192,21 @@ exports.secretsFixes = [
157
192
  }
158
193
  },
159
194
  manualFix: 'Store Google OAuth credentials:\n' +
160
- ' npx stack deploy --secrets set GOOGLE_CLIENT_ID\n' +
161
- ' npx stack deploy --secrets set GOOGLE_CLIENT_SECRET\n' +
195
+ ' npx stack deploy --secrets set ' + GOOGLE_CLIENT_ID + '\n' +
196
+ ' npx stack deploy --secrets set ' + GOOGLE_CLIENT_SECRET + '\n' +
162
197
  ' Get from: https://console.cloud.google.com/apis/credentials',
163
198
  },
164
199
  {
165
200
  id: 'auth-oauth-apple-missing',
166
201
  stage: 'secrets',
167
202
  severity: 'warning',
168
- description: 'Apple OAuth credentials not in vault (APPLE_CLIENT_ID)',
203
+ description: 'Apple OAuth credentials not in vault (' + APPLE_CLIENT_ID + ')',
169
204
  scan: async (config, rootDir) => {
170
205
  if (!isOAuthEnabled(config, 'apple'))
171
206
  return false;
172
207
  try {
173
208
  const vault = await getVault(config, rootDir);
174
- const clientId = await vault.getSecret('APPLE_CLIENT_ID');
209
+ const clientId = await vault.getSecret(APPLE_CLIENT_ID);
175
210
  return !clientId;
176
211
  }
177
212
  catch {
@@ -186,8 +221,8 @@ exports.secretsFixes = [
186
221
  console.log(' Apple OAuth Setup');
187
222
  console.log(' Get credentials from: https://developer.apple.com/account/resources/identifiers');
188
223
  console.log('');
189
- const clientId = await promptForSecret('APPLE_CLIENT_ID', config);
190
- const r1 = await vault.setSecret('APPLE_CLIENT_ID', clientId);
224
+ const clientId = await promptForSecret(APPLE_CLIENT_ID, config);
225
+ const r1 = await vault.setSecret(APPLE_CLIENT_ID, clientId);
191
226
  if (!r1.success)
192
227
  return false;
193
228
  console.log(' [OK] Stored Apple OAuth credentials in vault');
@@ -198,7 +233,7 @@ exports.secretsFixes = [
198
233
  }
199
234
  },
200
235
  manualFix: 'Store Apple OAuth credentials:\n' +
201
- ' npx stack deploy --secrets set APPLE_CLIENT_ID\n' +
236
+ ' npx stack deploy --secrets set ' + APPLE_CLIENT_ID + '\n' +
202
237
  ' Get from: https://developer.apple.com/account/resources/identifiers',
203
238
  },
204
239
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/secrets.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,+CAAiC;AAEjC,2EAA0E;AAE1E;;GAEG;AACH,SAAS,aAAa,CAAC,MAAqB;IAC1C,MAAM,IAAI,GAAI,MAAkC,CAAC,IAAI,CAAC;IACtD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,IAA+B,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,MAAqB,EAAE,QAA4B;IACzE,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAExB,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAA+C,CAAC;IACtE,IAAI,QAAQ,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IAEjC,4BAA4B;IAC5B,IAAI,IAAI,CAAC,cAAc,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAElD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,QAAQ,CAAC,MAAqB,EAAE,OAAe;IAC5D,MAAM,EAAE,mBAAmB,EAAE,GAAG,wDAAa,4CAA4C,GAAC,CAAC;IAC3F,OAAO,IAAI,mBAAmB,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,IAAI,IAAA,uCAAmB,EAAC,MAAM,CAAC;QACrE,mBAAmB,EAAE,MAAM,CAAC,OAAO,EAAE,mBAAmB;QACxD,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAEY,QAAA,YAAY,GAAU;IACjC;QACE,EAAE,EAAE,yBAAyB;QAC7B,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,UAAU;QACpB,WAAW,EAAE,2DAA2D;QACxE,IAAI,EAAE,KAAK,EAAE,MAAqB,EAAE,OAAe,EAAoB,EAAE;YACvE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBACnD,OAAO,CAAC,MAAM,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC,CAAC,4BAA4B;YAC5C,CAAC;QACH,CAAC;QACD,GAAG,EAAE,KAAK,EAAE,MAAqB,EAAE,OAAe,EAAoB,EAAE;YACtE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE9C,0DAA0D;gBAC1D,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACzD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;gBAE9D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;oBACxE,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;oBAC/D,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;gBACtD,OAAO,KAAK,CAAC;YACf,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzE,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,SAAS,EAAE,0EAA0E;KACtF;IAED;QACE,EAAE,EAAE,2BAA2B;QAC/B,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,0DAA0D;QACvE,IAAI,EAAE,KAAK,EAAE,MAAqB,EAAE,OAAe,EAAoB,EAAE;YACvE,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAAE,OAAO,KAAK,CAAC;YAEpD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;gBAC3D,OAAO,CAAC,QAAQ,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,GAAG,EAAE,KAAK,EAAE,MAAqB,EAAE,OAAe,EAAoB,EAAE;YACtE,IAAI,CAAC;gBACH,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,qCAAqC,GAAC,CAAC;gBAChF,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBACrC,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;gBAC1F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAEhB,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;gBACnE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;gBAC/D,IAAI,CAAC,EAAE,CAAC,OAAO;oBAAE,OAAO,KAAK,CAAC;gBAE9B,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;gBAC3E,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAC;gBACvE,IAAI,CAAC,EAAE,CAAC,OAAO;oBAAE,OAAO,KAAK,CAAC;gBAE9B,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;gBAChE,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,SAAS,EACP,mCAAmC;YACnC,yDAAyD;YACzD,6DAA6D;YAC7D,mEAAmE;KACtE;IAED;QACE,EAAE,EAAE,0BAA0B;QAC9B,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,wDAAwD;QACrE,IAAI,EAAE,KAAK,EAAE,MAAqB,EAAE,OAAe,EAAoB,EAAE;YACvE,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC;YAEnD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;gBAC1D,OAAO,CAAC,QAAQ,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,GAAG,EAAE,KAAK,EAAE,MAAqB,EAAE,OAAe,EAAoB,EAAE;YACtE,IAAI,CAAC;gBACH,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,qCAAqC,GAAC,CAAC;gBAChF,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;gBAClG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAEhB,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;gBAClE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;gBAC9D,IAAI,CAAC,EAAE,CAAC,OAAO;oBAAE,OAAO,KAAK,CAAC;gBAE9B,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;gBAC/D,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,SAAS,EACP,kCAAkC;YAClC,wDAAwD;YACxD,2EAA2E;KAC9E;CACF,CAAC"}
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/secrets.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,9 @@
3
3
  *
4
4
  * Validates that auth environment variables are properly
5
5
  * configured on staging and production servers.
6
+ *
7
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
8
+ * to avoid hardcoded strings drifting out of sync.
6
9
  */
7
10
  import type { Fix } from '../../../../types/index.js';
8
11
  export declare const validateFixes: Fix[];
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAkBrE,eAAO,MAAM,aAAa,EAAE,GAAG,EAiG9B,CAAC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAmCrE,eAAO,MAAM,aAAa,EAAE,GAAG,EAiG9B,CAAC"}
@@ -4,6 +4,9 @@
4
4
  *
5
5
  * Validates that auth environment variables are properly
6
6
  * configured on staging and production servers.
7
+ *
8
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
9
+ * to avoid hardcoded strings drifting out of sync.
7
10
  */
8
11
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
12
  if (k2 === undefined) k2 = k;
@@ -43,6 +46,22 @@ exports.validateFixes = void 0;
43
46
  const fs = __importStar(require("fs"));
44
47
  const path = __importStar(require("path"));
45
48
  const config_helpers_js_1 = require("../../../../utils/config-helpers.js");
49
+ /**
50
+ * Load required env var names from @factiii/auth's stack-plugin contract.
51
+ * Falls back to hardcoded values if auth is not installed.
52
+ */
53
+ function loadRequiredEnvVars() {
54
+ try {
55
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
56
+ const contract = require('@factiii/auth/stack-plugin');
57
+ return [...contract.AUTH_REQUIRED_ENV_VARS];
58
+ }
59
+ catch {
60
+ return ['JWT_SECRET'];
61
+ }
62
+ }
63
+ const requiredEnvVars = loadRequiredEnvVars();
64
+ const JWT_SECRET = requiredEnvVars[0] ?? 'JWT_SECRET';
46
65
  /**
47
66
  * Check if an env file has a variable set (non-empty, non-EXAMPLE)
48
67
  */
@@ -62,10 +81,10 @@ exports.validateFixes = [
62
81
  id: 'auth-env-jwt-staging',
63
82
  stage: 'staging',
64
83
  severity: 'critical',
65
- description: 'JWT_SECRET not set in .env.staging (auth will not work)',
84
+ description: JWT_SECRET + ' not set in .env.staging (auth will not work)',
66
85
  scan: async (_config, rootDir) => {
67
86
  const envPath = path.join(rootDir, '.env.staging');
68
- return !envFileHasVar(envPath, 'JWT_SECRET');
87
+ return !envFileHasVar(envPath, JWT_SECRET);
69
88
  },
70
89
  fix: async (config, rootDir) => {
71
90
  try {
@@ -75,9 +94,9 @@ exports.validateFixes = [
75
94
  vault_password_file: config.ansible?.vault_password_file,
76
95
  rootDir,
77
96
  });
78
- const jwtSecret = await vault.getSecret('JWT_SECRET');
97
+ const jwtSecret = await vault.getSecret(JWT_SECRET);
79
98
  if (!jwtSecret) {
80
- console.log(' JWT_SECRET not in vault — run: npx stack fix --secrets');
99
+ console.log(' ' + JWT_SECRET + ' not in vault — run: npx stack fix --secrets');
81
100
  return false;
82
101
  }
83
102
  // Append to .env.staging
@@ -86,15 +105,15 @@ exports.validateFixes = [
86
105
  if (fs.existsSync(envPath)) {
87
106
  content = fs.readFileSync(envPath, 'utf8');
88
107
  }
89
- if (content.includes('JWT_SECRET=')) {
108
+ if (content.includes(JWT_SECRET + '=')) {
90
109
  // Replace existing (empty or EXAMPLE) value
91
- content = content.replace(/^JWT_SECRET\s*=.*$/m, 'JWT_SECRET=' + jwtSecret);
110
+ content = content.replace(new RegExp('^' + JWT_SECRET + '\\s*=.*$', 'm'), JWT_SECRET + '=' + jwtSecret);
92
111
  }
93
112
  else {
94
- content = content.trimEnd() + '\nJWT_SECRET=' + jwtSecret + '\n';
113
+ content = content.trimEnd() + '\n' + JWT_SECRET + '=' + jwtSecret + '\n';
95
114
  }
96
115
  fs.writeFileSync(envPath, content, 'utf8');
97
- console.log(' [OK] Set JWT_SECRET in .env.staging from vault');
116
+ console.log(' [OK] Set ' + JWT_SECRET + ' in .env.staging from vault');
98
117
  return true;
99
118
  }
100
119
  catch (e) {
@@ -102,16 +121,16 @@ exports.validateFixes = [
102
121
  return false;
103
122
  }
104
123
  },
105
- manualFix: 'Add JWT_SECRET to .env.staging or run: npx stack fix --secrets && npx stack fix --staging',
124
+ manualFix: 'Add ' + JWT_SECRET + ' to .env.staging or run: npx stack fix --secrets && npx stack fix --staging',
106
125
  },
107
126
  {
108
127
  id: 'auth-env-jwt-prod',
109
128
  stage: 'prod',
110
129
  severity: 'critical',
111
- description: 'JWT_SECRET not set in .env.prod (auth will not work)',
130
+ description: JWT_SECRET + ' not set in .env.prod (auth will not work)',
112
131
  scan: async (_config, rootDir) => {
113
132
  const envPath = path.join(rootDir, '.env.prod');
114
- return !envFileHasVar(envPath, 'JWT_SECRET');
133
+ return !envFileHasVar(envPath, JWT_SECRET);
115
134
  },
116
135
  fix: async (config, rootDir) => {
117
136
  try {
@@ -121,9 +140,9 @@ exports.validateFixes = [
121
140
  vault_password_file: config.ansible?.vault_password_file,
122
141
  rootDir,
123
142
  });
124
- const jwtSecret = await vault.getSecret('JWT_SECRET');
143
+ const jwtSecret = await vault.getSecret(JWT_SECRET);
125
144
  if (!jwtSecret) {
126
- console.log(' JWT_SECRET not in vault — run: npx stack fix --secrets');
145
+ console.log(' ' + JWT_SECRET + ' not in vault — run: npx stack fix --secrets');
127
146
  return false;
128
147
  }
129
148
  // Append to .env.prod
@@ -132,14 +151,14 @@ exports.validateFixes = [
132
151
  if (fs.existsSync(envPath)) {
133
152
  content = fs.readFileSync(envPath, 'utf8');
134
153
  }
135
- if (content.includes('JWT_SECRET=')) {
136
- content = content.replace(/^JWT_SECRET\s*=.*$/m, 'JWT_SECRET=' + jwtSecret);
154
+ if (content.includes(JWT_SECRET + '=')) {
155
+ content = content.replace(new RegExp('^' + JWT_SECRET + '\\s*=.*$', 'm'), JWT_SECRET + '=' + jwtSecret);
137
156
  }
138
157
  else {
139
- content = content.trimEnd() + '\nJWT_SECRET=' + jwtSecret + '\n';
158
+ content = content.trimEnd() + '\n' + JWT_SECRET + '=' + jwtSecret + '\n';
140
159
  }
141
160
  fs.writeFileSync(envPath, content, 'utf8');
142
- console.log(' [OK] Set JWT_SECRET in .env.prod from vault');
161
+ console.log(' [OK] Set ' + JWT_SECRET + ' in .env.prod from vault');
143
162
  return true;
144
163
  }
145
164
  catch (e) {
@@ -147,7 +166,7 @@ exports.validateFixes = [
147
166
  return false;
148
167
  }
149
168
  },
150
- manualFix: 'Add JWT_SECRET to .env.prod or run: npx stack fix --secrets && npx stack fix --prod',
169
+ manualFix: 'Add ' + JWT_SECRET + ' to .env.prod or run: npx stack fix --secrets && npx stack fix --prod',
151
170
  },
152
171
  ];
153
172
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"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"}
@@ -128,15 +128,15 @@ class VercelAddon {
128
128
  return false;
129
129
  }
130
130
  static helpText = {
131
- VERCEL_TOKEN: `
132
- Vercel API Token for deployments.
133
-
134
- Get from: https://vercel.com/account/tokens
135
-
136
- Create a new token with:
137
- - Scope: Full Account (or specific team)
138
- - Expiration: No Expiration (or custom)
139
-
131
+ VERCEL_TOKEN: `
132
+ Vercel API Token for deployments.
133
+
134
+ Get from: https://vercel.com/account/tokens
135
+
136
+ Create a new token with:
137
+ - Scope: Full Account (or specific team)
138
+ - Expiration: No Expiration (or custom)
139
+
140
140
  The token will be stored securely in Ansible Vault.`,
141
141
  };
142
142
  // ============================================================
@@ -259,13 +259,13 @@ exports.fixes = [
259
259
  return false;
260
260
  }
261
261
  },
262
- manualFix: `
263
- Add Vercel to stack.yml:
264
-
265
- vercel: {}
266
-
267
- Then run: npx stack fix
268
- (Auto-creates project, detects framework, and saves IDs via Vercel API)
262
+ manualFix: `
263
+ Add Vercel to stack.yml:
264
+
265
+ vercel: {}
266
+
267
+ Then run: npx stack fix
268
+ (Auto-creates project, detects framework, and saves IDs via Vercel API)
269
269
  `,
270
270
  },
271
271
  {
@@ -335,9 +335,9 @@ Then run: npx stack fix
335
335
  return false;
336
336
  }
337
337
  },
338
- manualFix: `
339
- Run: npx stack fix
340
- (Auto-creates .vercel/project.json from Vercel API — no CLI needed)
338
+ manualFix: `
339
+ Run: npx stack fix
340
+ (Auto-creates .vercel/project.json from Vercel API — no CLI needed)
341
341
  `,
342
342
  },
343
343
  {